Skip to contentSkip to conversation

arm64: Expose physical/virtual address bits through cpuinfo

RFC PATCH New Kefeng Wang 3 participants 6 messages Mar 17, 2016 – Mar 21, 2016 arm64

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 arm64: Expose physical/virtual address bits through cpuinfo

AArch64 support six types Physical Address range, permitted values in ID_AA64MMFR0_EL1 are:

0000  32 bits, 4GB.
0001  36 bits, 64GB.
0010  40 bits, 1TB.
0011  42 bits, 4TB.
0100  44 bits, 16TB.
0101  48 bits, 256TB.

All other values are reserved.

Meanwhile, AArch64 allows 36-bit, 39-bit, 42-bit, 47-bit and 48-bit virtual addresses.

Exposing the physical and virtual address bits to userspace through procfs like x86, then it is easy to check them from cpuinfo.

---
 arch/arm64/include/asm/cpufeature.h | 11 +++++++++++
 arch/arm64/kernel/cpuinfo.c         |  4 +++-
 2 files changed, 14 insertions(+), 1 deletion(-)
arch/arm64/include/asm/cpufeature.h +11 -0
index a5c769b..33a9dc5 100644
@@ -188,6 +188,17 @@ static inline bool system_supports_mixed_endian_el0(void)
 	return id_aa64mmfr0_mixed_endian_el0(read_system_reg(SYS_ID_AA64MMFR0_EL1));
 }
 
+static inline int id_aa64mmfr0_parange_bits(void)
+{
+	/*
+	 * PARange[3:0] allows 0~5, other values are reserved,
+	 * convert to physical address bits with a simple formula.
+	 */
+	u32 parange = read_system_reg(SYS_ID_AA64MMFR0_EL1) & 0xf;
+
+	return parange < 3 ? 32 + parange * 4 : 42 + (parange - 3) * (parange - 2);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif
arch/arm64/kernel/cpuinfo.c +3 -1
index 212ae63..f6b49db 100644
@@ -146,7 +146,9 @@ static int c_show(struct seq_file *m, void *v)
 		seq_printf(m, "CPU architecture: 8\n");
 		seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
 		seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
-		seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
+		seq_printf(m, "CPU revision\t: %d\n", MIDR_REVISION(midr));
+		seq_printf(m, "address sizes\t: %d bits physical, %d bits virtual\n\n",
+			   id_aa64mmfr0_parange_bits(), VA_BITS);
 	}
 
 	return 0;
Signature · 1 line
1.7.12.4
#1 lore raw

RFC PATCH 1/1 arm64: Expose physical/virtual address bits through cpuinfo

Quoted 8 lines · Kefeng Wang

AArch64 support six types Physical Address range, permitted values in ID_AA64MMFR0_EL1 are:

0000  32 bits, 4GB.
0001  36 bits, 64GB.
0010  40 bits, 1TB.
0011  42 bits, 4TB.
0100  44 bits, 16TB.
0101  48 bits, 256TB.
Quoted 4 lines

All other values are reserved.

Meanwhile, AArch64 allows 36-bit, 39-bit, 42-bit, 47-bit and 48-bit virtual addresses.

See below..

arch/arm64/include/asm/cpufeature.h static inline bool system_supports_mixed_endian_el0(void) · line 199

Quoted 10 lines
arch/arm64/include/asm/cpufeature.h +9 -0
+static inline int id_aa64mmfr0_parange_bits(void)
+{
+	/*
+	 * PARange[3:0] allows 0~5, other values are reserved,
+	 * convert to physical address bits with a simple formula.
+	 */
+	u32 parange = read_system_reg(SYS_ID_AA64MMFR0_EL1) & 0xf;
+
+	return parange < 3 ? 32 + parange * 4 : 42 + (parange - 3) * (parange - 2);

This breaks for 52bit PA support added in ARMv8.2 [1]. It may be a good idea to use an array here.

Quoted 10 lines
arch/arm64/include/asm/cpufeature.h +2 -0
+}
+
  #endif /* __ASSEMBLY__ */
 
  #endif
arch/arm64/kernel/cpuinfo.c +0 -0
index 212ae63..f6b49db 100644

arch/arm64/kernel/cpuinfo.c static int c_show(struct seq_file *m, void *v) · line 151

Quoted 7 lines
arch/arm64/kernel/cpuinfo.c +3 -1
@@ -146,7 +146,9 @@ static int c_show(struct seq_file *m, void *v)
  		seq_printf(m, "CPU architecture: 8\n");
  		seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
  		seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
-		seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
+		seq_printf(m, "CPU revision\t: %d\n", MIDR_REVISION(midr));
+		seq_printf(m, "address sizes\t: %d bits physical, %d bits virtual\n\n",
+			   id_aa64mmfr0_parange_bits(), VA_BITS);

VA_BITS is an attribute of your running kernel and doesn't have anything to do with what the CPU can support. (e.g, it is 48bit on 8.0, 8.1, but could go upto 52 in 8.2)

[1] https://community.arm.com/groups/processors/blog/2016/01/05/armv8-a-architecture-evolution

Also, I am not sure if the change above would break userspace parsing the info. Ideally it shouldn't , but...

Thanks
Suzuki

#2 lore raw

RFC PATCH 1/1 arm64: Expose physical/virtual address bits through cpuinfo

Quoted 2 lines · Suzuki K. Poulose
Quoted 1 line · Kefeng Wang

AArch64 support six types Physical Address range, permitted values

[...]

Quoted 4 lines
Quoted 4 lines
arch/arm64/include/asm/cpufeature.h +4 -0
+static inline int id_aa64mmfr0_parange_bits(void)
+{
+    /*
+     * PARange[3:0] allows 0~5, other values are reserved,
Quoted 8 lines

arch/arm64/include/asm/cpufeature.h static inline bool system_supports_mixed_endian_el0(void) · line 199

Quoted 5 lines
arch/arm64/include/asm/cpufeature.h +5 -0
+     * convert to physical address bits with a simple formula.
+     */
+    u32 parange = read_system_reg(SYS_ID_AA64MMFR0_EL1) & 0xf;
+
+    return parange < 3 ? 32 + parange * 4 : 42 + (parange - 3) * (parange - 2);

This breaks for 52bit PA support added in ARMv8.2 [1]. It may be a good idea to use an array here.

Thanks for your reminder, will use array.

Quoted 5 lines
Quoted 5 lines
arch/arm64/include/asm/cpufeature.h +2 -0
+}
+
  #endif /* __ASSEMBLY__ */
Quoted 16 lines

arch/arm64/kernel/cpuinfo.c static int c_show(struct seq_file *m, void *v) · line 151

Quoted 13 lines
  #endif
arch/arm64/kernel/cpuinfo.c +3 -1
index 212ae63..f6b49db 100644
@@ -146,7 +146,9 @@ static int c_show(struct seq_file *m, void *v)
          seq_printf(m, "CPU architecture: 8\n");
          seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
          seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
-        seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
+        seq_printf(m, "CPU revision\t: %d\n", MIDR_REVISION(midr));
+        seq_printf(m, "address sizes\t: %d bits physical, %d bits virtual\n\n",
+               id_aa64mmfr0_parange_bits(), VA_BITS);

VA_BITS is an attribute of your running kernel and doesn't have anything to do with what the CPU can support. (e.g, it is 48bit on 8.0, 8.1, but could go upto 52 in 8.2)

After check the new id register id_aa64mmfr2 in armv8.2, I think we can use the LVA(larger virtual address) bit of id_aa64mmfr2 to get virtual address bits supported by cpu, what's opinion?

BTW, is it allowed to post patch by me to add more field of id_aa64mmfr2, if not, please let me know, thanks.

BRs,
Kefeng

Quoted 11 lines

[1] https://community.arm.com/groups/processors/blog/2016/01/05/armv8-a-architecture-evolution

Also, I am not sure if the change above would break userspace parsing the info. Ideally it shouldn't , but...

Thanks
Suzuki

.

#3 lore raw

RFC PATCH 1/1 arm64: Expose physical/virtual address bits through cpuinfo

Quoted 6 lines · Kefeng Wang
Quoted 2 lines · Suzuki K. Poulose
Quoted 1 line · Kefeng Wang

AArch64 support six types Physical Address range, permitted values

[...]

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

+static inline int id_aa64mmfr0_parange_bits(void)

VA_BITS is an attribute of your running kernel and doesn't have anything to do with what the CPU can support. (e.g, it is 48bit on 8.0, 8.1, but could go upto 52 in 8.2)

After check the new id register id_aa64mmfr2 in armv8.2, I think we can use the LVA(larger virtual address) bit of id_aa64mmfr2 to get virtual address bits supported by cpu, what's opinion?

Thats the only way to do it.

Quoted 2 lines

BTW, is it allowed to post patch by me to add more field of id_aa64mmfr2,

Of course. Also, since we use read_system_reg(), the values (pa and va width) won't change across the CPUs. Hence, you may avoid multiple extraction routines and reuse the results for one iteration.

Cheers
Suzuki

maintainer
#4 lore raw

RFC PATCH 1/1 arm64: Expose physical/virtual address bits through cpuinfo

In reply to Kefeng Wang
Quoted 8 lines · Kefeng Wang

AArch64 support six types Physical Address range, permitted values in ID_AA64MMFR0_EL1 are:

0000  32 bits, 4GB.
0001  36 bits, 64GB.
0010  40 bits, 1TB.
0011  42 bits, 4TB.
0100  44 bits, 16TB.
0101  48 bits, 256TB.
Quoted 7 lines

All other values are reserved.

Meanwhile, AArch64 allows 36-bit, 39-bit, 42-bit, 47-bit and 48-bit virtual addresses.

Exposing the physical and virtual address bits to userspace through procfs like x86, then it is easy to check them from cpuinfo.

So, what does user space need such information for?

Signature · 1 line
Catalin
#5 lore raw

RFC PATCH 1/1 arm64: Expose physical/virtual address bits through cpuinfo

Quoted 11 lines · Catalin Marinas
Quoted 10 lines · Kefeng Wang

AArch64 support six types Physical Address range, permitted values in ID_AA64MMFR0_EL1 are:

0000  32 bits, 4GB.
0001  36 bits, 64GB.
0010  40 bits, 1TB.
0011  42 bits, 4TB.
0100  44 bits, 16TB.
0101  48 bits, 256TB.

All other values are reserved.

Quoted 7 lines
Quoted 5 lines

Meanwhile, AArch64 allows 36-bit, 39-bit, 42-bit, 47-bit and 48-bit virtual addresses.

Exposing the physical and virtual address bits to userspace through procfs like x86, then it is easy to check them from cpuinfo.

So, what does user space need such information for?

For now, no user app use this, it just shows the physical/virtual address size that is supported by cpu.

AArch64 supports several different types of physical/virtual address bits(up to 52bit in ARMv8.2 especially), I think it's better to expose it, and cpuinfo is proper space.