[2/2] arm64: Expose PARange via ID_AA64MMFR0_EL1 and VARange via ID_AA64MMFR2_EL1
diff mbox series

Message ID 1548709076-22317-3-git-send-email-bhsharma@redhat.com
State New
Headers show
Series
  • arm64: Expose physical and virtual address capabilities to user-space
Related show

Commit Message

Bhupesh Sharma Jan. 28, 2019, 8:57 p.m. UTC
ARMv8.2 architecture hardware extensions can support
upto 52-bit physical addresses (ARMv8.2-LPA) and 52-bit virtual
addresses (ARMv8.2-LVA).

User-space utilities like 'makedumpfile' can try and use the getauxval()
function to retrieve the underlying PARange and VARange values
supported.

An example implementation can be via the 'Appendix I: Example' shown
in 'Documentation/arm64/cpu-feature-registers.txt'. A reference
'makedumpfile' implementation which uses a similar approach is
available in [0].

So, we expose these properties via 'FTR_NONSTRICT' and 'FTR_VISIBLE'
settings for 'ID_AA64MMFR0_PARANGE_SHIFT' and 'ID_AA64MMFR2_LVA_SHIFT'.

[0]. https://github.com/bhupesh-sharma/makedumpfile/blob/9d7da4aad3efe79b448f48cc3454fcae46a316d6/arch/arm64.c#L499

Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
---
 arch/arm64/kernel/cpufeature.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Suzuki K Poulose Jan. 29, 2019, 10:14 a.m. UTC | #1
Hi,

On 28/01/2019 20:57, Bhupesh Sharma wrote:
> ARMv8.2 architecture hardware extensions can support
> upto 52-bit physical addresses (ARMv8.2-LPA) and 52-bit virtual
> addresses (ARMv8.2-LVA).
> 
> User-space utilities like 'makedumpfile' can try and use the getauxval()
> function to retrieve the underlying PARange and VARange values
> supported.

Why do we need VARange here ? This value could be different from the
kernel VA. As for decoding the PTE, you could safely do the flip
of the upper byte by checking the page size of 64K.

What is the usecase for exposing the PARange ?

> 
> An example implementation can be via the 'Appendix I: Example' shown
> in 'Documentation/arm64/cpu-feature-registers.txt'. A reference
> 'makedumpfile' implementation which uses a similar approach is
> available in [0].
> 
> So, we expose these properties via 'FTR_NONSTRICT' and 'FTR_VISIBLE'
> settings for 'ID_AA64MMFR0_PARANGE_SHIFT' and 'ID_AA64MMFR2_LVA_SHIFT'.

What is the rationale behind changing the feature to NONSTRICT ?

> 
> [0]. https://github.com/bhupesh-sharma/makedumpfile/blob/9d7da4aad3efe79b448f48cc3454fcae46a316d6/arch/arm64.c#L499

Btw, if you are not using a 64K page size, the usage of the lva support
feature could corrupt your PTE-> PHYS conversion, unless I am missing something.

Suzuki
Bhupesh Sharma Jan. 30, 2019, 8:27 p.m. UTC | #2
Hi Suzuki,

Thanks for the review.

On 01/29/2019 03:44 PM, Suzuki K Poulose wrote:
> Hi,
> 
> On 28/01/2019 20:57, Bhupesh Sharma wrote:
>> ARMv8.2 architecture hardware extensions can support
>> upto 52-bit physical addresses (ARMv8.2-LPA) and 52-bit virtual
>> addresses (ARMv8.2-LVA).
>>
>> User-space utilities like 'makedumpfile' can try and use the getauxval()
>> function to retrieve the underlying PARange and VARange values
>> supported.
> 
> Why do we need VARange here ? This value could be different from the
> kernel VA. As for decoding the PTE, you could safely do the flip
> of the upper byte by checking the page size of 64K.

I shared the makedumpfile implementation (for decoding the PTE) just as 
an example, however there can be other user-space applications, for e.g 
a user-space application running with 48-bit kernel VA and 52-bit user 
space VA and requesting allocation in 'high' address via a 'hint' to 
mmap (See 
<http://lists.infradead.org/pipermail/kexec/2019-January/022389.html> 
for details).

As I mentioned in the reply to the 1/2 PATCH review, I can see only two 
methods to determine the underlying kernel support in such cases:

a). Read the CONFIG flags from .config, or

b). In absence of .config file on the system, read the system ID
registers like 'ID_AA64MMFR0_EL1' and 'ID_AA64MMFR2_EL1' and then make a
decision on whether to pass a hint to 'mmap'.

> What is the usecase for exposing the PARange ?

Again it's perfectly possible to use a 48-bit VA in kernel/user-space 
and 52-bit PA overall. This means that the user-space applications need 
to again depend on reading CONFIG file changes for reading the PARange 
and VARange values to determine the actual values set on the hardware 
before they can make a 'mmap' call.

Also one can use the VARange and PARange values (printed or returned as 
part of the user-space application code) to inform the overall calling 
benchmarkingtest-suite about the address space configuration for which 
the test-suite was executed.

>>
>> An example implementation can be via the 'Appendix I: Example' shown
>> in 'Documentation/arm64/cpu-feature-registers.txt'. A reference
>> 'makedumpfile' implementation which uses a similar approach is
>> available in [0].
>>
>> So, we expose these properties via 'FTR_NONSTRICT' and 'FTR_VISIBLE'
>> settings for 'ID_AA64MMFR0_PARANGE_SHIFT' and 'ID_AA64MMFR2_LVA_SHIFT'.
> 
> What is the rationale behind changing the feature to NONSTRICT ?

Yes, this seems like a left-over. Will fix in v2.

>>
>> [0]. 
>> https://github.com/bhupesh-sharma/makedumpfile/blob/9d7da4aad3efe79b448f48cc3454fcae46a316d6/arch/arm64.c#L499 
>>
> 
> Btw, if you are not using a 64K page size, the usage of the lva support
> feature could corrupt your PTE-> PHYS conversion, unless I am missing 
> something.

Fedora arm64 servers use 64K page size by default.

Also as a side note, perhaps the ABI example for the system id register 
access 
<https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt> 
needs to be updated for ARMv8.2 (as it doesn't support ID_AA64MMFR2_EL1 
via get_cpu_ftr(). May be I can send a separate patch to address the same.

Please let me know your thoughts on the same.

Thanks,
Bhupesh

Patch
diff mbox series

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index f6d84e2c92fe..5cfc08cbf147 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -194,7 +194,7 @@  static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
 	 * Differing PARange is fine as long as all peripherals and memory are mapped
 	 * within the minimum PARange of all CPUs
 	 */
-	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_PARANGE_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_PARANGE_SHIFT, 4, 0),
 	ARM64_FTR_END,
 };
 
@@ -211,7 +211,7 @@  static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
 static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_FWB_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_AT_SHIFT, 4, 0),
-	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_IESB_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LSM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_UAO_SHIFT, 4, 0),