Skip to content

Commit 10a0cc3

Browse files
ryanhrobMarc Zyngier
authored andcommitted
KVM: selftests: arm64: Support P52V48 4K and 16K guest_modes
Add support for VM_MODE_P52V48_4K and VM_MODE_P52V48_16K guest modes by using the FEAT_LPA2 pte format for stage1, when FEAT_LPA2 is available. Reviewed-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20231127111737.1897081-13-ryan.roberts@arm.com
1 parent 72324ac commit 10a0cc3

4 files changed

Lines changed: 36 additions & 9 deletions

File tree

tools/testing/selftests/kvm/include/kvm_util_base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ static inline struct userspace_mem_region *vm_get_mem_region(struct kvm_vm *vm,
171171

172172
enum vm_guest_mode {
173173
VM_MODE_P52V48_4K,
174+
VM_MODE_P52V48_16K,
174175
VM_MODE_P52V48_64K,
175176
VM_MODE_P48V48_4K,
176177
VM_MODE_P48V48_16K,

tools/testing/selftests/kvm/lib/aarch64/processor.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "kvm_util.h"
1313
#include "processor.h"
1414
#include <linux/bitfield.h>
15+
#include <linux/sizes.h>
1516

1617
#define DEFAULT_ARM64_GUEST_STACK_VADDR_MIN 0xac0000
1718

@@ -58,13 +59,25 @@ static uint64_t pte_index(struct kvm_vm *vm, vm_vaddr_t gva)
5859
return (gva >> vm->page_shift) & mask;
5960
}
6061

62+
static inline bool use_lpa2_pte_format(struct kvm_vm *vm)
63+
{
64+
return (vm->page_size == SZ_4K || vm->page_size == SZ_16K) &&
65+
(vm->pa_bits > 48 || vm->va_bits > 48);
66+
}
67+
6168
static uint64_t addr_pte(struct kvm_vm *vm, uint64_t pa, uint64_t attrs)
6269
{
6370
uint64_t pte;
6471

65-
pte = pa & GENMASK(47, vm->page_shift);
66-
if (vm->page_shift == 16)
67-
pte |= FIELD_GET(GENMASK(51, 48), pa) << 12;
72+
if (use_lpa2_pte_format(vm)) {
73+
pte = pa & GENMASK(49, vm->page_shift);
74+
pte |= FIELD_GET(GENMASK(51, 50), pa) << 8;
75+
attrs &= ~GENMASK(9, 8);
76+
} else {
77+
pte = pa & GENMASK(47, vm->page_shift);
78+
if (vm->page_shift == 16)
79+
pte |= FIELD_GET(GENMASK(51, 48), pa) << 12;
80+
}
6881
pte |= attrs;
6982

7083
return pte;
@@ -74,9 +87,14 @@ static uint64_t pte_addr(struct kvm_vm *vm, uint64_t pte)
7487
{
7588
uint64_t pa;
7689

77-
pa = pte & GENMASK(47, vm->page_shift);
78-
if (vm->page_shift == 16)
79-
pa |= FIELD_GET(GENMASK(15, 12), pte) << 48;
90+
if (use_lpa2_pte_format(vm)) {
91+
pa = pte & GENMASK(49, vm->page_shift);
92+
pa |= FIELD_GET(GENMASK(9, 8), pte) << 50;
93+
} else {
94+
pa = pte & GENMASK(47, vm->page_shift);
95+
if (vm->page_shift == 16)
96+
pa |= FIELD_GET(GENMASK(15, 12), pte) << 48;
97+
}
8098

8199
return pa;
82100
}
@@ -266,9 +284,6 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
266284

267285
/* Configure base granule size */
268286
switch (vm->mode) {
269-
case VM_MODE_P52V48_4K:
270-
TEST_FAIL("AArch64 does not support 4K sized pages "
271-
"with 52-bit physical address ranges");
272287
case VM_MODE_PXXV48_4K:
273288
TEST_FAIL("AArch64 does not support 4K sized pages "
274289
"with ANY-bit physical address ranges");
@@ -278,12 +293,14 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
278293
case VM_MODE_P36V48_64K:
279294
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
280295
break;
296+
case VM_MODE_P52V48_16K:
281297
case VM_MODE_P48V48_16K:
282298
case VM_MODE_P40V48_16K:
283299
case VM_MODE_P36V48_16K:
284300
case VM_MODE_P36V47_16K:
285301
tcr_el1 |= 2ul << 14; /* TG0 = 16KB */
286302
break;
303+
case VM_MODE_P52V48_4K:
287304
case VM_MODE_P48V48_4K:
288305
case VM_MODE_P40V48_4K:
289306
case VM_MODE_P36V48_4K:
@@ -297,6 +314,8 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
297314

298315
/* Configure output size */
299316
switch (vm->mode) {
317+
case VM_MODE_P52V48_4K:
318+
case VM_MODE_P52V48_16K:
300319
case VM_MODE_P52V48_64K:
301320
tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
302321
ttbr0_el1 |= FIELD_GET(GENMASK(51, 48), vm->pgd) << 2;
@@ -325,6 +344,8 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
325344
/* TCR_EL1 |= IRGN0:WBWA | ORGN0:WBWA | SH0:Inner-Shareable */;
326345
tcr_el1 |= (1 << 8) | (1 << 10) | (3 << 12);
327346
tcr_el1 |= (64 - vm->va_bits) /* T0SZ */;
347+
if (use_lpa2_pte_format(vm))
348+
tcr_el1 |= (1ul << 59) /* DS */;
328349

329350
vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1), sctlr_el1);
330351
vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1), tcr_el1);

tools/testing/selftests/kvm/lib/guest_modes.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ void guest_modes_append_default(void)
2323

2424
aarch64_get_supported_page_sizes(limit, &ipa4k, &ipa16k, &ipa64k);
2525

26+
guest_mode_append(VM_MODE_P52V48_4K, ipa4k >= 52);
27+
guest_mode_append(VM_MODE_P52V48_16K, ipa16k >= 52);
2628
guest_mode_append(VM_MODE_P52V48_64K, ipa64k >= 52);
2729

2830
guest_mode_append(VM_MODE_P48V48_4K, ipa4k >= 48);

tools/testing/selftests/kvm/lib/kvm_util.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ const char *vm_guest_mode_string(uint32_t i)
148148
{
149149
static const char * const strings[] = {
150150
[VM_MODE_P52V48_4K] = "PA-bits:52, VA-bits:48, 4K pages",
151+
[VM_MODE_P52V48_16K] = "PA-bits:52, VA-bits:48, 16K pages",
151152
[VM_MODE_P52V48_64K] = "PA-bits:52, VA-bits:48, 64K pages",
152153
[VM_MODE_P48V48_4K] = "PA-bits:48, VA-bits:48, 4K pages",
153154
[VM_MODE_P48V48_16K] = "PA-bits:48, VA-bits:48, 16K pages",
@@ -173,6 +174,7 @@ const char *vm_guest_mode_string(uint32_t i)
173174

174175
const struct vm_guest_mode_params vm_guest_mode_params[] = {
175176
[VM_MODE_P52V48_4K] = { 52, 48, 0x1000, 12 },
177+
[VM_MODE_P52V48_16K] = { 52, 48, 0x4000, 14 },
176178
[VM_MODE_P52V48_64K] = { 52, 48, 0x10000, 16 },
177179
[VM_MODE_P48V48_4K] = { 48, 48, 0x1000, 12 },
178180
[VM_MODE_P48V48_16K] = { 48, 48, 0x4000, 14 },
@@ -251,6 +253,7 @@ struct kvm_vm *____vm_create(enum vm_guest_mode mode)
251253
case VM_MODE_P36V48_64K:
252254
vm->pgtable_levels = 3;
253255
break;
256+
case VM_MODE_P52V48_16K:
254257
case VM_MODE_P48V48_16K:
255258
case VM_MODE_P40V48_16K:
256259
case VM_MODE_P36V48_16K:

0 commit comments

Comments
 (0)