KVM: selftests: arm64: Add support for VM_MODE_P36V48_{4K,64K}
Some of the arm64 systems out there have an IPA space that is positively tiny. Nonetheless, they make great KVM hosts. Add support for 36bit IPA support with 4kB pages, which makes some of the fruity machines happy. Whilst we're at it, add support for 64kB pages as well, though these boxes have no support for it. Reviewed-by: Andrew Jones <drjones@redhat.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20211227124809.1335409-6-maz@kernel.org
This commit is contained in:
Родитель
2f41a61c54
Коммит
e7f58a6bd2
|
@ -48,6 +48,8 @@ enum vm_guest_mode {
|
||||||
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_64K,
|
||||||
NUM_VM_MODES,
|
NUM_VM_MODES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -249,10 +249,12 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
|
||||||
case VM_MODE_P52V48_64K:
|
case VM_MODE_P52V48_64K:
|
||||||
case VM_MODE_P48V48_64K:
|
case VM_MODE_P48V48_64K:
|
||||||
case VM_MODE_P40V48_64K:
|
case VM_MODE_P40V48_64K:
|
||||||
|
case VM_MODE_P36V48_64K:
|
||||||
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
|
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
|
||||||
break;
|
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:
|
||||||
tcr_el1 |= 0ul << 14; /* TG0 = 4KB */
|
tcr_el1 |= 0ul << 14; /* TG0 = 4KB */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -272,6 +274,10 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
|
||||||
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_64K:
|
||||||
|
tcr_el1 |= 1ul << 32; /* IPS = 36 bits */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
|
TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@ void guest_modes_append_default(void)
|
||||||
if (ps4k)
|
if (ps4k)
|
||||||
vm_mode_default = VM_MODE_P40V48_4K;
|
vm_mode_default = VM_MODE_P40V48_4K;
|
||||||
}
|
}
|
||||||
|
if (limit >= 36) {
|
||||||
|
guest_mode_append(VM_MODE_P36V48_4K, ps4k, ps4k);
|
||||||
|
guest_mode_append(VM_MODE_P36V48_64K, ps64k, ps64k);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pick the first supported IPA size if the default
|
* Pick the first supported IPA size if the default
|
||||||
|
|
|
@ -172,6 +172,8 @@ const char *vm_guest_mode_string(uint32_t i)
|
||||||
[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_64K] = "PA-bits:36, VA-bits:48, 64K 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?");
|
||||||
|
@ -191,6 +193,8 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
|
||||||
[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_64K] = { 36, 48, 0x10000, 16 },
|
||||||
};
|
};
|
||||||
_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?");
|
||||||
|
@ -252,9 +256,11 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
|
||||||
vm->pgtable_levels = 3;
|
vm->pgtable_levels = 3;
|
||||||
break;
|
break;
|
||||||
case VM_MODE_P40V48_4K:
|
case VM_MODE_P40V48_4K:
|
||||||
|
case VM_MODE_P36V48_4K:
|
||||||
vm->pgtable_levels = 4;
|
vm->pgtable_levels = 4;
|
||||||
break;
|
break;
|
||||||
case VM_MODE_P40V48_64K:
|
case VM_MODE_P40V48_64K:
|
||||||
|
case VM_MODE_P36V48_64K:
|
||||||
vm->pgtable_levels = 3;
|
vm->pgtable_levels = 3;
|
||||||
break;
|
break;
|
||||||
case VM_MODE_PXXV48_4K:
|
case VM_MODE_PXXV48_4K:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче