Skip to content

Commit aa674de

Browse files
author
Marc Zyngier
committed
KVM: selftests: arm64: Add support for various modes with 16kB page size
The 16kB page size is not a popular choice, due to only a few CPUs actually implementing support for it. However, it can lead to some interesting performance improvements given the right uarch choices. Add support for this page size for various PA/VA combinations. Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent e7f58a6 commit aa674de

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,18 @@ enum vm_guest_mode {
4242
VM_MODE_P52V48_4K,
4343
VM_MODE_P52V48_64K,
4444
VM_MODE_P48V48_4K,
45+
VM_MODE_P48V48_16K,
4546
VM_MODE_P48V48_64K,
4647
VM_MODE_P40V48_4K,
48+
VM_MODE_P40V48_16K,
4749
VM_MODE_P40V48_64K,
4850
VM_MODE_PXXV48_4K, /* For 48bits VA but ANY bits PA */
4951
VM_MODE_P47V64_4K,
5052
VM_MODE_P44V64_4K,
5153
VM_MODE_P36V48_4K,
54+
VM_MODE_P36V48_16K,
5255
VM_MODE_P36V48_64K,
56+
VM_MODE_P36V47_16K,
5357
NUM_VM_MODES,
5458
};
5559

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,12 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
252252
case VM_MODE_P36V48_64K:
253253
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
254254
break;
255+
case VM_MODE_P48V48_16K:
256+
case VM_MODE_P40V48_16K:
257+
case VM_MODE_P36V48_16K:
258+
case VM_MODE_P36V47_16K:
259+
tcr_el1 |= 2ul << 14; /* TG0 = 16KB */
260+
break;
255261
case VM_MODE_P48V48_4K:
256262
case VM_MODE_P40V48_4K:
257263
case VM_MODE_P36V48_4K:
@@ -267,15 +273,19 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
267273
tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
268274
break;
269275
case VM_MODE_P48V48_4K:
276+
case VM_MODE_P48V48_16K:
270277
case VM_MODE_P48V48_64K:
271278
tcr_el1 |= 5ul << 32; /* IPS = 48 bits */
272279
break;
273280
case VM_MODE_P40V48_4K:
281+
case VM_MODE_P40V48_16K:
274282
case VM_MODE_P40V48_64K:
275283
tcr_el1 |= 2ul << 32; /* IPS = 40 bits */
276284
break;
277285
case VM_MODE_P36V48_4K:
286+
case VM_MODE_P36V48_16K:
278287
case VM_MODE_P36V48_64K:
288+
case VM_MODE_P36V47_16K:
279289
tcr_el1 |= 1ul << 32; /* IPS = 36 bits */
280290
break;
281291
default:

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,21 @@ void guest_modes_append_default(void)
2929
guest_mode_append(VM_MODE_P52V48_64K, ps64k, ps64k);
3030
if (limit >= 48) {
3131
guest_mode_append(VM_MODE_P48V48_4K, ps4k, ps4k);
32+
guest_mode_append(VM_MODE_P48V48_16K, ps16k, ps16k);
3233
guest_mode_append(VM_MODE_P48V48_64K, ps64k, ps64k);
3334
}
3435
if (limit >= 40) {
3536
guest_mode_append(VM_MODE_P40V48_4K, ps4k, ps4k);
37+
guest_mode_append(VM_MODE_P40V48_16K, ps16k, ps16k);
3638
guest_mode_append(VM_MODE_P40V48_64K, ps64k, ps64k);
3739
if (ps4k)
3840
vm_mode_default = VM_MODE_P40V48_4K;
3941
}
4042
if (limit >= 36) {
4143
guest_mode_append(VM_MODE_P36V48_4K, ps4k, ps4k);
44+
guest_mode_append(VM_MODE_P36V48_16K, ps16k, ps16k);
4245
guest_mode_append(VM_MODE_P36V48_64K, ps64k, ps64k);
46+
guest_mode_append(VM_MODE_P36V47_16K, ps16k, ps16k);
4347
}
4448

4549
/*

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,18 @@ const char *vm_guest_mode_string(uint32_t i)
166166
[VM_MODE_P52V48_4K] = "PA-bits:52, VA-bits:48, 4K pages",
167167
[VM_MODE_P52V48_64K] = "PA-bits:52, VA-bits:48, 64K pages",
168168
[VM_MODE_P48V48_4K] = "PA-bits:48, VA-bits:48, 4K pages",
169+
[VM_MODE_P48V48_16K] = "PA-bits:48, VA-bits:48, 16K pages",
169170
[VM_MODE_P48V48_64K] = "PA-bits:48, VA-bits:48, 64K pages",
170171
[VM_MODE_P40V48_4K] = "PA-bits:40, VA-bits:48, 4K pages",
172+
[VM_MODE_P40V48_16K] = "PA-bits:40, VA-bits:48, 16K pages",
171173
[VM_MODE_P40V48_64K] = "PA-bits:40, VA-bits:48, 64K pages",
172174
[VM_MODE_PXXV48_4K] = "PA-bits:ANY, VA-bits:48, 4K pages",
173175
[VM_MODE_P47V64_4K] = "PA-bits:47, VA-bits:64, 4K pages",
174176
[VM_MODE_P44V64_4K] = "PA-bits:44, VA-bits:64, 4K pages",
175177
[VM_MODE_P36V48_4K] = "PA-bits:36, VA-bits:48, 4K pages",
178+
[VM_MODE_P36V48_16K] = "PA-bits:36, VA-bits:48, 16K pages",
176179
[VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
180+
[VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages",
177181
};
178182
_Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
179183
"Missing new mode strings?");
@@ -187,14 +191,18 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
187191
[VM_MODE_P52V48_4K] = { 52, 48, 0x1000, 12 },
188192
[VM_MODE_P52V48_64K] = { 52, 48, 0x10000, 16 },
189193
[VM_MODE_P48V48_4K] = { 48, 48, 0x1000, 12 },
194+
[VM_MODE_P48V48_16K] = { 48, 48, 0x4000, 14 },
190195
[VM_MODE_P48V48_64K] = { 48, 48, 0x10000, 16 },
191196
[VM_MODE_P40V48_4K] = { 40, 48, 0x1000, 12 },
197+
[VM_MODE_P40V48_16K] = { 40, 48, 0x4000, 14 },
192198
[VM_MODE_P40V48_64K] = { 40, 48, 0x10000, 16 },
193199
[VM_MODE_PXXV48_4K] = { 0, 0, 0x1000, 12 },
194200
[VM_MODE_P47V64_4K] = { 47, 64, 0x1000, 12 },
195201
[VM_MODE_P44V64_4K] = { 44, 64, 0x1000, 12 },
196202
[VM_MODE_P36V48_4K] = { 36, 48, 0x1000, 12 },
203+
[VM_MODE_P36V48_16K] = { 36, 48, 0x4000, 14 },
197204
[VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
205+
[VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 },
198206
};
199207
_Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
200208
"Missing new mode params?");
@@ -263,6 +271,14 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
263271
case VM_MODE_P36V48_64K:
264272
vm->pgtable_levels = 3;
265273
break;
274+
case VM_MODE_P48V48_16K:
275+
case VM_MODE_P40V48_16K:
276+
case VM_MODE_P36V48_16K:
277+
vm->pgtable_levels = 4;
278+
break;
279+
case VM_MODE_P36V47_16K:
280+
vm->pgtable_levels = 3;
281+
break;
266282
case VM_MODE_PXXV48_4K:
267283
#ifdef __x86_64__
268284
kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits);

0 commit comments

Comments
 (0)