Merge tag 'kvm-x86-selftests-6.9' of https://github.com/kvm-x86/linux into HEAD
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 11 Mar 2024 14:20:35 +0000 (10:20 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 11 Mar 2024 14:20:35 +0000 (10:20 -0400)
KVM selftests changes for 6.9:

 - Add macros to reduce the amount of boilerplate code needed to write "simple"
   selftests, and to utilize selftest TAP infrastructure, which is especially
   beneficial for KVM selftests with multiple testcases.

 - Add basic smoke tests for SEV and SEV-ES, along with a pile of library
   support for handling private/encrypted/protected memory.

 - Fix benign bugs where tests neglect to close() guest_memfd files.

1  2 
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/include/kvm_util_base.h
tools/testing/selftests/kvm/include/x86_64/processor.h
tools/testing/selftests/kvm/lib/aarch64/processor.c
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/riscv/processor.c
tools/testing/selftests/kvm/lib/s390x/processor.c
tools/testing/selftests/kvm/lib/x86_64/processor.c
tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
tools/testing/selftests/kvm/x86_64/sync_regs_test.c

Simple merge
index 39c2499df34106645f794fe37aae80676ca49b7d,4a40b332115d34559eb48c8a25a2cd0e4bf7cbef..9ff131a6a1a56c1dcf7d1133144117ad0bbdff7c
@@@ -1081,6 -1124,6 +1124,8 @@@ void kvm_selftest_arch_init(void)
  
  void kvm_arch_vm_post_create(struct kvm_vm *vm);
  
+ bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr);
 +uint32_t guest_get_vcpuid(void);
 +
  #endif /* SELFTEST_KVM_UTIL_BASE_H */
index ec66d331a127389447510070d4fdfb916ffa4155,c993947f07823f09fb151578b2dad2c43e0eff32..e8211f5d68637ea7d0b9916e7931a23c0573dbe0
@@@ -324,11 -316,7 +328,10 @@@ struct kvm_vcpu *vm_arch_vcpu_add(struc
  
        /* Setup stack pointer and program counter of guest */
        vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.sp), stack_vaddr + stack_size);
-       vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.pc), (unsigned long)guest_code);
  
 +      /* Setup sscratch for guest_get_vcpuid() */
 +      vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(sscratch), vcpu_id);
 +
        /* Setup default exception vector of guest */
        vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(stvec), (unsigned long)guest_unexp_trap);
  
index f639b3e062e3a328165bfb6ed32f606cf1f48e76,49288fe10cd34eeb84a252260d4acbc271b1d5ac..c3bb2eb38cffedf60580e7e69dd23f77cb7acf00
@@@ -220,8 -225,17 +225,17 @@@ void __virt_pg_map(struct kvm_vm *vm, u
        /* Fill in page table entry. */
        pte = virt_get_pte(vm, pde, vaddr, PG_LEVEL_4K);
        TEST_ASSERT(!(*pte & PTE_PRESENT_MASK),
 -                  "PTE already present for 4k page at vaddr: 0x%lx\n", vaddr);
 +                  "PTE already present for 4k page at vaddr: 0x%lx", vaddr);
        *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK);
+       /*
+        * Neither SEV nor TDX supports shared page tables, so only the final
+        * leaf PTE needs manually set the C/S-bit.
+        */
+       if (vm_is_gpa_protected(vm, paddr))
+               *pte |= vm->arch.c_bit;
+       else
+               *pte |= vm->arch.s_bit;
  }
  
  void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)
index a49828adf2949464b668f530a977e9efd9d75888,ec3709e1c6847621e652452d4bcdd8c60df39600..0a6dfba3905b68c03cebaf1e821c7019c4a68cf1
@@@ -227,16 -203,16 +203,16 @@@ static void sev_mirror_create(struct kv
        int ret;
  
        ret = __sev_mirror_create(dst, src);
 -      TEST_ASSERT(!ret, "Copying context failed, ret: %d, errno: %d\n", ret, errno);
 +      TEST_ASSERT(!ret, "Copying context failed, ret: %d, errno: %d", ret, errno);
  }
  
- static void verify_mirror_allowed_cmds(int vm_fd)
+ static void verify_mirror_allowed_cmds(struct kvm_vm *vm)
  {
        struct kvm_sev_guest_status status;
+       int cmd_id;
  
-       for (int cmd_id = KVM_SEV_INIT; cmd_id < KVM_SEV_NR_MAX; ++cmd_id) {
+       for (cmd_id = KVM_SEV_INIT; cmd_id < KVM_SEV_NR_MAX; ++cmd_id) {
                int ret;
-               __u32 fw_error;
  
                /*
                 * These commands are allowed for mirror VMs, all others are
                 * These commands should be disallowed before the data
                 * parameter is examined so NULL is OK here.
                 */
-               ret = __sev_ioctl(vm_fd, cmd_id, NULL, &fw_error);
+               ret = __vm_sev_ioctl(vm, cmd_id, NULL);
                TEST_ASSERT(
                        ret == -1 && errno == EINVAL,
 -                      "Should not be able call command: %d. ret: %d, errno: %d\n",
 +                      "Should not be able call command: %d. ret: %d, errno: %d",
                        cmd_id, ret, errno);
        }
  
index a91b5b145fa35ac81dfaa225ff350e4186a229d0,67f78c0a58a51844e75df58383c53d31bc7d6591..adb5593daf483ec6b84d18dda8f5ebf8823a6827
@@@ -237,9 -223,15 +223,15 @@@ KVM_ONE_VCPU_TEST(sync_regs_test, read_
        run->kvm_valid_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS;
        rv = _vcpu_run(vcpu);
        TEST_ASSERT(rv < 0 && errno == EINVAL,
 -                  "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n",
 +                  "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d",
                    rv);
        run->kvm_valid_regs = 0;
+ }
+ KVM_ONE_VCPU_TEST(sync_regs_test, set_invalid, guest_code)
+ {
+       struct kvm_run *run = vcpu->run;
+       int rv;
  
        /* Request setting invalid register set into VCPU. */
        run->kvm_dirty_regs = INVALID_SYNC_FIELD;
        run->kvm_dirty_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS;
        rv = _vcpu_run(vcpu);
        TEST_ASSERT(rv < 0 && errno == EINVAL,
 -                  "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n",
 +                  "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d",
                    rv);
        run->kvm_dirty_regs = 0;
+ }
+ KVM_ONE_VCPU_TEST(sync_regs_test, req_and_verify_all_valid, guest_code)
+ {
+       struct kvm_run *run = vcpu->run;
+       struct kvm_vcpu_events events;
+       struct kvm_sregs sregs;
+       struct kvm_regs regs;
  
        /* Request and verify all valid register sets. */
        /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */