ARM64 支持多种虚拟地址长度,在运行时可通过 vabits_actual
变量判别。
vabits_actual
由 5383cc6efed1 (“arm64: mm: Introduce vabits_actual”)
于 v5.4 引入(patchwork 链接
),由 67e7fdfcc682 (“arm64: mm: introduce 52-bit userspace support”)
引入的 vabits_user
演进而来。
在 v5.10 中,该变量的赋值位于 arch/arm64/kernel/head.S 的 __create_page_tables
:
1#ifdef CONFIG_ARM64_VA_BITS_52
2 mrs_s x6, SYS_ID_AA64MMFR2_EL1
3 and x6, x6, #(0xf << ID_AA64MMFR2_LVA_SHIFT)
4 mov x5, #52
5 cbnz x6, 1f
6#endif
7 mov x5, #VA_BITS_MIN
81:
9 adr_l x6, vabits_actual
10 str x5, [x6]
11 dmb sy
12 dc ivac, x6 // Invalidate potentially stale cache line
当前主线(v6.2)中的实现,与 5.10 相比有较大变化:
1 /*
2 * The following callee saved general purpose registers are used on the
3 * primary lowlevel boot path:
4 *
5 * Register Scope Purpose
6 * x20 primary_entry() .. __primary_switch() CPU boot mode
7 * x21 primary_entry() .. start_kernel() FDT pointer passed at boot in x0
8 * x22 create_idmap() .. start_kernel() ID map VA of the DT blob
9 * x23 primary_entry() .. start_kernel() physical misalignment/KASLR offset
10 * x24 __primary_switch() linear map KASLR seed
11 * x25 primary_entry() .. start_kernel() supported VA size
12 * x28 create_idmap() callee preserved temp register
13 */
14SYM_CODE_START(primary_entry)
15 /* . . . */
16#if VA_BITS > 48
17 mrs_s x0, SYS_ID_AA64MMFR2_EL1
18 tst x0, #0xf << ID_AA64MMFR2_EL1_VARange_SHIFT
19 mov x0, #VA_BITS
20 mov x25, #VA_BITS_MIN
21 csel x25, x25, x0, eq
22 mov x0, x25
23#endif
24
25 /* . . . */
26
27SYM_FUNC_START_LOCAL(__primary_switched)
28 /* . . . */
29#if VA_BITS > 48
30 adr_l x8, vabits_actual // Set this early so KASAN early init
31 str x25, [x8] // ... observes the correct value
32 dc civac, x8 // Make visible to booting secondaries
33#endif
代码中还有两个与之类似的常量:VA_BITS
和 VA_BITS_MIN
:
1// arch/arm64/include/asm/memory.h
2#if VA_BITS > 48
3#define VA_BITS_MIN (48)
4#else
5#define VA_BITS_MIN (VA_BITS)
6#endif
内核文档 Documentation/arm64/memory.rst 中 “52-bit VA support in the kernel” 一节有对上述三者的描述:
Most code in the kernel should not need to consider the
VA_BITS
, for code that does need to know the VA size the variables are defined as follows:
VA_BITS
constant the maximum VA space sizeVA_BITS_MIN
constant the minimum VA space sizevabits_actual
variable the actual VA space sizeMaximum and minimum sizes can be useful to ensure that buffers are sized large enough or that addresses are positioned close enough for the “worst” case.
虚拟地址长度设定条件: