[RFC 3/9] arm64: handle 52-bit addresses in TTBR
Robin Murphy
robin.murphy at arm.com
Thu Dec 7 06:51:03 PST 2017
On 07/12/17 12:29, Kristina Martsenko wrote:
> On 21/11/17 14:39, Robin Murphy wrote:
>> Hi Kristina,
>>
>> On 21/11/17 11:57, Kristina Martsenko wrote:
>>> The top 4 bits of a 52-bit physical address are positioned at bits 2..5
>>> in the TTBR registers. Introduce a couple of macros to move the bits
>>> there, and change all TTBR writers to use them.
>>>
>>> Leave TTBR0 PAN code unchanged, to avoid complicating it. A system with
>>> 52-bit PA will have PAN anyway (because it's ARMv8.1 or later), and a
>>> system without 52-bit PA can only use up to 48-bit PAs. Add a kconfig
>>> dependency to ensure PAN is configured.
>>>
>>> In addition, when using 52-bit PA there is a special alignment
>>> requirement on the top-level table. We don't currently have any VA_BITS
>>> configuration that would violate the requirement, but one could be added
>>> in the future, so add a compile-time BUG_ON to check for it.
>>>
>>> Signed-off-by: Kristina Martsenko <kristina.martsenko at arm.com>
>>> ---
>
> [...]
>
>>> diff --git a/arch/arm64/include/asm/assembler.h
>>> b/arch/arm64/include/asm/assembler.h
>>> index 04cf94766b78..ba3c796b9fe1 100644
>>> --- a/arch/arm64/include/asm/assembler.h
>>> +++ b/arch/arm64/include/asm/assembler.h
>>> @@ -512,4 +512,21 @@ alternative_else_nop_endif
>>> #endif
>>> .endm
>>> +/*
>>> + * Arrange a physical address in a TTBR register, taking care of 52-bit
>>> + * addresses.
>>> + *
>>> + * phys: physical address, preserved
>>> + * ttbr: returns the TTBR value
>>> + */
>>> + .macro phys_to_ttbr, phys, ttbr
>>> +#ifdef CONFIG_ARM64_PA_BITS_52
>>> + and \ttbr, \phys, #(1 << 48) - 1
>>> + orr \ttbr, \ttbr, \phys, lsr #48 - 2
>>> + bic \ttbr, \ttbr, #(1 << 2) - 1
>>
>> Is there any reason for masking off each end of the result separately
>> like this, or could we just do it more straightforwardly?
>
> I don't recall any reason, maybe just to keep it simple, to avoid having
> a separate mask macro.
>
>> #define TTBR_BADDR_MASK ((1 << 46) - 1) << 2
>>
>> orr \ttbr, \phys, \phys, lsr #46
>> and \ttbr, \ttbr, #TTBR_BADDR_MASK
>>
>> (and equivalently for phys_to_pte in patch 4)
>
> Ok, I'll rewrite it like this. (Note that mask is 52-bit-specific though.)
I don't see that it need be 52-bit specific - true the BADDR field
itself is strictly bits 47:1, but AFAICS bit 1 is always going to be
RES0: either explicitly in the 52-bit case, or from the (x-1):1
definition otherwise, since the requirement that a table must be aligned
to its size infers an absolute lower bound of x >= 3 (it may be larger
still due to other reasons, but I'm finding this area of the ARM ARM
obnoxiously difficult to read). Thus defining the mask as covering 47:2
should still be reasonable in all cases.
>> Even better if there's a convenient place to define the mask such that
>> it can be shared with KVM's existing VTTBR stuff too.
>
> Do you mean VTTBR_BADDR_MASK? I don't think this would be useful there,
> VTTBR_BADDR_MASK checks the alignment of the address that goes into
> VTTBR (not the VTTBR value itself), and takes into account specifically
> the 40-bit IPA and concatenated page tables.
Ah, I see - from skimming the code I managed to assume VTTBR_BADDR_MASK
was a mask for the actual VTTBR.BADDR register field; I hadn't delved
into all the VTTBR_X gubbins (yuck). Fair enough, scratch that idea. At
least TTBR_ASID_MASK[1] gets to have a friend :)
Robin.
[1]
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1555176.html
>
> Kristina
>
>>> +#else
>>> + mov \ttbr, \phys
>>> +#endif
>>> + .endm
>>> +
>>> #endif /* __ASM_ASSEMBLER_H */
More information about the linux-arm-kernel
mailing list