From: Huang, Shaoqin <shaoqin.huang@intel.com>
To: kvm-riscv@lists.infradead.org
Subject: [PATCH 2/3] KVM: selftests: Consolidate boilerplate code in get_ucall()
Date: Sun, 19 Jun 2022 18:36:10 +0800 [thread overview]
Message-ID: <de35d629-e076-e02d-7482-c93de628dd82@intel.com> (raw)
In-Reply-To: <20220618001618.1840806-3-seanjc@google.com>
On 6/18/2022 8:16 AM, Sean Christopherson wrote:
> 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).
It seems the get_ucall() returns the uc->cmd, the ucall_arch_get_ucall()
returns a host virtual address.
>
> Use pointer shenanigans instead of an unnecessary bounce buffer when the
> caller of get_ucall() provides a valid pointer.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> .../selftests/kvm/include/ucall_common.h | 8 ++------
> .../testing/selftests/kvm/lib/aarch64/ucall.c | 15 +++------------
> tools/testing/selftests/kvm/lib/riscv/ucall.c | 19 +++----------------
> tools/testing/selftests/kvm/lib/s390x/ucall.c | 16 +++-------------
> .../testing/selftests/kvm/lib/ucall_common.c | 19 +++++++++++++++++++
> .../testing/selftests/kvm/lib/x86_64/ucall.c | 16 +++-------------
> 6 files changed, 33 insertions(+), 60 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
> index c6a4fd7fe443..cb9b37282701 100644
> --- a/tools/testing/selftests/kvm/include/ucall_common.h
> +++ b/tools/testing/selftests/kvm/include/ucall_common.h
> @@ -26,9 +26,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)
> {
> @@ -40,11 +41,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)
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> index 2de9fdd34159..9c124adbb560 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> @@ -75,13 +75,9 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
> *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,7 @@ 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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/riscv/ucall.c b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> index b1598f418c1f..37e091d4366e 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> index 114cb4af295f..0f695a031d35 100644
> --- a/tools/testing/selftests/kvm/lib/s390x/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
> index 749ffdf23855..c488ed23d0dd 100644
> --- a/tools/testing/selftests/kvm/lib/ucall_common.c
> +++ b/tools/testing/selftests/kvm/lib/ucall_common.c
> @@ -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;
> +}
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> index 9f532dba1003..ec53a406f689 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> @@ -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, ®s);
> - 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, (vm_vaddr_t)regs.rdi);
> }
> -
> - return ucall.cmd;
> + return NULL;
> }
WARNING: multiple messages have this Message-ID (diff)
From: "Huang, Shaoqin" <shaoqin.huang@intel.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Marc Zyngier <maz@kernel.org>, Anup Patel <anup@brainfault.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
Janosch Frank <frankja@linux.ibm.com>,
Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: kvm@vger.kernel.org, David Hildenbrand <david@redhat.com>,
linux-kernel@vger.kernel.org,
Colton Lewis <coltonlewis@google.com>,
kvm-riscv@lists.infradead.org,
Atish Patra <atishp@atishpatra.org>,
linux-riscv@lists.infradead.org, kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 2/3] KVM: selftests: Consolidate boilerplate code in get_ucall()
Date: Sun, 19 Jun 2022 18:36:10 +0800 [thread overview]
Message-ID: <de35d629-e076-e02d-7482-c93de628dd82@intel.com> (raw)
In-Reply-To: <20220618001618.1840806-3-seanjc@google.com>
On 6/18/2022 8:16 AM, Sean Christopherson wrote:
> 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).
It seems the get_ucall() returns the uc->cmd, the ucall_arch_get_ucall()
returns a host virtual address.
>
> Use pointer shenanigans instead of an unnecessary bounce buffer when the
> caller of get_ucall() provides a valid pointer.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> .../selftests/kvm/include/ucall_common.h | 8 ++------
> .../testing/selftests/kvm/lib/aarch64/ucall.c | 15 +++------------
> tools/testing/selftests/kvm/lib/riscv/ucall.c | 19 +++----------------
> tools/testing/selftests/kvm/lib/s390x/ucall.c | 16 +++-------------
> .../testing/selftests/kvm/lib/ucall_common.c | 19 +++++++++++++++++++
> .../testing/selftests/kvm/lib/x86_64/ucall.c | 16 +++-------------
> 6 files changed, 33 insertions(+), 60 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
> index c6a4fd7fe443..cb9b37282701 100644
> --- a/tools/testing/selftests/kvm/include/ucall_common.h
> +++ b/tools/testing/selftests/kvm/include/ucall_common.h
> @@ -26,9 +26,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)
> {
> @@ -40,11 +41,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)
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> index 2de9fdd34159..9c124adbb560 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> @@ -75,13 +75,9 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
> *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,7 @@ 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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/riscv/ucall.c b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> index b1598f418c1f..37e091d4366e 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> index 114cb4af295f..0f695a031d35 100644
> --- a/tools/testing/selftests/kvm/lib/s390x/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
> index 749ffdf23855..c488ed23d0dd 100644
> --- a/tools/testing/selftests/kvm/lib/ucall_common.c
> +++ b/tools/testing/selftests/kvm/lib/ucall_common.c
> @@ -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;
> +}
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> index 9f532dba1003..ec53a406f689 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> @@ -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, ®s);
> - 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, (vm_vaddr_t)regs.rdi);
> }
> -
> - return ucall.cmd;
> + return NULL;
> }
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
WARNING: multiple messages have this Message-ID (diff)
From: "Huang, Shaoqin" <shaoqin.huang@intel.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Marc Zyngier <maz@kernel.org>, Anup Patel <anup@brainfault.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
Janosch Frank <frankja@linux.ibm.com>,
Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: James Morse <james.morse@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
"Atish Patra" <atishp@atishpatra.org>,
David Hildenbrand <david@redhat.com>, <kvm@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<kvmarm@lists.cs.columbia.edu>, <kvm-riscv@lists.infradead.org>,
<linux-riscv@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
"Colton Lewis" <coltonlewis@google.com>,
Andrew Jones <drjones@redhat.com>
Subject: Re: [PATCH 2/3] KVM: selftests: Consolidate boilerplate code in get_ucall()
Date: Sun, 19 Jun 2022 18:36:10 +0800 [thread overview]
Message-ID: <de35d629-e076-e02d-7482-c93de628dd82@intel.com> (raw)
In-Reply-To: <20220618001618.1840806-3-seanjc@google.com>
On 6/18/2022 8:16 AM, Sean Christopherson wrote:
> 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).
It seems the get_ucall() returns the uc->cmd, the ucall_arch_get_ucall()
returns a host virtual address.
>
> Use pointer shenanigans instead of an unnecessary bounce buffer when the
> caller of get_ucall() provides a valid pointer.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> .../selftests/kvm/include/ucall_common.h | 8 ++------
> .../testing/selftests/kvm/lib/aarch64/ucall.c | 15 +++------------
> tools/testing/selftests/kvm/lib/riscv/ucall.c | 19 +++----------------
> tools/testing/selftests/kvm/lib/s390x/ucall.c | 16 +++-------------
> .../testing/selftests/kvm/lib/ucall_common.c | 19 +++++++++++++++++++
> .../testing/selftests/kvm/lib/x86_64/ucall.c | 16 +++-------------
> 6 files changed, 33 insertions(+), 60 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
> index c6a4fd7fe443..cb9b37282701 100644
> --- a/tools/testing/selftests/kvm/include/ucall_common.h
> +++ b/tools/testing/selftests/kvm/include/ucall_common.h
> @@ -26,9 +26,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)
> {
> @@ -40,11 +41,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)
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> index 2de9fdd34159..9c124adbb560 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> @@ -75,13 +75,9 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
> *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,7 @@ 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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/riscv/ucall.c b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> index b1598f418c1f..37e091d4366e 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> index 114cb4af295f..0f695a031d35 100644
> --- a/tools/testing/selftests/kvm/lib/s390x/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
> index 749ffdf23855..c488ed23d0dd 100644
> --- a/tools/testing/selftests/kvm/lib/ucall_common.c
> +++ b/tools/testing/selftests/kvm/lib/ucall_common.c
> @@ -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;
> +}
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> index 9f532dba1003..ec53a406f689 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> @@ -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, ®s);
> - 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, (vm_vaddr_t)regs.rdi);
> }
> -
> - return ucall.cmd;
> + return NULL;
> }
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: "Huang, Shaoqin" <shaoqin.huang@intel.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Marc Zyngier <maz@kernel.org>, Anup Patel <anup@brainfault.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
Janosch Frank <frankja@linux.ibm.com>,
Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: James Morse <james.morse@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
"Atish Patra" <atishp@atishpatra.org>,
David Hildenbrand <david@redhat.com>, <kvm@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<kvmarm@lists.cs.columbia.edu>, <kvm-riscv@lists.infradead.org>,
<linux-riscv@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
"Colton Lewis" <coltonlewis@google.com>,
Andrew Jones <drjones@redhat.com>
Subject: Re: [PATCH 2/3] KVM: selftests: Consolidate boilerplate code in get_ucall()
Date: Sun, 19 Jun 2022 18:36:10 +0800 [thread overview]
Message-ID: <de35d629-e076-e02d-7482-c93de628dd82@intel.com> (raw)
In-Reply-To: <20220618001618.1840806-3-seanjc@google.com>
On 6/18/2022 8:16 AM, Sean Christopherson wrote:
> 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).
It seems the get_ucall() returns the uc->cmd, the ucall_arch_get_ucall()
returns a host virtual address.
>
> Use pointer shenanigans instead of an unnecessary bounce buffer when the
> caller of get_ucall() provides a valid pointer.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> .../selftests/kvm/include/ucall_common.h | 8 ++------
> .../testing/selftests/kvm/lib/aarch64/ucall.c | 15 +++------------
> tools/testing/selftests/kvm/lib/riscv/ucall.c | 19 +++----------------
> tools/testing/selftests/kvm/lib/s390x/ucall.c | 16 +++-------------
> .../testing/selftests/kvm/lib/ucall_common.c | 19 +++++++++++++++++++
> .../testing/selftests/kvm/lib/x86_64/ucall.c | 16 +++-------------
> 6 files changed, 33 insertions(+), 60 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
> index c6a4fd7fe443..cb9b37282701 100644
> --- a/tools/testing/selftests/kvm/include/ucall_common.h
> +++ b/tools/testing/selftests/kvm/include/ucall_common.h
> @@ -26,9 +26,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)
> {
> @@ -40,11 +41,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)
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> index 2de9fdd34159..9c124adbb560 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> @@ -75,13 +75,9 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
> *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,7 @@ 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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/riscv/ucall.c b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> index b1598f418c1f..37e091d4366e 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> index 114cb4af295f..0f695a031d35 100644
> --- a/tools/testing/selftests/kvm/lib/s390x/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
> index 749ffdf23855..c488ed23d0dd 100644
> --- a/tools/testing/selftests/kvm/lib/ucall_common.c
> +++ b/tools/testing/selftests/kvm/lib/ucall_common.c
> @@ -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;
> +}
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> index 9f532dba1003..ec53a406f689 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> @@ -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, ®s);
> - 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, (vm_vaddr_t)regs.rdi);
> }
> -
> - return ucall.cmd;
> + return NULL;
> }
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: "Huang, Shaoqin" <shaoqin.huang@intel.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Marc Zyngier <maz@kernel.org>, Anup Patel <anup@brainfault.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
Janosch Frank <frankja@linux.ibm.com>,
Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: James Morse <james.morse@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
"Atish Patra" <atishp@atishpatra.org>,
David Hildenbrand <david@redhat.com>, <kvm@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<kvmarm@lists.cs.columbia.edu>, <kvm-riscv@lists.infradead.org>,
<linux-riscv@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
"Colton Lewis" <coltonlewis@google.com>,
Andrew Jones <drjones@redhat.com>
Subject: Re: [PATCH 2/3] KVM: selftests: Consolidate boilerplate code in get_ucall()
Date: Sun, 19 Jun 2022 18:36:10 +0800 [thread overview]
Message-ID: <de35d629-e076-e02d-7482-c93de628dd82@intel.com> (raw)
In-Reply-To: <20220618001618.1840806-3-seanjc@google.com>
On 6/18/2022 8:16 AM, Sean Christopherson wrote:
> 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).
It seems the get_ucall() returns the uc->cmd, the ucall_arch_get_ucall()
returns a host virtual address.
>
> Use pointer shenanigans instead of an unnecessary bounce buffer when the
> caller of get_ucall() provides a valid pointer.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> .../selftests/kvm/include/ucall_common.h | 8 ++------
> .../testing/selftests/kvm/lib/aarch64/ucall.c | 15 +++------------
> tools/testing/selftests/kvm/lib/riscv/ucall.c | 19 +++----------------
> tools/testing/selftests/kvm/lib/s390x/ucall.c | 16 +++-------------
> .../testing/selftests/kvm/lib/ucall_common.c | 19 +++++++++++++++++++
> .../testing/selftests/kvm/lib/x86_64/ucall.c | 16 +++-------------
> 6 files changed, 33 insertions(+), 60 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
> index c6a4fd7fe443..cb9b37282701 100644
> --- a/tools/testing/selftests/kvm/include/ucall_common.h
> +++ b/tools/testing/selftests/kvm/include/ucall_common.h
> @@ -26,9 +26,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)
> {
> @@ -40,11 +41,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)
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> index 2de9fdd34159..9c124adbb560 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/ucall.c
> @@ -75,13 +75,9 @@ void ucall_arch_do_ucall(vm_vaddr_t uc)
> *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,7 @@ 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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/riscv/ucall.c b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> index b1598f418c1f..37e091d4366e 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> index 114cb4af295f..0f695a031d35 100644
> --- a/tools/testing/selftests/kvm/lib/s390x/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/s390x/ucall.c
> @@ -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;
> }
> diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
> index 749ffdf23855..c488ed23d0dd 100644
> --- a/tools/testing/selftests/kvm/lib/ucall_common.c
> +++ b/tools/testing/selftests/kvm/lib/ucall_common.c
> @@ -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;
> +}
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> index 9f532dba1003..ec53a406f689 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c
> @@ -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, ®s);
> - 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, (vm_vaddr_t)regs.rdi);
> }
> -
> - return ucall.cmd;
> + return NULL;
> }
next prev parent reply other threads:[~2022-06-19 10:36 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-18 0:16 [PATCH 0/3] KVM: selftests: Consolidate ucall code Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` [PATCH 1/3] KVM: selftests: Consolidate common code for popuplating ucall struct Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-20 7:39 ` Christian Borntraeger
2022-06-20 7:39 ` Christian Borntraeger
2022-06-20 7:39 ` Christian Borntraeger
2022-06-20 7:39 ` Christian Borntraeger
2022-06-20 7:39 ` Christian Borntraeger
2022-06-18 0:16 ` [PATCH 2/3] KVM: selftests: Consolidate boilerplate code in get_ucall() Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-19 10:36 ` Huang, Shaoqin [this message]
2022-06-19 10:36 ` Huang, Shaoqin
2022-06-19 10:36 ` Huang, Shaoqin
2022-06-19 10:36 ` Huang, Shaoqin
2022-06-19 10:36 ` Huang, Shaoqin
2022-06-21 14:41 ` Sean Christopherson
2022-06-21 14:41 ` Sean Christopherson
2022-06-21 14:41 ` Sean Christopherson
2022-06-21 14:41 ` Sean Christopherson
2022-06-21 14:41 ` Sean Christopherson
2022-06-18 0:16 ` [PATCH 3/3] KVM: selftest: Add __weak stubs for ucall_arch_(un)init() Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-18 0:16 ` Sean Christopherson
2022-06-20 7:33 ` [PATCH 0/3] KVM: selftests: Consolidate ucall code Andrew Jones
2022-06-20 7:33 ` Andrew Jones
2022-06-20 7:33 ` Andrew Jones
2022-06-20 7:33 ` Andrew Jones
2022-06-20 7:33 ` Andrew Jones
2022-06-20 12:03 ` Paolo Bonzini
2022-06-20 12:03 ` Paolo Bonzini
2022-06-20 12:03 ` Paolo Bonzini
2022-06-20 12:03 ` Paolo Bonzini
2022-06-20 12:03 ` Paolo Bonzini
2022-06-21 14:54 ` Sean Christopherson
2022-06-21 14:54 ` Sean Christopherson
2022-06-21 14:54 ` Sean Christopherson
2022-06-21 14:54 ` Sean Christopherson
2022-06-21 14:54 ` Sean Christopherson
2022-07-15 19:32 ` Peter Gonda
2022-07-15 19:32 ` Peter Gonda
2022-07-15 19:32 ` Peter Gonda
2022-07-15 19:32 ` Peter Gonda
2022-07-15 19:32 ` Peter Gonda
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=de35d629-e076-e02d-7482-c93de628dd82@intel.com \
--to=shaoqin.huang@intel.com \
--cc=kvm-riscv@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.