]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
KVM: selftests: Consolidate boilerplate code in get_ucall()
authorSean Christopherson <seanjc@google.com>
Thu, 6 Oct 2022 00:34:04 +0000 (00:34 +0000)
committerSean Christopherson <seanjc@google.com>
Thu, 17 Nov 2022 00:58:51 +0000 (16:58 -0800)
Consolidate the actual copying of a ucall struct from guest=>host into
the common get_ucall().  Return a host virtual address instead of a guest
virtual address even though the addr_gva2hva() part could be moved to
get_ucall() too.  Conceptually, get_ucall() is invoked from the host and
should return a host virtual address (and returning NULL for "nothing to
see here" is far superior to returning 0).

Use pointer shenanigans instead of an unnecessary bounce buffer when the
caller of get_ucall() provides a valid pointer.

Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
Tested-by: Peter Gonda <pgonda@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Link: https://lore.kernel.org/r/20221006003409.649993-3-seanjc@google.com
tools/testing/selftests/kvm/include/ucall_common.h
tools/testing/selftests/kvm/lib/aarch64/ucall.c
tools/testing/selftests/kvm/lib/riscv/ucall.c
tools/testing/selftests/kvm/lib/s390x/ucall.c
tools/testing/selftests/kvm/lib/ucall_common.c
tools/testing/selftests/kvm/lib/x86_64/ucall.c

index 5a85f5318bbe5968d9b12dc8f5bad17dec9a7ee6..63bfc60be995ebc8056f85312ca8d7fc779d03b4 100644 (file)
@@ -27,9 +27,10 @@ struct ucall {
 void ucall_arch_init(struct kvm_vm *vm, void *arg);
 void ucall_arch_uninit(struct kvm_vm *vm);
 void ucall_arch_do_ucall(vm_vaddr_t uc);
-uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc);
+void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu);
 
 void ucall(uint64_t cmd, int nargs, ...);
+uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc);
 
 static inline void ucall_init(struct kvm_vm *vm, void *arg)
 {
@@ -41,11 +42,6 @@ static inline void ucall_uninit(struct kvm_vm *vm)
        ucall_arch_uninit(vm);
 }
 
-static inline uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
-{
-       return ucall_arch_get_ucall(vcpu, uc);
-}
-
 #define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4) \
                                ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4)
 #define GUEST_SYNC(stage)      ucall(UCALL_SYNC, 2, "hello", stage)
index 3630708c32d627eb3a5b0838865bc24bb6c0a191..f214f5cc53d3be117c5d84c9cf9c77b1f71ddc6e 100644 (file)
@@ -75,13 +75,9 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
        WRITE_ONCE(*ucall_exit_mmio_addr, uc);
 }
 
-uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
+void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
 {
        struct kvm_run *run = vcpu->run;
-       struct ucall ucall = {};
-
-       if (uc)
-               memset(uc, 0, sizeof(*uc));
 
        if (run->exit_reason == KVM_EXIT_MMIO &&
            run->mmio.phys_addr == (uint64_t)ucall_exit_mmio_addr) {
@@ -90,12 +86,8 @@ uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
                TEST_ASSERT(run->mmio.is_write && run->mmio.len == 8,
                            "Unexpected ucall exit mmio address access");
                memcpy(&gva, run->mmio.data, sizeof(gva));
-               memcpy(&ucall, addr_gva2hva(vcpu->vm, gva), sizeof(ucall));
-
-               vcpu_run_complete_io(vcpu);
-               if (uc)
-                       memcpy(uc, &ucall, sizeof(ucall));
+               return addr_gva2hva(vcpu->vm, gva);
        }
 
-       return ucall.cmd;
+       return NULL;
 }
index b1598f418c1f8e7e4d7f20e819565a0c84a0042f..37e091d4366e55cd845273344946e19140ee5e8e 100644 (file)
@@ -51,27 +51,15 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
                  uc, 0, 0, 0, 0, 0);
 }
 
-uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
+void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
 {
        struct kvm_run *run = vcpu->run;
-       struct ucall ucall = {};
-
-       if (uc)
-               memset(uc, 0, sizeof(*uc));
 
        if (run->exit_reason == KVM_EXIT_RISCV_SBI &&
            run->riscv_sbi.extension_id == KVM_RISCV_SELFTESTS_SBI_EXT) {
                switch (run->riscv_sbi.function_id) {
                case KVM_RISCV_SELFTESTS_SBI_UCALL:
-                       memcpy(&ucall,
-                              addr_gva2hva(vcpu->vm, run->riscv_sbi.args[0]),
-                              sizeof(ucall));
-
-                       vcpu_run_complete_io(vcpu);
-                       if (uc)
-                               memcpy(uc, &ucall, sizeof(ucall));
-
-                       break;
+                       return addr_gva2hva(vcpu->vm, run->riscv_sbi.args[0]);
                case KVM_RISCV_SELFTESTS_SBI_UNEXP:
                        vcpu_dump(stderr, vcpu, 2);
                        TEST_ASSERT(0, "Unexpected trap taken by guest");
@@ -80,6 +68,5 @@ uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
                        break;
                }
        }
-
-       return ucall.cmd;
+       return NULL;
 }
index 114cb4af295f51e5a7a69793a34a21831e7112cc..0f695a031d35d635de238b1d8c06001c66be6d3d 100644 (file)
@@ -20,13 +20,9 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
        asm volatile ("diag 0,%0,0x501" : : "a"(uc) : "memory");
 }
 
-uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
+void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
 {
        struct kvm_run *run = vcpu->run;
-       struct ucall ucall = {};
-
-       if (uc)
-               memset(uc, 0, sizeof(*uc));
 
        if (run->exit_reason == KVM_EXIT_S390_SIEIC &&
            run->s390_sieic.icptcode == 4 &&
@@ -34,13 +30,7 @@ uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
            (run->s390_sieic.ipb >> 16) == 0x501) {
                int reg = run->s390_sieic.ipa & 0xf;
 
-               memcpy(&ucall, addr_gva2hva(vcpu->vm, run->s.regs.gprs[reg]),
-                      sizeof(ucall));
-
-               vcpu_run_complete_io(vcpu);
-               if (uc)
-                       memcpy(uc, &ucall, sizeof(ucall));
+               return addr_gva2hva(vcpu->vm, run->s.regs.gprs[reg]);
        }
-
-       return ucall.cmd;
+       return NULL;
 }
index 2395c7f1d5435a1b2a47de47f07ba94d5bef9e3b..ced48086074631eacb54a8c7f90d94229058054a 100644 (file)
@@ -18,3 +18,22 @@ void ucall(uint64_t cmd, int nargs, ...)
 
        ucall_arch_do_ucall((vm_vaddr_t)&uc);
 }
+
+uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
+{
+       struct ucall ucall;
+       void *addr;
+
+       if (!uc)
+               uc = &ucall;
+
+       addr = ucall_arch_get_ucall(vcpu);
+       if (addr) {
+               memcpy(uc, addr, sizeof(*uc));
+               vcpu_run_complete_io(vcpu);
+       } else {
+               memset(uc, 0, sizeof(*uc));
+       }
+
+       return uc->cmd;
+}
index 9f532dba1003505ce7f239f6f46106420c8c34e7..ead9946399abf09d4327c9141cd7e1cb8ab4991d 100644 (file)
@@ -22,25 +22,15 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
                : : [port] "d" (UCALL_PIO_PORT), "D" (uc) : "rax", "memory");
 }
 
-uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
+void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
 {
        struct kvm_run *run = vcpu->run;
-       struct ucall ucall = {};
-
-       if (uc)
-               memset(uc, 0, sizeof(*uc));
 
        if (run->exit_reason == KVM_EXIT_IO && run->io.port == UCALL_PIO_PORT) {
                struct kvm_regs regs;
 
                vcpu_regs_get(vcpu, &regs);
-               memcpy(&ucall, addr_gva2hva(vcpu->vm, (vm_vaddr_t)regs.rdi),
-                      sizeof(ucall));
-
-               vcpu_run_complete_io(vcpu);
-               if (uc)
-                       memcpy(uc, &ucall, sizeof(ucall));
+               return addr_gva2hva(vcpu->vm, regs.rdi);
        }
-
-       return ucall.cmd;
+       return NULL;
 }