Commit cdbd2428 authored by Andrew Jones's avatar Andrew Jones Committed by Paolo Bonzini

kvm: selftests: add pa-48/va-48 VM modes

Signed-off-by: default avatarAndrew Jones <drjones@redhat.com>
Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
parent 696ade77
...@@ -36,6 +36,8 @@ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */ ...@@ -36,6 +36,8 @@ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
enum vm_guest_mode { 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_64K,
VM_MODE_P40V48_4K, VM_MODE_P40V48_4K,
VM_MODE_P40V48_64K, VM_MODE_P40V48_64K,
NUM_VM_MODES, NUM_VM_MODES,
......
...@@ -268,13 +268,20 @@ void vcpu_setup(struct kvm_vm *vm, int vcpuid, int pgd_memslot, int gdt_memslot) ...@@ -268,13 +268,20 @@ void vcpu_setup(struct kvm_vm *vm, int vcpuid, int pgd_memslot, int gdt_memslot)
switch (vm->mode) { switch (vm->mode) {
case VM_MODE_P52V48_4K: case VM_MODE_P52V48_4K:
tcr_el1 |= 0ul << 14; /* TG0 = 4KB */ TEST_ASSERT(false, "AArch64 does not support 4K sized pages "
tcr_el1 |= 6ul << 32; /* IPS = 52 bits */ "with 52-bit physical address ranges");
break;
case VM_MODE_P52V48_64K: case VM_MODE_P52V48_64K:
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */ tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
tcr_el1 |= 6ul << 32; /* IPS = 52 bits */ tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
break; break;
case VM_MODE_P48V48_4K:
tcr_el1 |= 0ul << 14; /* TG0 = 4KB */
tcr_el1 |= 5ul << 32; /* IPS = 48 bits */
break;
case VM_MODE_P48V48_64K:
tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
tcr_el1 |= 5ul << 32; /* IPS = 48 bits */
break;
case VM_MODE_P40V48_4K: case VM_MODE_P40V48_4K:
tcr_el1 |= 0ul << 14; /* TG0 = 4KB */ tcr_el1 |= 0ul << 14; /* TG0 = 4KB */
tcr_el1 |= 2ul << 32; /* IPS = 40 bits */ tcr_el1 |= 2ul << 32; /* IPS = 40 bits */
...@@ -305,7 +312,6 @@ void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid, uint8_t indent) ...@@ -305,7 +312,6 @@ void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid, uint8_t indent)
get_reg(vm, vcpuid, ARM64_CORE_REG(regs.pstate), &pstate); get_reg(vm, vcpuid, ARM64_CORE_REG(regs.pstate), &pstate);
get_reg(vm, vcpuid, ARM64_CORE_REG(regs.pc), &pc); get_reg(vm, vcpuid, ARM64_CORE_REG(regs.pc), &pc);
fprintf(stream, "%*spstate: 0x%.16llx pc: 0x%.16llx\n", fprintf(stream, "%*spstate: 0x%.16llx pc: 0x%.16llx\n",
indent, "", pstate, pc); indent, "", pstate, pc);
} }
...@@ -99,9 +99,13 @@ static void vm_open(struct kvm_vm *vm, int perm) ...@@ -99,9 +99,13 @@ static void vm_open(struct kvm_vm *vm, int perm)
const char * const vm_guest_mode_string[] = { const char * const vm_guest_mode_string[] = {
"PA-bits:52, VA-bits:48, 4K pages", "PA-bits:52, VA-bits:48, 4K pages",
"PA-bits:52, VA-bits:48, 64K pages", "PA-bits:52, VA-bits:48, 64K pages",
"PA-bits:48, VA-bits:48, 4K pages",
"PA-bits:48, VA-bits:48, 64K pages",
"PA-bits:40, VA-bits:48, 4K pages", "PA-bits:40, VA-bits:48, 4K pages",
"PA-bits:40, VA-bits:48, 64K pages", "PA-bits:40, VA-bits:48, 64K pages",
}; };
_Static_assert(sizeof(vm_guest_mode_string)/sizeof(char *) == NUM_VM_MODES,
"Missing new mode strings?");
/* /*
* VM Create * VM Create
...@@ -137,16 +141,31 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) ...@@ -137,16 +141,31 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
switch (vm->mode) { switch (vm->mode) {
case VM_MODE_P52V48_4K: case VM_MODE_P52V48_4K:
vm->pgtable_levels = 4; vm->pgtable_levels = 4;
vm->pa_bits = 52;
vm->va_bits = 48;
vm->page_size = 0x1000; vm->page_size = 0x1000;
vm->page_shift = 12; vm->page_shift = 12;
vm->va_bits = 48;
break; break;
case VM_MODE_P52V48_64K: case VM_MODE_P52V48_64K:
vm->pgtable_levels = 3; vm->pgtable_levels = 3;
vm->pa_bits = 52; vm->pa_bits = 52;
vm->va_bits = 48;
vm->page_size = 0x10000; vm->page_size = 0x10000;
vm->page_shift = 16; vm->page_shift = 16;
break;
case VM_MODE_P48V48_4K:
vm->pgtable_levels = 4;
vm->pa_bits = 48;
vm->va_bits = 48; vm->va_bits = 48;
vm->page_size = 0x1000;
vm->page_shift = 12;
break;
case VM_MODE_P48V48_64K:
vm->pgtable_levels = 3;
vm->pa_bits = 48;
vm->va_bits = 48;
vm->page_size = 0x10000;
vm->page_shift = 16;
break; break;
case VM_MODE_P40V48_4K: case VM_MODE_P40V48_4K:
vm->pgtable_levels = 4; vm->pgtable_levels = 4;
...@@ -1445,7 +1464,7 @@ const char *exit_reason_str(unsigned int exit_reason) ...@@ -1445,7 +1464,7 @@ const char *exit_reason_str(unsigned int exit_reason)
* *
* Within the VM specified by vm, locates a range of available physical * Within the VM specified by vm, locates a range of available physical
* pages at or above paddr_min. If found, the pages are marked as in use * pages at or above paddr_min. If found, the pages are marked as in use
* and thier base address is returned. A TEST_ASSERT failure occurs if * and their base address is returned. A TEST_ASSERT failure occurs if
* not enough pages are available at or above paddr_min. * not enough pages are available at or above paddr_min.
*/ */
vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment