All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] powerpc/mm: Add validation for platform reserved memory ranges
@ 2016-03-02  8:46 Anshuman Khandual
  2016-03-02 12:10 ` Michael Ellerman
  0 siblings, 1 reply; 5+ messages in thread
From: Anshuman Khandual @ 2016-03-02  8:46 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: aneesh.kumar, mpe

For partition running on PHYP, there can be a adjunct partition
which shares the virtual address range with the operating system.
Virtual address ranges which can be used by the adjunct partition
are communicated with virtual device node of the device tree with
a property known as "ibm,reserved-virtual-addresses". This patch
introduces a new function named 'validate_reserved_va_range' which
is called inside 'setup_system' to validate that these reserved
virtual address ranges do not overlap with the address ranges used
by the kernel for all supported memory contexts. This helps prevent
the possibility of getting return codes similar to H_RESOURCE for
H_PROTECT hcalls for conflicting HPTE entries.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/mmu.h  |  1 +
 arch/powerpc/kernel/setup_64.c  |  2 ++
 arch/powerpc/mm/hash_utils_64.c | 51 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 3d5abfe..95257c1 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -124,6 +124,7 @@ extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
 /* MMU initialization */
 extern void early_init_mmu(void);
 extern void early_init_mmu_secondary(void);
+extern void validate_reserved_va_range(void);
 
 extern void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 				       phys_addr_t first_memblock_size);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 5c03a6a..04bc592 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -546,6 +546,8 @@ void __init setup_system(void)
 	smp_release_cpus();
 #endif
 
+	validate_reserved_va_range();
+
 	pr_info("Starting Linux %s %s\n", init_utsname()->machine,
 		 init_utsname()->version);
 
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index ba59d59..03adafc 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -810,6 +810,57 @@ void __init early_init_mmu(void)
 	slb_initialize();
 }
 
+/*
+ * PAPR says that each record contains 3 * 32 bit element, hence 12 bytes.
+ * First two element contains the abbreviated virtual address (high order
+ * 32 bits and low order 32 bits generates the abbreviated virtual address
+ * of 64 bits which need to be concatenated with 12 bits of 0 at the end
+ * to generate the actual 76 bit reserved virtual address) and size of the
+ * reserved virtual address range is encoded in next 32 bit element as number
+ * of 4K pages.
+ */
+#define	BYTES_PER_RVA_RECORD	12
+
+/*
+ * Linux uses 65 bits (MAX_PHYSMEM_BITS + CONTEXT_BITS) from available 78
+ * bit wide virtual address range. As reserved virtual address range comes
+ * as an abbreviated form of 64 bits, we will use a partial address mask
+ * (65 bit mask >> 12) to match it for simplicity.
+ */
+#define	PARTIAL_USED_VA_MASK	0x1FFFFFFFFFFFFFULL
+
+void __init validate_reserved_va_range(void)
+{
+	struct device_node *np;
+	struct property *prop;
+	unsigned int size, count, i;
+	const __be32 *value;
+	__be64 vaddr;
+
+	np = of_find_node_by_name(NULL, "vdevice");
+	if (!np)
+		return;
+
+	prop = of_find_property(np, "ibm,reserved-virtual-addresses", NULL);
+	if (!prop)
+		return;
+
+	value = of_get_property(np, "ibm,reserved-virtual-addresses", &size);
+	if (!value)
+		return;
+
+	count = size / BYTES_PER_RVA_RECORD;
+	for (i = 0; i < count; i++) {
+		vaddr = ((__be64) value[i * 3] << 32) | value[i * 3 + 1];
+		if (vaddr & ~PARTIAL_USED_VA_MASK) {
+			pr_info("Reserved virtual address range starting "
+				"at [%llx000] verified for overlap\n", vaddr);
+			continue;
+		}
+		BUG_ON("Reserved virtual address range overlapping");
+	}
+}
+
 #ifdef CONFIG_SMP
 void early_init_mmu_secondary(void)
 {
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [RFC] powerpc/mm: Add validation for platform reserved memory ranges
  2016-03-02  8:46 [RFC] powerpc/mm: Add validation for platform reserved memory ranges Anshuman Khandual
@ 2016-03-02 12:10 ` Michael Ellerman
  2016-03-04  3:59   ` Anshuman Khandual
  0 siblings, 1 reply; 5+ messages in thread
From: Michael Ellerman @ 2016-03-02 12:10 UTC (permalink / raw)
  To: Anshuman Khandual, linuxppc-dev; +Cc: aneesh.kumar

On Wed, 2016-02-03 at 08:46:12 UTC, Anshuman Khandual wrote:
> For partition running on PHYP, there can be a adjunct partition
> which shares the virtual address range with the operating system.
> Virtual address ranges which can be used by the adjunct partition
> are communicated with virtual device node of the device tree with
> a property known as "ibm,reserved-virtual-addresses". This patch
> introduces a new function named 'validate_reserved_va_range' which
> is called inside 'setup_system' to validate that these reserved
> virtual address ranges do not overlap with the address ranges used
> by the kernel for all supported memory contexts. This helps prevent
> the possibility of getting return codes similar to H_RESOURCE for
> H_PROTECT hcalls for conflicting HPTE entries.

Good plan.

> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
> index 3d5abfe..95257c1 100644
> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
> index 5c03a6a..04bc592 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -546,6 +546,8 @@ void __init setup_system(void)
>  	smp_release_cpus();
>  #endif
>  
> +	validate_reserved_va_range();
> +

I don't see why this can't just be an initcall in hash_utils_64.c, rather than
being called from here.

>  	pr_info("Starting Linux %s %s\n", init_utsname()->machine,
>  		 init_utsname()->version);
>  
> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
> index ba59d59..03adafc 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -810,6 +810,57 @@ void __init early_init_mmu(void)
>  	slb_initialize();
>  }
>  
> +/*
> + * PAPR says that each record contains 3 * 32 bit element, hence 12 bytes.
> + * First two element contains the abbreviated virtual address (high order
> + * 32 bits and low order 32 bits generates the abbreviated virtual address
> + * of 64 bits which need to be concatenated with 12 bits of 0 at the end
> + * to generate the actual 76 bit reserved virtual address) and size of the
> + * reserved virtual address range is encoded in next 32 bit element as number
> + * of 4K pages.
> + */
> +#define	BYTES_PER_RVA_RECORD	12

Please define a properly endian-annotated struct which encodes the layout.

It can be local to the function if that works.

> +/*
> + * Linux uses 65 bits (MAX_PHYSMEM_BITS + CONTEXT_BITS) from available 78
> + * bit wide virtual address range. As reserved virtual address range comes
> + * as an abbreviated form of 64 bits, we will use a partial address mask
> + * (65 bit mask >> 12) to match it for simplicity.
> + */
> +#define	PARTIAL_USED_VA_MASK	0x1FFFFFFFFFFFFFULL

Please calculate this from the appropriate constants. We don't want to have to
update it in future.

> +void __init validate_reserved_va_range(void)
> +{
> +	struct device_node *np;
> +	struct property *prop;
> +	unsigned int size, count, i;
> +	const __be32 *value;
> +	__be64 vaddr;
> +
> +	np = of_find_node_by_name(NULL, "vdevice");
> +	if (!np)
> +		return;
> +
> +	prop = of_find_property(np, "ibm,reserved-virtual-addresses", NULL);
> +	if (!prop)
> +		return;

You don't need to do a find, the get below will do it for you.

> +	value = of_get_property(np, "ibm,reserved-virtual-addresses", &size);
> +	if (!value)
> +		return;
> +
> +	count = size / BYTES_PER_RVA_RECORD;
> +	for (i = 0; i < count; i++) {
> +		vaddr = ((__be64) value[i * 3] << 32) | value[i * 3 + 1];
> +		if (vaddr & ~PARTIAL_USED_VA_MASK) {

How can it work to test a __be64 against a non-byte-swapped mask ? But like I
said above, please do this with a struct and proper endian conversions.

> +			pr_info("Reserved virtual address range starting "
> +				"at [%llx000] verified for overlap\n", vaddr);

This should print nothing in the success case.

> +			continue;
> +		}
> +		BUG_ON("Reserved virtual address range overlapping");

But here you should provide more detail. The first thing a debugger will need
to know is what address overlapped.

cheers

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC] powerpc/mm: Add validation for platform reserved memory ranges
  2016-03-02 12:10 ` Michael Ellerman
@ 2016-03-04  3:59   ` Anshuman Khandual
  2016-03-04  4:49     ` Aneesh Kumar K.V
  0 siblings, 1 reply; 5+ messages in thread
From: Anshuman Khandual @ 2016-03-04  3:59 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev; +Cc: aneesh.kumar

On 03/02/2016 05:40 PM, Michael Ellerman wrote:
> On Wed, 2016-02-03 at 08:46:12 UTC, Anshuman Khandual wrote:
>> For partition running on PHYP, there can be a adjunct partition
>> which shares the virtual address range with the operating system.
>> Virtual address ranges which can be used by the adjunct partition
>> are communicated with virtual device node of the device tree with
>> a property known as "ibm,reserved-virtual-addresses". This patch
>> introduces a new function named 'validate_reserved_va_range' which
>> is called inside 'setup_system' to validate that these reserved
>> virtual address ranges do not overlap with the address ranges used
>> by the kernel for all supported memory contexts. This helps prevent
>> the possibility of getting return codes similar to H_RESOURCE for
>> H_PROTECT hcalls for conflicting HPTE entries.
> 
> Good plan.

Thanks !

> 
>> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
>> index 3d5abfe..95257c1 100644
>> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
>> index 5c03a6a..04bc592 100644
>> --- a/arch/powerpc/kernel/setup_64.c
>> +++ b/arch/powerpc/kernel/setup_64.c
>> @@ -546,6 +546,8 @@ void __init setup_system(void)
>>  	smp_release_cpus();
>>  #endif
>>  
>> +	validate_reserved_va_range();
>> +
> 
> I don't see why this can't just be an initcall in hash_utils_64.c, rather than
> being called from here.

That works, will change it.

> 
>>  	pr_info("Starting Linux %s %s\n", init_utsname()->machine,
>>  		 init_utsname()->version);
>>  
>> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
>> index ba59d59..03adafc 100644
>> --- a/arch/powerpc/mm/hash_utils_64.c
>> +++ b/arch/powerpc/mm/hash_utils_64.c
>> @@ -810,6 +810,57 @@ void __init early_init_mmu(void)
>>  	slb_initialize();
>>  }
>>  
>> +/*
>> + * PAPR says that each record contains 3 * 32 bit element, hence 12 bytes.
>> + * First two element contains the abbreviated virtual address (high order
>> + * 32 bits and low order 32 bits generates the abbreviated virtual address
>> + * of 64 bits which need to be concatenated with 12 bits of 0 at the end
>> + * to generate the actual 76 bit reserved virtual address) and size of the
>> + * reserved virtual address range is encoded in next 32 bit element as number
>> + * of 4K pages.
>> + */
>> +#define	BYTES_PER_RVA_RECORD	12
> 
> Please define a properly endian-annotated struct which encodes the layout.

something like this ?

struct reserved_va_record {
	__be32	high_addr;	/* High 32 bits of the abbreviated VA */
	__be32	low_addr;	/* Low 32 bits of the abbreviated VA */
	__be32	nr_4k;		/* VA range in multiple of 4K pages */
};

> 
> It can be local to the function if that works.
> 

Okay.

>> +/*
>> + * Linux uses 65 bits (MAX_PHYSMEM_BITS + CONTEXT_BITS) from available 78
>> + * bit wide virtual address range. As reserved virtual address range comes
>> + * as an abbreviated form of 64 bits, we will use a partial address mask
>> + * (65 bit mask >> 12) to match it for simplicity.
>> + */
>> +#define	PARTIAL_USED_VA_MASK	0x1FFFFFFFFFFFFFULL
> 
> Please calculate this from the appropriate constants. We don't want to have to
> update it in future.

Sure, I guess something like this works.

#define RVA_SKIPPED_BITS        12      /* This changes with PAPR */
#define USED_VA_BITS            MAX_PHYSMEM_BITS + CONTEXT_BITS
#define PARTIAL_USED_VA_MASK    ((1ULL << (USED_VA_BITS - RVA_SKIPPED_BITS)) - 1)

> 
>> +void __init validate_reserved_va_range(void)
>> +{
>> +	struct device_node *np;
>> +	struct property *prop;
>> +	unsigned int size, count, i;
>> +	const __be32 *value;
>> +	__be64 vaddr;
>> +
>> +	np = of_find_node_by_name(NULL, "vdevice");
>> +	if (!np)
>> +		return;
>> +
>> +	prop = of_find_property(np, "ibm,reserved-virtual-addresses", NULL);
>> +	if (!prop)
>> +		return;
> 
> You don't need to do a find, the get below will do it for you.

Sure.

> 
>> +	value = of_get_property(np, "ibm,reserved-virtual-addresses", &size);
>> +	if (!value)
>> +		return;
>> +
>> +	count = size / BYTES_PER_RVA_RECORD;
>> +	for (i = 0; i < count; i++) {
>> +		vaddr = ((__be64) value[i * 3] << 32) | value[i * 3 + 1];
>> +		if (vaddr & ~PARTIAL_USED_VA_MASK) {
> 
> How can it work to test a __be64 against a non-byte-swapped mask ? But like I
> said above, please do this with a struct and proper endian conversions.

sure.

> 
>> +			pr_info("Reserved virtual address range starting "
>> +				"at [%llx000] verified for overlap\n", vaddr);
> 
> This should print nothing in the success case.

Not even as a pr_devel level message ? 

> 
>> +			continue;
>> +		}
>> +		BUG_ON("Reserved virtual address range overlapping");
> 
> But here you should provide more detail. The first thing a debugger will need
> to know is what address overlapped.

Sure, will provide the starting VA and the size of the range.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC] powerpc/mm: Add validation for platform reserved memory ranges
  2016-03-04  3:59   ` Anshuman Khandual
@ 2016-03-04  4:49     ` Aneesh Kumar K.V
  2016-03-04  5:46       ` Anshuman Khandual
  0 siblings, 1 reply; 5+ messages in thread
From: Aneesh Kumar K.V @ 2016-03-04  4:49 UTC (permalink / raw)
  To: Anshuman Khandual, Michael Ellerman, linuxppc-dev

Anshuman Khandual <khandual@linux.vnet.ibm.com> writes:

> On 03/02/2016 05:40 PM, Michael Ellerman wrote:
>> On Wed, 2016-02-03 at 08:46:12 UTC, Anshuman Khandual wrote:
>>> For partition running on PHYP, there can be a adjunct partition
>>> which shares the virtual address range with the operating system.
>>> Virtual address ranges which can be used by the adjunct partition
>>> are communicated with virtual device node of the device tree with
>>> a property known as "ibm,reserved-virtual-addresses". This patch
>>> introduces a new function named 'validate_reserved_va_range' which
>>> is called inside 'setup_system' to validate that these reserved
>>> virtual address ranges do not overlap with the address ranges used
>>> by the kernel for all supported memory contexts. This helps prevent
>>> the possibility of getting return codes similar to H_RESOURCE for
>>> H_PROTECT hcalls for conflicting HPTE entries.
>> 
>> Good plan.
>
> Thanks !
>
>> 
>>> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
>>> index 3d5abfe..95257c1 100644
>>> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
>>> index 5c03a6a..04bc592 100644
>>> --- a/arch/powerpc/kernel/setup_64.c
>>> +++ b/arch/powerpc/kernel/setup_64.c
>>> @@ -546,6 +546,8 @@ void __init setup_system(void)
>>>  	smp_release_cpus();
>>>  #endif
>>>  
>>> +	validate_reserved_va_range();
>>> +
>> 
>> I don't see why this can't just be an initcall in hash_utils_64.c, rather than
>> being called from here.
>
> That works, will change it.
>
>> 
>>>  	pr_info("Starting Linux %s %s\n", init_utsname()->machine,
>>>  		 init_utsname()->version);
>>>  
>>> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
>>> index ba59d59..03adafc 100644
>>> --- a/arch/powerpc/mm/hash_utils_64.c
>>> +++ b/arch/powerpc/mm/hash_utils_64.c
>>> @@ -810,6 +810,57 @@ void __init early_init_mmu(void)
>>>  	slb_initialize();
>>>  }
>>>  
>>> +/*
>>> + * PAPR says that each record contains 3 * 32 bit element, hence 12 bytes.
>>> + * First two element contains the abbreviated virtual address (high order
>>> + * 32 bits and low order 32 bits generates the abbreviated virtual address
>>> + * of 64 bits which need to be concatenated with 12 bits of 0 at the end
>>> + * to generate the actual 76 bit reserved virtual address) and size of the
>>> + * reserved virtual address range is encoded in next 32 bit element as number
>>> + * of 4K pages.
>>> + */
>>> +#define	BYTES_PER_RVA_RECORD	12
>> 
>> Please define a properly endian-annotated struct which encodes the layout.
>
> something like this ?
>
> struct reserved_va_record {
> 	__be32	high_addr;	/* High 32 bits of the abbreviated VA */
> 	__be32	low_addr;	/* Low 32 bits of the abbreviated VA */
> 	__be32	nr_4k;		/* VA range in multiple of 4K pages */
> };
>
>> 
>> It can be local to the function if that works.
>> 
>
> Okay.
>
>>> +/*
>>> + * Linux uses 65 bits (MAX_PHYSMEM_BITS + CONTEXT_BITS) from available 78
>>> + * bit wide virtual address range. As reserved virtual address range comes
>>> + * as an abbreviated form of 64 bits, we will use a partial address mask
>>> + * (65 bit mask >> 12) to match it for simplicity.
>>> + */
>>> +#define	PARTIAL_USED_VA_MASK	0x1FFFFFFFFFFFFFULL
>> 
>> Please calculate this from the appropriate constants. We don't want to have to
>> update it in future.
>
> Sure, I guess something like this works.
>
> #define RVA_SKIPPED_BITS        12      /* This changes with PAPR */
> #define USED_VA_BITS            MAX_PHYSMEM_BITS + CONTEXT_BITS

context + esid + sid shift it should be


> #define PARTIAL_USED_VA_MASK    ((1ULL << (USED_VA_BITS - RVA_SKIPPED_BITS)) - 1)
>
>> 
>>> +void __init validate_reserved_va_range(void)
>>> +{
>>> +	struct device_node *np;
>>> +	struct property *prop;
>>> +	unsigned int size, count, i;
>>> +	const __be32 *value;
>>> +	__be64 vaddr;
>>> +
>>> +	np = of_find_node_by_name(NULL, "vdevice");
>>> +	if (!np)
>>> +		return;
>>> +
>>> +	prop = of_find_property(np, "ibm,reserved-virtual-addresses", NULL);
>>> +	if (!prop)
>>> +		return;
>> 
>> You don't need to do a find, the get below will do it for you.
>
> Sure.
>
>> 
>>> +	value = of_get_property(np, "ibm,reserved-virtual-addresses", &size);
>>> +	if (!value)
>>> +		return;
>>> +
>>> +	count = size / BYTES_PER_RVA_RECORD;
>>> +	for (i = 0; i < count; i++) {
>>> +		vaddr = ((__be64) value[i * 3] << 32) | value[i * 3 + 1];
>>> +		if (vaddr & ~PARTIAL_USED_VA_MASK) {
>> 
>> How can it work to test a __be64 against a non-byte-swapped mask ? But like I
>> said above, please do this with a struct and proper endian conversions.
>
> sure.
>
>> 
>>> +			pr_info("Reserved virtual address range starting "
>>> +				"at [%llx000] verified for overlap\n", vaddr);
>> 
>> This should print nothing in the success case.
>
> Not even as a pr_devel level message ? 
>
>> 
>>> +			continue;
>>> +		}
>>> +		BUG_ON("Reserved virtual address range overlapping");
>> 
>> But here you should provide more detail. The first thing a debugger will need
>> to know is what address overlapped.
>
> Sure, will provide the starting VA and the size of the range.

-aneesh

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC] powerpc/mm: Add validation for platform reserved memory ranges
  2016-03-04  4:49     ` Aneesh Kumar K.V
@ 2016-03-04  5:46       ` Anshuman Khandual
  0 siblings, 0 replies; 5+ messages in thread
From: Anshuman Khandual @ 2016-03-04  5:46 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Michael Ellerman, linuxppc-dev

On 03/04/2016 10:19 AM, Aneesh Kumar K.V wrote:
> Anshuman Khandual <khandual@linux.vnet.ibm.com> writes:
> 
>> On 03/02/2016 05:40 PM, Michael Ellerman wrote:
>>> On Wed, 2016-02-03 at 08:46:12 UTC, Anshuman Khandual wrote:
>>>> For partition running on PHYP, there can be a adjunct partition
>>>> which shares the virtual address range with the operating system.
>>>> Virtual address ranges which can be used by the adjunct partition
>>>> are communicated with virtual device node of the device tree with
>>>> a property known as "ibm,reserved-virtual-addresses". This patch
>>>> introduces a new function named 'validate_reserved_va_range' which
>>>> is called inside 'setup_system' to validate that these reserved
>>>> virtual address ranges do not overlap with the address ranges used
>>>> by the kernel for all supported memory contexts. This helps prevent
>>>> the possibility of getting return codes similar to H_RESOURCE for
>>>> H_PROTECT hcalls for conflicting HPTE entries.
>>>
>>> Good plan.
>>
>> Thanks !
>>
>>>
>>>> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
>>>> index 3d5abfe..95257c1 100644
>>>> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
>>>> index 5c03a6a..04bc592 100644
>>>> --- a/arch/powerpc/kernel/setup_64.c
>>>> +++ b/arch/powerpc/kernel/setup_64.c
>>>> @@ -546,6 +546,8 @@ void __init setup_system(void)
>>>>  	smp_release_cpus();
>>>>  #endif
>>>>  
>>>> +	validate_reserved_va_range();
>>>> +
>>>
>>> I don't see why this can't just be an initcall in hash_utils_64.c, rather than
>>> being called from here.
>>
>> That works, will change it.
>>
>>>
>>>>  	pr_info("Starting Linux %s %s\n", init_utsname()->machine,
>>>>  		 init_utsname()->version);
>>>>  
>>>> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
>>>> index ba59d59..03adafc 100644
>>>> --- a/arch/powerpc/mm/hash_utils_64.c
>>>> +++ b/arch/powerpc/mm/hash_utils_64.c
>>>> @@ -810,6 +810,57 @@ void __init early_init_mmu(void)
>>>>  	slb_initialize();
>>>>  }
>>>>  
>>>> +/*
>>>> + * PAPR says that each record contains 3 * 32 bit element, hence 12 bytes.
>>>> + * First two element contains the abbreviated virtual address (high order
>>>> + * 32 bits and low order 32 bits generates the abbreviated virtual address
>>>> + * of 64 bits which need to be concatenated with 12 bits of 0 at the end
>>>> + * to generate the actual 76 bit reserved virtual address) and size of the
>>>> + * reserved virtual address range is encoded in next 32 bit element as number
>>>> + * of 4K pages.
>>>> + */
>>>> +#define	BYTES_PER_RVA_RECORD	12
>>>
>>> Please define a properly endian-annotated struct which encodes the layout.
>>
>> something like this ?
>>
>> struct reserved_va_record {
>> 	__be32	high_addr;	/* High 32 bits of the abbreviated VA */
>> 	__be32	low_addr;	/* Low 32 bits of the abbreviated VA */
>> 	__be32	nr_4k;		/* VA range in multiple of 4K pages */
>> };
>>
>>>
>>> It can be local to the function if that works.
>>>
>>
>> Okay.
>>
>>>> +/*
>>>> + * Linux uses 65 bits (MAX_PHYSMEM_BITS + CONTEXT_BITS) from available 78
>>>> + * bit wide virtual address range. As reserved virtual address range comes
>>>> + * as an abbreviated form of 64 bits, we will use a partial address mask
>>>> + * (65 bit mask >> 12) to match it for simplicity.
>>>> + */
>>>> +#define	PARTIAL_USED_VA_MASK	0x1FFFFFFFFFFFFFULL
>>>
>>> Please calculate this from the appropriate constants. We don't want to have to
>>> update it in future.
>>
>> Sure, I guess something like this works.
>>
>> #define RVA_SKIPPED_BITS        12      /* This changes with PAPR */
>> #define USED_VA_BITS            MAX_PHYSMEM_BITS + CONTEXT_BITS
> 
> context + esid + sid shift it should be

Yeah its more appropriate but but we dont have any constants like
ESID_SHIFT (or ESID_SHIFT_1T) to match SID_SHIFT (or SID_SHIFT_1T)
which adds up to 46 bits of EA.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-03-04  5:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-02  8:46 [RFC] powerpc/mm: Add validation for platform reserved memory ranges Anshuman Khandual
2016-03-02 12:10 ` Michael Ellerman
2016-03-04  3:59   ` Anshuman Khandual
2016-03-04  4:49     ` Aneesh Kumar K.V
2016-03-04  5:46       ` Anshuman Khandual

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.