diff mbox series

[v4,06/15] arm64: Make the PHYS_MASK_SHIFT dynamic

Message ID 20240701095505.165383-7-steven.price@arm.com (mailing list archive)
State New, archived
Headers show
Series arm64: Support for running as a guest in Arm CCA | expand

Commit Message

Steven Price July 1, 2024, 9:54 a.m. UTC
Make the PHYS_MASK_SHIFT dynamic for Realms. This is only is required
for masking the PFN from a pte entry. For a realm phys_mask_shift is
reduced if the RMM reports a smaller configured size for the guest.

The realm configuration splits the address space into two with the top
half being memory shared with the host, and the bottom half being
protected memory. We treat the bit which controls this split as an
attribute bit and hence exclude it (and any higher bits) from the mask.

Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Steven Price <steven.price@arm.com>

---
v3: Drop the MAX_PHYS_MASK{,_SHIFT} definitions as they are no longer
needed.
---
 arch/arm64/include/asm/pgtable-hwdef.h | 6 ------
 arch/arm64/include/asm/pgtable.h       | 5 +++++
 arch/arm64/kernel/rsi.c                | 5 +++++
 3 files changed, 10 insertions(+), 6 deletions(-)

Comments

Will Deacon July 9, 2024, 11:43 a.m. UTC | #1
On Mon, Jul 01, 2024 at 10:54:56AM +0100, Steven Price wrote:
> Make the PHYS_MASK_SHIFT dynamic for Realms. This is only is required
> for masking the PFN from a pte entry. For a realm phys_mask_shift is
> reduced if the RMM reports a smaller configured size for the guest.
> 
> The realm configuration splits the address space into two with the top
> half being memory shared with the host, and the bottom half being
> protected memory. We treat the bit which controls this split as an
> attribute bit and hence exclude it (and any higher bits) from the mask.
> 
> Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Steven Price <steven.price@arm.com>
> 
> ---
> v3: Drop the MAX_PHYS_MASK{,_SHIFT} definitions as they are no longer
> needed.
> ---
>  arch/arm64/include/asm/pgtable-hwdef.h | 6 ------
>  arch/arm64/include/asm/pgtable.h       | 5 +++++
>  arch/arm64/kernel/rsi.c                | 5 +++++
>  3 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index 9943ff0af4c9..2e3af0693bd8 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -203,12 +203,6 @@
>   */
>  #define PTE_S2_MEMATTR(t)	(_AT(pteval_t, (t)) << 2)
>  
> -/*
> - * Highest possible physical address supported.
> - */
> -#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
> -#define PHYS_MASK		((UL(1) << PHYS_MASK_SHIFT) - 1)
> -
>  #define TTBR_CNP_BIT		(UL(1) << 0)
>  
>  /*
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index f8efbc128446..11d614d83317 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -39,6 +39,11 @@
>  #include <linux/sched.h>
>  #include <linux/page_table_check.h>
>  
> +extern unsigned int phys_mask_shift;
> +
> +#define PHYS_MASK_SHIFT		(phys_mask_shift)
> +#define PHYS_MASK		((1UL << PHYS_MASK_SHIFT) - 1)

I tried to figure out where this is actually used so I could understand
your comment in the commit message:

 > This is only is required for masking the PFN from a pte entry

The closest thing I could find is in arch/arm64/mm/mmap.c, where the
mask is used as part of valid_mmap_phys_addr_range() which exists purely
to filter accesses to /dev/mem. That's pretty niche, so why not just
inline the RSI-specific stuff in there behind a static key instead of
changing these definitions?

Or did I miss a subtle user somewhere else?

Will
Suzuki K Poulose July 9, 2024, 12:55 p.m. UTC | #2
On 09/07/2024 12:43, Will Deacon wrote:
> On Mon, Jul 01, 2024 at 10:54:56AM +0100, Steven Price wrote:
>> Make the PHYS_MASK_SHIFT dynamic for Realms. This is only is required
>> for masking the PFN from a pte entry. For a realm phys_mask_shift is
>> reduced if the RMM reports a smaller configured size for the guest.
>>
>> The realm configuration splits the address space into two with the top
>> half being memory shared with the host, and the bottom half being
>> protected memory. We treat the bit which controls this split as an
>> attribute bit and hence exclude it (and any higher bits) from the mask.
>>
>> Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>>
>> ---
>> v3: Drop the MAX_PHYS_MASK{,_SHIFT} definitions as they are no longer
>> needed.
>> ---
>>   arch/arm64/include/asm/pgtable-hwdef.h | 6 ------
>>   arch/arm64/include/asm/pgtable.h       | 5 +++++
>>   arch/arm64/kernel/rsi.c                | 5 +++++
>>   3 files changed, 10 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
>> index 9943ff0af4c9..2e3af0693bd8 100644
>> --- a/arch/arm64/include/asm/pgtable-hwdef.h
>> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
>> @@ -203,12 +203,6 @@
>>    */
>>   #define PTE_S2_MEMATTR(t)	(_AT(pteval_t, (t)) << 2)
>>   
>> -/*
>> - * Highest possible physical address supported.
>> - */
>> -#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
>> -#define PHYS_MASK		((UL(1) << PHYS_MASK_SHIFT) - 1)
>> -
>>   #define TTBR_CNP_BIT		(UL(1) << 0)
>>   
>>   /*
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index f8efbc128446..11d614d83317 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -39,6 +39,11 @@
>>   #include <linux/sched.h>
>>   #include <linux/page_table_check.h>
>>   
>> +extern unsigned int phys_mask_shift;
>> +
>> +#define PHYS_MASK_SHIFT		(phys_mask_shift)
>> +#define PHYS_MASK		((1UL << PHYS_MASK_SHIFT) - 1)
> 
> I tried to figure out where this is actually used so I could understand
> your comment in the commit message:
> 
>   > This is only is required for masking the PFN from a pte entry
> 
> The closest thing I could find is in arch/arm64/mm/mmap.c, where the
> mask is used as part of valid_mmap_phys_addr_range() which exists purely
> to filter accesses to /dev/mem. That's pretty niche, so why not just
> inline the RSI-specific stuff in there behind a static key instead of
> changing these definitions?
> 
> Or did I miss a subtle user somewhere else?

We need to prevent ioremap() of addresses beyond that limit too.

Suzuki

> 
> Will
Steven Price July 10, 2024, 3:34 p.m. UTC | #3
On 09/07/2024 13:55, Suzuki K Poulose wrote:
> On 09/07/2024 12:43, Will Deacon wrote:
>> On Mon, Jul 01, 2024 at 10:54:56AM +0100, Steven Price wrote:
>>> Make the PHYS_MASK_SHIFT dynamic for Realms. This is only is required
>>> for masking the PFN from a pte entry. For a realm phys_mask_shift is
>>> reduced if the RMM reports a smaller configured size for the guest.
>>>
>>> The realm configuration splits the address space into two with the top
>>> half being memory shared with the host, and the bottom half being
>>> protected memory. We treat the bit which controls this split as an
>>> attribute bit and hence exclude it (and any higher bits) from the mask.
>>>
>>> Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> Signed-off-by: Steven Price <steven.price@arm.com>
>>>
>>> ---
>>> v3: Drop the MAX_PHYS_MASK{,_SHIFT} definitions as they are no longer
>>> needed.
>>> ---
>>>   arch/arm64/include/asm/pgtable-hwdef.h | 6 ------
>>>   arch/arm64/include/asm/pgtable.h       | 5 +++++
>>>   arch/arm64/kernel/rsi.c                | 5 +++++
>>>   3 files changed, 10 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h
>>> b/arch/arm64/include/asm/pgtable-hwdef.h
>>> index 9943ff0af4c9..2e3af0693bd8 100644
>>> --- a/arch/arm64/include/asm/pgtable-hwdef.h
>>> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
>>> @@ -203,12 +203,6 @@
>>>    */
>>>   #define PTE_S2_MEMATTR(t)    (_AT(pteval_t, (t)) << 2)
>>>   -/*
>>> - * Highest possible physical address supported.
>>> - */
>>> -#define PHYS_MASK_SHIFT        (CONFIG_ARM64_PA_BITS)
>>> -#define PHYS_MASK        ((UL(1) << PHYS_MASK_SHIFT) - 1)
>>> -
>>>   #define TTBR_CNP_BIT        (UL(1) << 0)
>>>     /*
>>> diff --git a/arch/arm64/include/asm/pgtable.h
>>> b/arch/arm64/include/asm/pgtable.h
>>> index f8efbc128446..11d614d83317 100644
>>> --- a/arch/arm64/include/asm/pgtable.h
>>> +++ b/arch/arm64/include/asm/pgtable.h
>>> @@ -39,6 +39,11 @@
>>>   #include <linux/sched.h>
>>>   #include <linux/page_table_check.h>
>>>   +extern unsigned int phys_mask_shift;
>>> +
>>> +#define PHYS_MASK_SHIFT        (phys_mask_shift)
>>> +#define PHYS_MASK        ((1UL << PHYS_MASK_SHIFT) - 1)
>>
>> I tried to figure out where this is actually used so I could understand
>> your comment in the commit message:
>>
>>   > This is only is required for masking the PFN from a pte entry
>>
>> The closest thing I could find is in arch/arm64/mm/mmap.c, where the
>> mask is used as part of valid_mmap_phys_addr_range() which exists purely
>> to filter accesses to /dev/mem. That's pretty niche, so why not just
>> inline the RSI-specific stuff in there behind a static key instead of
>> changing these definitions?
>>
>> Or did I miss a subtle user somewhere else?
> 
> We need to prevent ioremap() of addresses beyond that limit too.

Which is arguably not much better in terms of nicheness... But this
seemed cleaner rather than trying to keep track of the niche areas of
the kernel which require this and modifying them. We could use a static
key here, but I don't think this is used for any hot-paths so it didn't
seem worth the complexity.

Steve
diff mbox series

Patch

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 9943ff0af4c9..2e3af0693bd8 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -203,12 +203,6 @@ 
  */
 #define PTE_S2_MEMATTR(t)	(_AT(pteval_t, (t)) << 2)
 
-/*
- * Highest possible physical address supported.
- */
-#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
-#define PHYS_MASK		((UL(1) << PHYS_MASK_SHIFT) - 1)
-
 #define TTBR_CNP_BIT		(UL(1) << 0)
 
 /*
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index f8efbc128446..11d614d83317 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -39,6 +39,11 @@ 
 #include <linux/sched.h>
 #include <linux/page_table_check.h>
 
+extern unsigned int phys_mask_shift;
+
+#define PHYS_MASK_SHIFT		(phys_mask_shift)
+#define PHYS_MASK		((1UL << PHYS_MASK_SHIFT) - 1)
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
 
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index 231c1a3ecdeb..7ac5fc4a27d0 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -13,6 +13,8 @@  struct realm_config config;
 unsigned long prot_ns_shared;
 EXPORT_SYMBOL(prot_ns_shared);
 
+unsigned int phys_mask_shift = CONFIG_ARM64_PA_BITS;
+
 DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
 EXPORT_SYMBOL(rsi_present);
 
@@ -80,6 +82,9 @@  void __init arm64_rsi_init(void)
 		return;
 	prot_ns_shared = BIT(config.ipa_bits - 1);
 
+	if (config.ipa_bits - 1 < phys_mask_shift)
+		phys_mask_shift = config.ipa_bits - 1;
+
 	static_branch_enable(&rsi_present);
 }