lkml.org 
[lkml]   [2022]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [V3 06/11] KVM: selftests: Consolidate common code for popuplating
    On Wed, Aug 10, 2022 at 08:20:28AM -0700, Peter Gonda wrote:
    > From: Sean Christopherson <seanjc@google.com>
    >
    > Make ucall() a common helper that populates struct ucall, and only calls
    > into arch code to make the actually call out to userspace.
    >
    > Rename all arch-specific helpers to make it clear they're arch-specific,
    > and to avoid collisions with common helpers (one more on its way...)
    >
    > Add WRITE_ONCE() to stores in ucall() code to as already done to aarch64
    > code in commit 9e2f6498efbb ("selftests: KVM: Handle compiler
    > optimizations in ucall") to prevent clang optimizations breaking ucalls.
    >
    > Cc: Colton Lewis <coltonlewis@google.com>
    > Cc: Andrew Jones <drjones@redhat.com>
    > Signed-off-by: Sean Christopherson <seanjc@google.com>
    > Signed-off-by: Peter Gonda <pgonda@google.com>
    > ---
    > tools/testing/selftests/kvm/Makefile | 1 +
    > .../selftests/kvm/include/ucall_common.h | 23 ++++++++++++++++---
    > .../testing/selftests/kvm/lib/aarch64/ucall.c | 20 ++++------------
    > tools/testing/selftests/kvm/lib/riscv/ucall.c | 23 ++++---------------
    > tools/testing/selftests/kvm/lib/s390x/ucall.c | 23 ++++---------------
    > .../testing/selftests/kvm/lib/ucall_common.c | 20 ++++++++++++++++
    > .../testing/selftests/kvm/lib/x86_64/ucall.c | 23 ++++---------------
    > 7 files changed, 60 insertions(+), 73 deletions(-)
    > create mode 100644 tools/testing/selftests/kvm/lib/ucall_common.c
    >
    > diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
    > index 690b499c3471..39fc5e8e5594 100644
    > --- a/tools/testing/selftests/kvm/Makefile
    > +++ b/tools/testing/selftests/kvm/Makefile
    > @@ -46,6 +46,7 @@ LIBKVM += lib/perf_test_util.c
    > LIBKVM += lib/rbtree.c
    > LIBKVM += lib/sparsebit.c
    > LIBKVM += lib/test_util.c
    > +LIBKVM += lib/ucall_common.c
    >
    > LIBKVM_x86_64 += lib/x86_64/apic.c
    > LIBKVM_x86_64 += lib/x86_64/handlers.S
    > diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
    > index ee79d180e07e..5a85f5318bbe 100644
    > --- a/tools/testing/selftests/kvm/include/ucall_common.h
    > +++ b/tools/testing/selftests/kvm/include/ucall_common.h
    > @@ -24,10 +24,27 @@ struct ucall {
    > uint64_t args[UCALL_MAX_ARGS];
    > };
    >
    > -void ucall_init(struct kvm_vm *vm, void *arg);
    > -void ucall_uninit(struct kvm_vm *vm);
    > +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(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)
    > +{
    > + ucall_arch_init(vm, arg);
    > +}
    > +
    > +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)
    > diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
    > index ed237b744690..1c81a6a5c1f2 100644
    > --- a/tools/testing/selftests/kvm/lib/aarch64/ucall.c
    > +++ b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
    > @@ -21,7 +21,7 @@ static bool ucall_mmio_init(struct kvm_vm *vm, vm_paddr_t gpa)
    > return true;
    > }
    >
    > -void ucall_init(struct kvm_vm *vm, void *arg)
    > +void ucall_arch_init(struct kvm_vm *vm, void *arg)
    > {
    > vm_paddr_t gpa, start, end, step, offset;
    > unsigned int bits;
    > @@ -64,30 +64,18 @@ void ucall_init(struct kvm_vm *vm, void *arg)
    > TEST_FAIL("Can't find a ucall mmio address");
    > }
    >
    > -void ucall_uninit(struct kvm_vm *vm)
    > +void ucall_arch_uninit(struct kvm_vm *vm)
    > {
    > ucall_exit_mmio_addr = 0;
    > sync_global_to_guest(vm, ucall_exit_mmio_addr);
    > }
    >
    > -void ucall(uint64_t cmd, int nargs, ...)
    > +void ucall_arch_do_ucall(vm_vaddr_t uc)
    > {
    > - struct ucall uc = {};
    > - va_list va;
    > - int i;
    > -
    > - WRITE_ONCE(uc.cmd, cmd);
    > - nargs = min(nargs, UCALL_MAX_ARGS);
    > -
    > - va_start(va, nargs);
    > - for (i = 0; i < nargs; ++i)
    > - WRITE_ONCE(uc.args[i], va_arg(va, uint64_t));
    > - va_end(va);
    > -
    > WRITE_ONCE(*ucall_exit_mmio_addr, (vm_vaddr_t)&uc);
    ^ should just be uc

    > }
    >
    > -uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > +uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > {
    > struct kvm_run *run = vcpu->run;
    > struct ucall ucall = {};
    > diff --git a/tools/testing/selftests/kvm/lib/riscv/ucall.c b/tools/testing/selftests/kvm/lib/riscv/ucall.c
    > index 087b9740bc8f..b1598f418c1f 100644
    > --- a/tools/testing/selftests/kvm/lib/riscv/ucall.c
    > +++ b/tools/testing/selftests/kvm/lib/riscv/ucall.c
    > @@ -10,11 +10,11 @@
    > #include "kvm_util.h"
    > #include "processor.h"
    >
    > -void ucall_init(struct kvm_vm *vm, void *arg)
    > +void ucall_arch_init(struct kvm_vm *vm, void *arg)
    > {
    > }
    >
    > -void ucall_uninit(struct kvm_vm *vm)
    > +void ucall_arch_uninit(struct kvm_vm *vm)
    > {
    > }
    >
    > @@ -44,27 +44,14 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
    > return ret;
    > }
    >
    > -void ucall(uint64_t cmd, int nargs, ...)
    > +void ucall_arch_do_ucall(vm_vaddr_t uc)
    > {
    > - struct ucall uc = {
    > - .cmd = cmd,
    > - };
    > - va_list va;
    > - int i;
    > -
    > - nargs = min(nargs, UCALL_MAX_ARGS);
    > -
    > - va_start(va, nargs);
    > - for (i = 0; i < nargs; ++i)
    > - uc.args[i] = va_arg(va, uint64_t);
    > - va_end(va);
    > -
    > sbi_ecall(KVM_RISCV_SELFTESTS_SBI_EXT,
    > KVM_RISCV_SELFTESTS_SBI_UCALL,
    > - (vm_vaddr_t)&uc, 0, 0, 0, 0, 0);
    > + uc, 0, 0, 0, 0, 0);
    > }
    >
    > -uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > +uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > {
    > struct kvm_run *run = vcpu->run;
    > struct ucall ucall = {};
    > diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390x/ucall.c
    > index 73dc4e21190f..114cb4af295f 100644
    > --- a/tools/testing/selftests/kvm/lib/s390x/ucall.c
    > +++ b/tools/testing/selftests/kvm/lib/s390x/ucall.c
    > @@ -6,34 +6,21 @@
    > */
    > #include "kvm_util.h"
    >
    > -void ucall_init(struct kvm_vm *vm, void *arg)
    > +void ucall_arch_init(struct kvm_vm *vm, void *arg)
    > {
    > }
    >
    > -void ucall_uninit(struct kvm_vm *vm)
    > +void ucall_arch_uninit(struct kvm_vm *vm)
    > {
    > }
    >
    > -void ucall(uint64_t cmd, int nargs, ...)
    > +void ucall_arch_do_ucall(vm_vaddr_t uc)
    > {
    > - struct ucall uc = {
    > - .cmd = cmd,
    > - };
    > - va_list va;
    > - int i;
    > -
    > - nargs = min(nargs, UCALL_MAX_ARGS);
    > -
    > - va_start(va, nargs);
    > - for (i = 0; i < nargs; ++i)
    > - uc.args[i] = va_arg(va, uint64_t);
    > - va_end(va);
    > -
    > /* Exit via DIAGNOSE 0x501 (normally used for breakpoints) */
    > - asm volatile ("diag 0,%0,0x501" : : "a"(&uc) : "memory");
    > + asm volatile ("diag 0,%0,0x501" : : "a"(uc) : "memory");
    > }
    >
    > -uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > +uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > {
    > struct kvm_run *run = vcpu->run;
    > struct ucall ucall = {};
    > diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
    > new file mode 100644
    > index 000000000000..2395c7f1d543
    > --- /dev/null
    > +++ b/tools/testing/selftests/kvm/lib/ucall_common.c
    > @@ -0,0 +1,20 @@
    > +// SPDX-License-Identifier: GPL-2.0-only
    > +#include "kvm_util.h"
    > +
    > +void ucall(uint64_t cmd, int nargs, ...)
    > +{
    > + struct ucall uc = {};
    > + va_list va;
    > + int i;
    > +
    > + WRITE_ONCE(uc.cmd, cmd);
    > +
    > + nargs = min(nargs, UCALL_MAX_ARGS);
    > +
    > + va_start(va, nargs);
    > + for (i = 0; i < nargs; ++i)
    > + WRITE_ONCE(uc.args[i], va_arg(va, uint64_t));
    > + va_end(va);
    > +
    > + ucall_arch_do_ucall((vm_vaddr_t)&uc);
    > +}
    > diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
    > index e5f0f9e0d3ee..9f532dba1003 100644
    > --- a/tools/testing/selftests/kvm/lib/x86_64/ucall.c
    > +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
    > @@ -8,34 +8,21 @@
    >
    > #define UCALL_PIO_PORT ((uint16_t)0x1000)
    >
    > -void ucall_init(struct kvm_vm *vm, void *arg)
    > +void ucall_arch_init(struct kvm_vm *vm, void *arg)
    > {
    > }
    >
    > -void ucall_uninit(struct kvm_vm *vm)
    > +void ucall_arch_uninit(struct kvm_vm *vm)
    > {
    > }
    >
    > -void ucall(uint64_t cmd, int nargs, ...)
    > +void ucall_arch_do_ucall(vm_vaddr_t uc)
    > {
    > - struct ucall uc = {
    > - .cmd = cmd,
    > - };
    > - va_list va;
    > - int i;
    > -
    > - nargs = min(nargs, UCALL_MAX_ARGS);
    > -
    > - va_start(va, nargs);
    > - for (i = 0; i < nargs; ++i)
    > - uc.args[i] = va_arg(va, uint64_t);
    > - va_end(va);
    > -
    > asm volatile("in %[port], %%al"
    > - : : [port] "d" (UCALL_PIO_PORT), "D" (&uc) : "rax", "memory");
    > + : : [port] "d" (UCALL_PIO_PORT), "D" (uc) : "rax", "memory");
    > }
    >
    > -uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > +uint64_t ucall_arch_get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
    > {
    > struct kvm_run *run = vcpu->run;
    > struct ucall ucall = {};
    > --
    > 2.37.1.559.g78731f0fdb-goog
    >

    Otherwise,

    Reviewed-by: Andrew Jones <andrew.jones@linux.dev>

    \
     
     \ /
      Last update: 2022-08-16 17:27    [W:4.296 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site