OSDN Git Service

kvm: selftests: introduce new VM mode for 64K pages
authorAndrew Jones <drjones@redhat.com>
Tue, 18 Sep 2018 17:54:33 +0000 (19:54 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 16 Oct 2018 22:29:35 +0000 (00:29 +0200)
Rename VM_MODE_FLAT48PG to be more descriptive of its config and add a
new config that has the same parameters, except with 64K pages.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/lib/aarch64/processor.c
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/kvm_util_internal.h
tools/testing/selftests/kvm/lib/x86_64/processor.c

index e0c9cf4..88df26c 100644 (file)
@@ -34,9 +34,14 @@ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
 #define DEFAULT_STACK_PGS              5
 
 enum vm_guest_mode {
-       VM_MODE_FLAT48PG,
+       VM_MODE_P52V48_4K,
+       VM_MODE_P52V48_64K,
+       NUM_VM_MODES,
 };
 
+#define vm_guest_mode_string(m) vm_guest_mode_string[m]
+extern const char * const vm_guest_mode_string[];
+
 enum vm_mem_backing_src_type {
        VM_MEM_SRC_ANONYMOUS,
        VM_MEM_SRC_ANONYMOUS_THP,
index 871fe21..b1dfc0d 100644 (file)
@@ -226,7 +226,7 @@ struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
        uint64_t extra_pg_pages = (extra_mem_pages / ptrs_per_4k_pte) * 2;
        struct kvm_vm *vm;
 
-       vm = vm_create(VM_MODE_FLAT48PG, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
+       vm = vm_create(VM_MODE_P52V48_4K, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
 
        kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
        vm_vcpu_add_default(vm, vcpuid, guest_code);
@@ -267,10 +267,14 @@ void vcpu_setup(struct kvm_vm *vm, int vcpuid, int pgd_memslot, int gdt_memslot)
        get_reg(vm, vcpuid, ARM64_SYS_REG(TCR_EL1), &tcr_el1);
 
        switch (vm->mode) {
-       case VM_MODE_FLAT48PG:
+       case VM_MODE_P52V48_4K:
                tcr_el1 |= 0ul << 14; /* TG0 = 4KB */
                tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
                break;
+       case VM_MODE_P52V48_64K:
+               tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
+               tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
+               break;
        default:
                TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", vm->mode);
        }
index fd346fb..b37e52f 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/kernel.h>
 
 #define KVM_UTIL_PGS_PER_HUGEPG 512
-#define KVM_UTIL_MIN_PADDR      0x2000
+#define KVM_UTIL_MIN_PFN       2
 
 /* Aligns x up to the next multiple of size. Size must be a power of 2. */
 static void *align(void *x, size_t size)
@@ -96,11 +96,16 @@ static void vm_open(struct kvm_vm *vm, int perm)
                "rc: %i errno: %i", vm->fd, errno);
 }
 
+const char * const vm_guest_mode_string[] = {
+       "PA-bits:52, VA-bits:48, 4K pages",
+       "PA-bits:52, VA-bits:48, 64K pages",
+};
+
 /*
  * VM Create
  *
  * Input Args:
- *   mode - VM Mode (e.g. VM_MODE_FLAT48PG)
+ *   mode - VM Mode (e.g. VM_MODE_P52V48_4K)
  *   phy_pages - Physical memory pages
  *   perm - permission
  *
@@ -109,7 +114,7 @@ static void vm_open(struct kvm_vm *vm, int perm)
  * Return:
  *   Pointer to opaque structure that describes the created VM.
  *
- * Creates a VM with the mode specified by mode (e.g. VM_MODE_FLAT48PG).
+ * Creates a VM with the mode specified by mode (e.g. VM_MODE_P52V48_4K).
  * When phy_pages is non-zero, a memory region of phy_pages physical pages
  * is created and mapped starting at guest physical address 0.  The file
  * descriptor to control the created VM is created with the permissions
@@ -128,28 +133,34 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
 
        /* Setup mode specific traits. */
        switch (vm->mode) {
-       case VM_MODE_FLAT48PG:
+       case VM_MODE_P52V48_4K:
                vm->pgtable_levels = 4;
                vm->page_size = 0x1000;
                vm->page_shift = 12;
                vm->va_bits = 48;
-
-               /* Limit to 48-bit canonical virtual addresses. */
-               vm->vpages_valid = sparsebit_alloc();
-               sparsebit_set_num(vm->vpages_valid,
-                       0, (1ULL << (48 - 1)) >> vm->page_shift);
-               sparsebit_set_num(vm->vpages_valid,
-                       (~((1ULL << (48 - 1)) - 1)) >> vm->page_shift,
-                       (1ULL << (48 - 1)) >> vm->page_shift);
-
-               /* Limit physical addresses to 52-bits. */
-               vm->max_gfn = ((1ULL << 52) >> vm->page_shift) - 1;
                break;
-
+       case VM_MODE_P52V48_64K:
+               vm->pgtable_levels = 3;
+               vm->pa_bits = 52;
+               vm->page_size = 0x10000;
+               vm->page_shift = 16;
+               vm->va_bits = 48;
+               break;
        default:
                TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", mode);
        }
 
+       /* Limit to VA-bit canonical virtual addresses. */
+       vm->vpages_valid = sparsebit_alloc();
+       sparsebit_set_num(vm->vpages_valid,
+               0, (1ULL << (vm->va_bits - 1)) >> vm->page_shift);
+       sparsebit_set_num(vm->vpages_valid,
+               (~((1ULL << (vm->va_bits - 1)) - 1)) >> vm->page_shift,
+               (1ULL << (vm->va_bits - 1)) >> vm->page_shift);
+
+       /* Limit physical addresses to PA-bits. */
+       vm->max_gfn = ((1ULL << vm->pa_bits) >> vm->page_shift) - 1;
+
        /* Allocate and setup memory for guest. */
        vm->vpages_mapped = sparsebit_alloc();
        if (phy_pages != 0)
@@ -868,7 +879,8 @@ vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
                pages--, vaddr += vm->page_size) {
                vm_paddr_t paddr;
 
-               paddr = vm_phy_page_alloc(vm, KVM_UTIL_MIN_PADDR, data_memslot);
+               paddr = vm_phy_page_alloc(vm,
+                               KVM_UTIL_MIN_PFN * vm->page_size, data_memslot);
 
                virt_pg_map(vm, vaddr, paddr, pgd_memslot);
 
index d048d73..52701db 100644 (file)
@@ -49,6 +49,7 @@ struct kvm_vm {
        unsigned int pgtable_levels;
        unsigned int page_size;
        unsigned int page_shift;
+       unsigned int pa_bits;
        unsigned int va_bits;
        uint64_t max_gfn;
        struct vcpu *vcpu_head;
index 67f84fb..f28127f 100644 (file)
@@ -231,7 +231,7 @@ void virt_pgd_alloc(struct kvm_vm *vm, uint32_t pgd_memslot)
 {
        int rc;
 
-       TEST_ASSERT(vm->mode == VM_MODE_FLAT48PG, "Attempt to use "
+       TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use "
                "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
 
        /* If needed, create page map l4 table. */
@@ -264,7 +264,7 @@ void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
        uint16_t index[4];
        struct pageMapL4Entry *pml4e;
 
-       TEST_ASSERT(vm->mode == VM_MODE_FLAT48PG, "Attempt to use "
+       TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use "
                "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
 
        TEST_ASSERT((vaddr % vm->page_size) == 0,
@@ -551,7 +551,7 @@ vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
        struct pageTableEntry *pte;
        void *hva;
 
-       TEST_ASSERT(vm->mode == VM_MODE_FLAT48PG, "Attempt to use "
+       TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use "
                "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
 
        index[0] = (gva >> 12) & 0x1ffu;
@@ -624,7 +624,7 @@ void vcpu_setup(struct kvm_vm *vm, int vcpuid, int pgd_memslot, int gdt_memslot)
        kvm_setup_gdt(vm, &sregs.gdt, gdt_memslot, pgd_memslot);
 
        switch (vm->mode) {
-       case VM_MODE_FLAT48PG:
+       case VM_MODE_P52V48_4K:
                sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG;
                sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR;
                sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX);
@@ -823,7 +823,7 @@ struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
        uint64_t extra_pg_pages = extra_mem_pages / 512 * 2;
 
        /* Create VM */
-       vm = vm_create(VM_MODE_FLAT48PG,
+       vm = vm_create(VM_MODE_P52V48_4K,
                       DEFAULT_GUEST_PHY_PAGES + extra_pg_pages,
                       O_RDWR);