From nobody Wed Apr 8 11:43:13 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EBABC4332F for ; Thu, 6 Oct 2022 00:34:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229891AbiJFAe0 (ORCPT ); Wed, 5 Oct 2022 20:34:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58078 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229794AbiJFAeR (ORCPT ); Wed, 5 Oct 2022 20:34:17 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 474F286885 for ; Wed, 5 Oct 2022 17:34:16 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id b11-20020a630c0b000000b0044c0bb18323so173071pgl.17 for ; Wed, 05 Oct 2022 17:34:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=LxD1Ig1Wg9dHPvXi6MK9jGxHhkv2R7KkJnjSBckG4C0=; b=AfxO+Er11HVjf/Y10wy9fBxzGZO94qsVOxlhlno9xnC17t63/Tr5Dqcdnn4SgvpLuG CuJqkVZk7Y2Nwx9waPSTB561h6UAaO2K4RQzHy7Az1TPcPTtq5pSQPvcBWN5gOouyY6k 4I34xu/irDrmfqkx36b3NkVK+rVKDB9KBL6LdG2tndjidRcrR2pOzpqph0jvh77XbKZk /Z1zGmieRScTq3oOEkySFyVpZBUxPcZe/VYPQHuO564VtXObBd5GQI4VfhzXYVlpiDRA uI+V38I7ZlQhWma4UcdPLaxXvmHzH0m5NoByfdMlosXVrL4xaFqrN8UyGXf4L7ywFi6w mKzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=LxD1Ig1Wg9dHPvXi6MK9jGxHhkv2R7KkJnjSBckG4C0=; b=gYM41gP9iHpxQl11+ehutjTIp1o6rJqM/q5kifcdtHjxru4OQYTnIxoB5foC5QEcjx 2CcYb+ZET1YsvVAjzXOkr4o5P8O/+OPrgVlCysrlk+/qo6/Jbx+d1y+U8oAWM7Olb2Vw 1MSCLe+nwJMRJOGky+yp/tfcese4f37uFlt+0E7L+I0diZHGoc0E05nTyaKaaspPLD5n WWHu67N6/Si3DIaTO3s2xUcVK3FE8aJk6pZWCEYgW55sgzn5goHjEsKgrXyk3sZaqsww r/DLGtA/6B3kaYSQizNPJlNdRYbpCTYDDga3ubI6iebbSpcM0PIb9d2NgAvx2codi5oY gIZw== X-Gm-Message-State: ACrzQf1sYqlP5q+/hq7NZO+LL9h4Lfsykuq56GF91vGXBYDOi1LpBe8B sMRKUjeYC+WrPO0CbUNEJHxltYxoHW8= X-Google-Smtp-Source: AMsMyM7eCt0EkeFVVtjGTO8xDyWvbelrIj+5gtw3GtcA4yoUoAjJIz+e6CsiiencYUd1amboMYPXXKjRKWw= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a05:6a00:190d:b0:550:6db3:b9be with SMTP id y13-20020a056a00190d00b005506db3b9bemr2333440pfi.1.1665016455813; Wed, 05 Oct 2022 17:34:15 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 6 Oct 2022 00:34:03 +0000 In-Reply-To: <20221006003409.649993-1-seanjc@google.com> Mime-Version: 1.0 References: <20221006003409.649993-1-seanjc@google.com> X-Mailer: git-send-email 2.38.0.rc1.362.ged0d419d3c-goog Message-ID: <20221006003409.649993-2-seanjc@google.com> Subject: [PATCH v6 1/7] KVM: selftests: Consolidate common code for populating ucall struct From: Sean Christopherson To: Paolo Bonzini , Shuah Khan , Marc Zyngier , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Nathan Chancellor , Nick Desaulniers Cc: James Morse , Alexandru Elisei , Suzuki K Poulose , Oliver Upton , Atish Patra , David Hildenbrand , Tom Rix , linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvmarm@lists.cs.columbia.edu, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, llvm@lists.linux.dev, Colton Lewis , Andrew Jones , Peter Gonda , Sean Christopherson Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 (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 Reviewed-by: Andrew Jones Tested-by: Peter Gonda Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/include/ucall_common.h | 23 ++++++++++++++++--- .../testing/selftests/kvm/lib/aarch64/ucall.c | 22 ++++-------------- 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, 61 insertions(+), 74 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 0172eb6cb6ee..65eb45ff1bff 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -47,6 +47,7 @@ LIBKVM +=3D lib/perf_test_util.c LIBKVM +=3D lib/rbtree.c LIBKVM +=3D lib/sparsebit.c LIBKVM +=3D lib/test_util.c +LIBKVM +=3D lib/ucall_common.c =20 LIBKVM_STRING +=3D lib/string_override.c =20 diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/tes= ting/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]; }; =20 -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); +} =20 #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/testin= g/selftests/kvm/lib/aarch64/ucall.c index ed237b744690..3630708c32d6 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; } =20 -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"); } =20 -void ucall_uninit(struct kvm_vm *vm) +void ucall_arch_uninit(struct kvm_vm *vm) { ucall_exit_mmio_addr =3D 0; sync_global_to_guest(vm, ucall_exit_mmio_addr); } =20 -void ucall(uint64_t cmd, int nargs, ...) +void ucall_arch_do_ucall(vm_vaddr_t uc) { - struct ucall uc =3D {}; - va_list va; - int i; - - WRITE_ONCE(uc.cmd, cmd); - nargs =3D min(nargs, UCALL_MAX_ARGS); - - va_start(va, nargs); - for (i =3D 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); + WRITE_ONCE(*ucall_exit_mmio_addr, uc); } =20 -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 =3D vcpu->run; struct ucall ucall =3D {}; 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" =20 -void ucall_init(struct kvm_vm *vm, void *arg) +void ucall_arch_init(struct kvm_vm *vm, void *arg) { } =20 -void ucall_uninit(struct kvm_vm *vm) +void ucall_arch_uninit(struct kvm_vm *vm) { } =20 @@ -44,27 +44,14 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long= arg0, return ret; } =20 -void ucall(uint64_t cmd, int nargs, ...) +void ucall_arch_do_ucall(vm_vaddr_t uc) { - struct ucall uc =3D { - .cmd =3D cmd, - }; - va_list va; - int i; - - nargs =3D min(nargs, UCALL_MAX_ARGS); - - va_start(va, nargs); - for (i =3D 0; i < nargs; ++i) - uc.args[i] =3D 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); } =20 -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 =3D vcpu->run; struct ucall ucall =3D {}; 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" =20 -void ucall_init(struct kvm_vm *vm, void *arg) +void ucall_arch_init(struct kvm_vm *vm, void *arg) { } =20 -void ucall_uninit(struct kvm_vm *vm) +void ucall_arch_uninit(struct kvm_vm *vm) { } =20 -void ucall(uint64_t cmd, int nargs, ...) +void ucall_arch_do_ucall(vm_vaddr_t uc) { - struct ucall uc =3D { - .cmd =3D cmd, - }; - va_list va; - int i; - - nargs =3D min(nargs, UCALL_MAX_ARGS); - - va_start(va, nargs); - for (i =3D 0; i < nargs; ++i) - uc.args[i] =3D 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"); } =20 -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 =3D vcpu->run; struct ucall ucall =3D {}; 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 =3D {}; + va_list va; + int i; + + WRITE_ONCE(uc.cmd, cmd); + + nargs =3D min(nargs, UCALL_MAX_ARGS); + + va_start(va, nargs); + for (i =3D 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 @@ =20 #define UCALL_PIO_PORT ((uint16_t)0x1000) =20 -void ucall_init(struct kvm_vm *vm, void *arg) +void ucall_arch_init(struct kvm_vm *vm, void *arg) { } =20 -void ucall_uninit(struct kvm_vm *vm) +void ucall_arch_uninit(struct kvm_vm *vm) { } =20 -void ucall(uint64_t cmd, int nargs, ...) +void ucall_arch_do_ucall(vm_vaddr_t uc) { - struct ucall uc =3D { - .cmd =3D cmd, - }; - va_list va; - int i; - - nargs =3D min(nargs, UCALL_MAX_ARGS); - - va_start(va, nargs); - for (i =3D 0; i < nargs; ++i) - uc.args[i] =3D 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"); } =20 -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 =3D vcpu->run; struct ucall ucall =3D {}; --=20 2.38.0.rc1.362.ged0d419d3c-goog