mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
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 <maz@kernel.org> Reviewed-by: Andrew Jones <drjones@redhat.com> Link: https://lore.kernel.org/r/20211227124809.1335409-7-maz@kernel.org
This commit is contained in:
parent
e7f58a6bd2
commit
aa674de1dc
@ -42,14 +42,18 @@ enum vm_guest_mode {
|
|||||||
VM_MODE_P52V48_4K,
|
VM_MODE_P52V48_4K,
|
||||||
VM_MODE_P52V48_64K,
|
VM_MODE_P52V48_64K,
|
||||||
VM_MODE_P48V48_4K,
|
VM_MODE_P48V48_4K,
|
||||||
|
VM_MODE_P48V48_16K,
|
||||||
VM_MODE_P48V48_64K,
|
VM_MODE_P48V48_64K,
|
||||||
VM_MODE_P40V48_4K,
|
VM_MODE_P40V48_4K,
|
||||||
|
VM_MODE_P40V48_16K,
|
||||||
VM_MODE_P40V48_64K,
|
VM_MODE_P40V48_64K,
|
||||||
VM_MODE_PXXV48_4K, /* For 48bits VA but ANY bits PA */
|
VM_MODE_PXXV48_4K, /* For 48bits VA but ANY bits PA */
|
||||||
VM_MODE_P47V64_4K,
|
VM_MODE_P47V64_4K,
|
||||||
VM_MODE_P44V64_4K,
|
VM_MODE_P44V64_4K,
|
||||||
VM_MODE_P36V48_4K,
|
VM_MODE_P36V48_4K,
|
||||||
|
VM_MODE_P36V48_16K,
|
||||||
VM_MODE_P36V48_64K,
|
VM_MODE_P36V48_64K,
|
||||||
|
VM_MODE_P36V47_16K,
|
||||||
NUM_VM_MODES,
|
NUM_VM_MODES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -252,6 +252,12 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
|
|||||||
case VM_MODE_P36V48_64K:
|
case VM_MODE_P36V48_64K:
|
||||||
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
|
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
|
||||||
break;
|
break;
|
||||||
|
case VM_MODE_P48V48_16K:
|
||||||
|
case VM_MODE_P40V48_16K:
|
||||||
|
case VM_MODE_P36V48_16K:
|
||||||
|
case VM_MODE_P36V47_16K:
|
||||||
|
tcr_el1 |= 2ul << 14; /* TG0 = 16KB */
|
||||||
|
break;
|
||||||
case VM_MODE_P48V48_4K:
|
case VM_MODE_P48V48_4K:
|
||||||
case VM_MODE_P40V48_4K:
|
case VM_MODE_P40V48_4K:
|
||||||
case VM_MODE_P36V48_4K:
|
case VM_MODE_P36V48_4K:
|
||||||
@ -267,15 +273,19 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
|
|||||||
tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
|
tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
|
||||||
break;
|
break;
|
||||||
case VM_MODE_P48V48_4K:
|
case VM_MODE_P48V48_4K:
|
||||||
|
case VM_MODE_P48V48_16K:
|
||||||
case VM_MODE_P48V48_64K:
|
case VM_MODE_P48V48_64K:
|
||||||
tcr_el1 |= 5ul << 32; /* IPS = 48 bits */
|
tcr_el1 |= 5ul << 32; /* IPS = 48 bits */
|
||||||
break;
|
break;
|
||||||
case VM_MODE_P40V48_4K:
|
case VM_MODE_P40V48_4K:
|
||||||
|
case VM_MODE_P40V48_16K:
|
||||||
case VM_MODE_P40V48_64K:
|
case VM_MODE_P40V48_64K:
|
||||||
tcr_el1 |= 2ul << 32; /* IPS = 40 bits */
|
tcr_el1 |= 2ul << 32; /* IPS = 40 bits */
|
||||||
break;
|
break;
|
||||||
case VM_MODE_P36V48_4K:
|
case VM_MODE_P36V48_4K:
|
||||||
|
case VM_MODE_P36V48_16K:
|
||||||
case VM_MODE_P36V48_64K:
|
case VM_MODE_P36V48_64K:
|
||||||
|
case VM_MODE_P36V47_16K:
|
||||||
tcr_el1 |= 1ul << 32; /* IPS = 36 bits */
|
tcr_el1 |= 1ul << 32; /* IPS = 36 bits */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -29,17 +29,21 @@ void guest_modes_append_default(void)
|
|||||||
guest_mode_append(VM_MODE_P52V48_64K, ps64k, ps64k);
|
guest_mode_append(VM_MODE_P52V48_64K, ps64k, ps64k);
|
||||||
if (limit >= 48) {
|
if (limit >= 48) {
|
||||||
guest_mode_append(VM_MODE_P48V48_4K, ps4k, ps4k);
|
guest_mode_append(VM_MODE_P48V48_4K, ps4k, ps4k);
|
||||||
|
guest_mode_append(VM_MODE_P48V48_16K, ps16k, ps16k);
|
||||||
guest_mode_append(VM_MODE_P48V48_64K, ps64k, ps64k);
|
guest_mode_append(VM_MODE_P48V48_64K, ps64k, ps64k);
|
||||||
}
|
}
|
||||||
if (limit >= 40) {
|
if (limit >= 40) {
|
||||||
guest_mode_append(VM_MODE_P40V48_4K, ps4k, ps4k);
|
guest_mode_append(VM_MODE_P40V48_4K, ps4k, ps4k);
|
||||||
|
guest_mode_append(VM_MODE_P40V48_16K, ps16k, ps16k);
|
||||||
guest_mode_append(VM_MODE_P40V48_64K, ps64k, ps64k);
|
guest_mode_append(VM_MODE_P40V48_64K, ps64k, ps64k);
|
||||||
if (ps4k)
|
if (ps4k)
|
||||||
vm_mode_default = VM_MODE_P40V48_4K;
|
vm_mode_default = VM_MODE_P40V48_4K;
|
||||||
}
|
}
|
||||||
if (limit >= 36) {
|
if (limit >= 36) {
|
||||||
guest_mode_append(VM_MODE_P36V48_4K, ps4k, ps4k);
|
guest_mode_append(VM_MODE_P36V48_4K, ps4k, ps4k);
|
||||||
|
guest_mode_append(VM_MODE_P36V48_16K, ps16k, ps16k);
|
||||||
guest_mode_append(VM_MODE_P36V48_64K, ps64k, ps64k);
|
guest_mode_append(VM_MODE_P36V48_64K, ps64k, ps64k);
|
||||||
|
guest_mode_append(VM_MODE_P36V47_16K, ps16k, ps16k);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -166,14 +166,18 @@ const char *vm_guest_mode_string(uint32_t i)
|
|||||||
[VM_MODE_P52V48_4K] = "PA-bits:52, VA-bits:48, 4K pages",
|
[VM_MODE_P52V48_4K] = "PA-bits:52, VA-bits:48, 4K pages",
|
||||||
[VM_MODE_P52V48_64K] = "PA-bits:52, VA-bits:48, 64K pages",
|
[VM_MODE_P52V48_64K] = "PA-bits:52, VA-bits:48, 64K pages",
|
||||||
[VM_MODE_P48V48_4K] = "PA-bits:48, VA-bits:48, 4K pages",
|
[VM_MODE_P48V48_4K] = "PA-bits:48, VA-bits:48, 4K pages",
|
||||||
|
[VM_MODE_P48V48_16K] = "PA-bits:48, VA-bits:48, 16K pages",
|
||||||
[VM_MODE_P48V48_64K] = "PA-bits:48, VA-bits:48, 64K pages",
|
[VM_MODE_P48V48_64K] = "PA-bits:48, VA-bits:48, 64K pages",
|
||||||
[VM_MODE_P40V48_4K] = "PA-bits:40, VA-bits:48, 4K pages",
|
[VM_MODE_P40V48_4K] = "PA-bits:40, VA-bits:48, 4K pages",
|
||||||
|
[VM_MODE_P40V48_16K] = "PA-bits:40, VA-bits:48, 16K pages",
|
||||||
[VM_MODE_P40V48_64K] = "PA-bits:40, VA-bits:48, 64K pages",
|
[VM_MODE_P40V48_64K] = "PA-bits:40, VA-bits:48, 64K pages",
|
||||||
[VM_MODE_PXXV48_4K] = "PA-bits:ANY, VA-bits:48, 4K pages",
|
[VM_MODE_PXXV48_4K] = "PA-bits:ANY, VA-bits:48, 4K pages",
|
||||||
[VM_MODE_P47V64_4K] = "PA-bits:47, VA-bits:64, 4K pages",
|
[VM_MODE_P47V64_4K] = "PA-bits:47, VA-bits:64, 4K pages",
|
||||||
[VM_MODE_P44V64_4K] = "PA-bits:44, VA-bits:64, 4K pages",
|
[VM_MODE_P44V64_4K] = "PA-bits:44, VA-bits:64, 4K pages",
|
||||||
[VM_MODE_P36V48_4K] = "PA-bits:36, VA-bits:48, 4K pages",
|
[VM_MODE_P36V48_4K] = "PA-bits:36, VA-bits:48, 4K pages",
|
||||||
|
[VM_MODE_P36V48_16K] = "PA-bits:36, VA-bits:48, 16K pages",
|
||||||
[VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
|
[VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
|
||||||
|
[VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages",
|
||||||
};
|
};
|
||||||
_Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
|
_Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
|
||||||
"Missing new mode strings?");
|
"Missing new mode strings?");
|
||||||
@ -187,14 +191,18 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
|
|||||||
[VM_MODE_P52V48_4K] = { 52, 48, 0x1000, 12 },
|
[VM_MODE_P52V48_4K] = { 52, 48, 0x1000, 12 },
|
||||||
[VM_MODE_P52V48_64K] = { 52, 48, 0x10000, 16 },
|
[VM_MODE_P52V48_64K] = { 52, 48, 0x10000, 16 },
|
||||||
[VM_MODE_P48V48_4K] = { 48, 48, 0x1000, 12 },
|
[VM_MODE_P48V48_4K] = { 48, 48, 0x1000, 12 },
|
||||||
|
[VM_MODE_P48V48_16K] = { 48, 48, 0x4000, 14 },
|
||||||
[VM_MODE_P48V48_64K] = { 48, 48, 0x10000, 16 },
|
[VM_MODE_P48V48_64K] = { 48, 48, 0x10000, 16 },
|
||||||
[VM_MODE_P40V48_4K] = { 40, 48, 0x1000, 12 },
|
[VM_MODE_P40V48_4K] = { 40, 48, 0x1000, 12 },
|
||||||
|
[VM_MODE_P40V48_16K] = { 40, 48, 0x4000, 14 },
|
||||||
[VM_MODE_P40V48_64K] = { 40, 48, 0x10000, 16 },
|
[VM_MODE_P40V48_64K] = { 40, 48, 0x10000, 16 },
|
||||||
[VM_MODE_PXXV48_4K] = { 0, 0, 0x1000, 12 },
|
[VM_MODE_PXXV48_4K] = { 0, 0, 0x1000, 12 },
|
||||||
[VM_MODE_P47V64_4K] = { 47, 64, 0x1000, 12 },
|
[VM_MODE_P47V64_4K] = { 47, 64, 0x1000, 12 },
|
||||||
[VM_MODE_P44V64_4K] = { 44, 64, 0x1000, 12 },
|
[VM_MODE_P44V64_4K] = { 44, 64, 0x1000, 12 },
|
||||||
[VM_MODE_P36V48_4K] = { 36, 48, 0x1000, 12 },
|
[VM_MODE_P36V48_4K] = { 36, 48, 0x1000, 12 },
|
||||||
|
[VM_MODE_P36V48_16K] = { 36, 48, 0x4000, 14 },
|
||||||
[VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
|
[VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
|
||||||
|
[VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 },
|
||||||
};
|
};
|
||||||
_Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
|
_Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
|
||||||
"Missing new mode params?");
|
"Missing new mode params?");
|
||||||
@ -263,6 +271,14 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
|
|||||||
case VM_MODE_P36V48_64K:
|
case VM_MODE_P36V48_64K:
|
||||||
vm->pgtable_levels = 3;
|
vm->pgtable_levels = 3;
|
||||||
break;
|
break;
|
||||||
|
case VM_MODE_P48V48_16K:
|
||||||
|
case VM_MODE_P40V48_16K:
|
||||||
|
case VM_MODE_P36V48_16K:
|
||||||
|
vm->pgtable_levels = 4;
|
||||||
|
break;
|
||||||
|
case VM_MODE_P36V47_16K:
|
||||||
|
vm->pgtable_levels = 3;
|
||||||
|
break;
|
||||||
case VM_MODE_PXXV48_4K:
|
case VM_MODE_PXXV48_4K:
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits);
|
kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits);
|
||||||
|
Loading…
Reference in New Issue
Block a user