From: Andrew Jones <ajones@ventanamicro.com>
To: "Radim Krčmář" <rkrcmar@ventanamicro.com>
Cc: kvm-riscv@lists.infradead.org, kvm@vger.kernel.org,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
Anup Patel <anup@brainfault.org>,
Atish Patra <atishp@atishpatra.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>,
Mayuresh Chitale <mchitale@ventanamicro.com>
Subject: Re: [PATCH 4/5] KVM: RISC-V: reset VCPU state when becoming runnable
Date: Fri, 25 Apr 2025 15:26:08 +0200 [thread overview]
Message-ID: <20250425-2bc11e21ecef7269702c424e@orel> (raw)
In-Reply-To: <20250403112522.1566629-7-rkrcmar@ventanamicro.com>
On Thu, Apr 03, 2025 at 01:25:23PM +0200, Radim Krčmář wrote:
> Beware, this patch is "breaking" the userspace interface, because it
> fixes a KVM/QEMU bug where the boot VCPU is not being reset by KVM.
>
> The VCPU reset paths are inconsistent right now. KVM resets VCPUs that
> are brought up by KVM-accelerated SBI calls, but does nothing for VCPUs
> brought up through ioctls.
I guess we currently expect userspace to make a series of set-one-reg
ioctls in order to prepare ("reset") newly created vcpus, and I guess
the problem is that KVM isn't capturing the resulting configuration
in order to replay it when SBI HSM reset is invoked by the guest. But,
instead of capture-replay we could just exit to userspace on an SBI
HSM reset call and let userspace repeat what it did at vcpu-create
time.
>
> We need to perform a KVM reset even when the VCPU is started through an
> ioctl. This patch is one of the ways we can achieve it.
>
> Assume that userspace has no business setting the post-reset state.
> KVM is de-facto the SBI implementation, as the SBI HSM acceleration
> cannot be disabled and userspace cannot control the reset state, so KVM
> should be in full control of the post-reset state.
>
> Do not reset the pc and a1 registers, because SBI reset is expected to
> provide them and KVM has no idea what these registers should be -- only
> the userspace knows where it put the data.
s/userspace/guest/
>
> An important consideration is resume. Userspace might want to start
> with non-reset state. Check ran_atleast_once to allow this, because
> KVM-SBI HSM creates some VCPUs as STOPPED.
>
> The drawback is that userspace can still start the boot VCPU with an
> incorrect reset state, because there is no way to distinguish a freshly
> reset new VCPU on the KVM side (userspace might set some values by
> mistake) from a restored VCPU (userspace must set all values).
If there's a correct vs. incorrect reset state that KVM needs to enforce,
then we'll need a different API than just a bunch of set-one-reg calls,
or set/get-one-reg should be WARL for userpace.
>
> The advantage of this solution is that it fixes current QEMU and makes
> some sense with the assumption that KVM implements SBI HSM.
> I do not like it too much, so I'd be in favor of a different solution if
> we can still afford to drop support for current userspaces.
>
> For a cleaner solution, we should add interfaces to perform the KVM-SBI
> reset request on userspace demand.
That's what the change to kvm_arch_vcpu_ioctl_set_mpstate() in this
patch is providing, right?
> I think it would also be much better
> if userspace was in control of the post-reset state.
Agreed. Can we just exit to userspace on SBI HSM reset?
Thanks,
drew
>
> Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
> ---
> arch/riscv/include/asm/kvm_host.h | 1 +
> arch/riscv/include/asm/kvm_vcpu_sbi.h | 3 +++
> arch/riscv/kvm/vcpu.c | 9 +++++++++
> arch/riscv/kvm/vcpu_sbi.c | 21 +++++++++++++++++++--
> 4 files changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
> index 0c8c9c05af91..9bbf8c4a286b 100644
> --- a/arch/riscv/include/asm/kvm_host.h
> +++ b/arch/riscv/include/asm/kvm_host.h
> @@ -195,6 +195,7 @@ struct kvm_vcpu_smstateen_csr {
>
> struct kvm_vcpu_reset_state {
> spinlock_t lock;
> + bool active;
> unsigned long pc;
> unsigned long a1;
> };
> diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
> index aaaa81355276..2c334a87e02a 100644
> --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
> +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
> @@ -57,6 +57,9 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
> u32 type, u64 flags);
> void kvm_riscv_vcpu_sbi_request_reset(struct kvm_vcpu *vcpu,
> unsigned long pc, unsigned long a1);
> +void __kvm_riscv_vcpu_set_reset_state(struct kvm_vcpu *vcpu,
> + unsigned long pc, unsigned long a1);
> +void kvm_riscv_vcpu_sbi_request_reset_from_userspace(struct kvm_vcpu *vcpu);
> int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
> int kvm_riscv_vcpu_set_reg_sbi_ext(struct kvm_vcpu *vcpu,
> const struct kvm_one_reg *reg);
> diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
> index b8485c1c1ce4..4578863a39e3 100644
> --- a/arch/riscv/kvm/vcpu.c
> +++ b/arch/riscv/kvm/vcpu.c
> @@ -58,6 +58,11 @@ static void kvm_riscv_vcpu_context_reset(struct kvm_vcpu *vcpu)
> struct kvm_vcpu_reset_state *reset_state = &vcpu->arch.reset_state;
> void *vector_datap = cntx->vector.datap;
>
> + spin_lock(&reset_state->lock);
> + if (!reset_state->active)
> + __kvm_riscv_vcpu_set_reset_state(vcpu, cntx->sepc, cntx->a1);
> + spin_unlock(&reset_state->lock);
> +
> memset(cntx, 0, sizeof(*cntx));
> memset(csr, 0, sizeof(*csr));
>
> @@ -520,6 +525,10 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
>
> switch (mp_state->mp_state) {
> case KVM_MP_STATE_RUNNABLE:
> + if (riscv_vcpu_supports_sbi_ext(vcpu, KVM_RISCV_SBI_EXT_HSM) &&
> + vcpu->arch.ran_atleast_once &&
> + kvm_riscv_vcpu_stopped(vcpu))
> + kvm_riscv_vcpu_sbi_request_reset_from_userspace(vcpu);
> WRITE_ONCE(vcpu->arch.mp_state, *mp_state);
> break;
> case KVM_MP_STATE_STOPPED:
> diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
> index 3d7955e05cc3..77f9f0bd3842 100644
> --- a/arch/riscv/kvm/vcpu_sbi.c
> +++ b/arch/riscv/kvm/vcpu_sbi.c
> @@ -156,12 +156,29 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
> run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
> }
>
> +/* must be called with held vcpu->arch.reset_state.lock */
> +void __kvm_riscv_vcpu_set_reset_state(struct kvm_vcpu *vcpu,
> + unsigned long pc, unsigned long a1)
> +{
> + vcpu->arch.reset_state.active = true;
> + vcpu->arch.reset_state.pc = pc;
> + vcpu->arch.reset_state.a1 = a1;
> +}
> +
> void kvm_riscv_vcpu_sbi_request_reset(struct kvm_vcpu *vcpu,
> unsigned long pc, unsigned long a1)
> {
> spin_lock(&vcpu->arch.reset_state.lock);
> - vcpu->arch.reset_state.pc = pc;
> - vcpu->arch.reset_state.a1 = a1;
> + __kvm_riscv_vcpu_set_reset_state(vcpu, pc, a1);
> + spin_unlock(&vcpu->arch.reset_state.lock);
> +
> + kvm_make_request(KVM_REQ_VCPU_RESET, vcpu);
> +}
> +
> +void kvm_riscv_vcpu_sbi_request_reset_from_userspace(struct kvm_vcpu *vcpu)
> +{
> + spin_lock(&vcpu->arch.reset_state.lock);
> + vcpu->arch.reset_state.active = false;
> spin_unlock(&vcpu->arch.reset_state.lock);
>
> kvm_make_request(KVM_REQ_VCPU_RESET, vcpu);
> --
> 2.48.1
>
next prev parent reply other threads:[~2025-04-25 13:26 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-03 11:25 [PATCH 0/5] KVM: RISC-V: VCPU reset fixes Radim Krčmář
2025-04-03 11:25 ` [PATCH 1/5] KVM: RISC-V: refactor vector state reset Radim Krčmář
2025-04-25 12:56 ` Andrew Jones
2025-05-07 11:43 ` Anup Patel
2025-04-03 11:25 ` [PATCH 2/5] KVM: RISC-V: refactor sbi reset request Radim Krčmář
2025-04-25 12:58 ` Andrew Jones
2025-05-07 12:01 ` Anup Patel
2025-05-07 17:28 ` Radim Krčmář
2025-05-08 5:02 ` Anup Patel
2025-04-03 11:25 ` [PATCH 3/5] KVM: RISC-V: remove unnecessary SBI reset state Radim Krčmář
2025-04-25 13:05 ` Andrew Jones
2025-04-28 12:16 ` Anup Patel
2025-04-28 18:00 ` Radim Krčmář
2025-04-29 5:50 ` Anup Patel
2025-05-08 6:18 ` Anup Patel
2025-05-08 10:02 ` Radim Krčmář
2025-05-08 13:11 ` Anup Patel
2025-04-03 11:25 ` [PATCH 4/5] KVM: RISC-V: reset VCPU state when becoming runnable Radim Krčmář
2025-04-25 13:26 ` Andrew Jones [this message]
2025-04-25 16:04 ` Radim Krčmář
2025-04-28 12:22 ` Anup Patel
2025-04-28 17:45 ` Radim Krčmář
2025-04-29 5:55 ` Anup Patel
2025-04-29 10:25 ` Radim Krčmář
2025-04-29 15:01 ` Anup Patel
2025-04-29 16:21 ` Radim Krčmář
2025-04-30 4:22 ` Anup Patel
2025-04-30 5:26 ` Anup Patel
2025-04-30 8:29 ` Radim Krčmář
2025-04-30 10:17 ` Anup Patel
2025-04-30 11:45 ` Radim Krčmář
2025-04-30 13:02 ` Anup Patel
2025-04-30 14:38 ` Radim Krčmář
2025-04-03 11:25 ` [PATCH 5/5] KVM: RISC-V: reset smstateen CSRs Radim Krčmář
2025-04-25 12:38 ` Anup Patel
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=20250425-2bc11e21ecef7269702c424e@orel \
--to=ajones@ventanamicro.com \
--cc=alex@ghiti.fr \
--cc=anup@brainfault.org \
--cc=aou@eecs.berkeley.edu \
--cc=atishp@atishpatra.org \
--cc=kvm-riscv@lists.infradead.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mchitale@ventanamicro.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=rkrcmar@ventanamicro.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox