From nobody Sun Feb 8 03:30:49 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CF80219317 for ; Thu, 15 May 2025 14:53:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747320783; cv=none; b=XnxmpLNwXmuTIEHITqTbZTEtZJCsrZdJFUxViFJIbL2a5QovkBRL3s1g1mFD42zAjVl48uDSSDEW4QkyrrnJWPUWSROsriUNHYr/5MCdOeO0hwe9CnXl3KiPM9sn43YH9A1VCXmEKBD0HOHj28+du6U8mqTFgh1MJj5U+EHXYw4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747320783; c=relaxed/simple; bh=5aytGyw7U1i0Xd1U4Oy4rPiXiOEcWSKgzOJuZ2cVDao=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y4vdfb+XMZCloBfNFgAaDIdXOaX55xmoOGG8DlRPM8WvyRC8O+VNX0LQWwbjlUBzJXStVmler6XmvJa2m98EUaREVp/5Aw84Nrw/P2+n9rNPXZFkcbj0pNH7GX2m15lVcgxHfcCCOxyhctCSoomSFdo2WZxY99oaCjVWOsx8yE8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=TFIp5Lwr; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="TFIp5Lwr" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-442eb7edc80so589195e9.1 for ; Thu, 15 May 2025 07:53:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1747320779; x=1747925579; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MI4r/0MkyeFCFhMfeAnOJjuw3BBTosdSkQfxrX8t8KQ=; b=TFIp5Lwr6HkDG1EKOSfpDn84Ous5Gd06u55uJAwZiYlZ8fnZZeMnUA8i/FMVAreJC4 uie0S734Dm2lmpjAllJANYEV8TchL55Qk6tw6c9UxpL0cBf0J1+0dZEQyCZRpX+ldpoK PTKpj0EzCBwQfry/vCvrXVj/SQG31trZ/tqla0Sq1WVgQDGC3PD5pdgvdVHcaBa42jrK 1bn1FLyKRuuWUx7kGZd5XJtPsKHSzAoB181pmjGKDwdsKr7c6w93iEmJChiuJsJoJwdr OpX2inGXMLyMNd/pvti0DtrNly+A/Inu/ySORntea5UUegIM7QJzwmHlqJ8TO4sEL6nc nyTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747320779; x=1747925579; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MI4r/0MkyeFCFhMfeAnOJjuw3BBTosdSkQfxrX8t8KQ=; b=Z3qMdG76kX0DfQX01JpvWsOSdhdGAl2ASz/LlzgD41gslHCrqnDQZnk6XT843UbBUs p4bybWtKWbcQWI35SpyEtujI3EVyf+aEDKOS6DGI6hWE97cYy3vdfRhr2jezcVxmRTc/ h+j+J7zExZ6UecWkt+dpBY98tWMdTCBbd+oB4ZVyhEBTDdtGdGF2/2ApMQeyIR1ZTiMF tAAY/dwR3wXFIuufS7HMuVkA/LIel+eQFpiwRhhLYMcGfksrc2nzqVIZKPTdFy/5U0WH Utje+EtT8h7ZzhhdW0nwD5x/DV+iIuMALzwRNciol2pzwiN7K2eQxbuqcTeKnUcSVAH0 q8/g== X-Forwarded-Encrypted: i=1; AJvYcCUftAXbczPiDbOxlmqKBsal+ZdeHPChdEEeEtN3Btb8pTOfC8aJNtewyTiWyPHKXSbAZqIRPm+7p94Q9jc=@vger.kernel.org X-Gm-Message-State: AOJu0YyJN+q2OmU4E2EnsYob6qBYoTPCRuFvMZN28tVtUVJQYRFvo344 SddtHaGvsH4cNa6l6BH6MJSfkIMQx+b1yCky0mrJV0gGQuEoJrQnQ/UkegkdJPc= X-Gm-Gg: ASbGncvfSMDGjTwSw2b/d1wPrKITCkK/H7VqUEYv4KY1rAwOjtXWermcTrRLOZvmXGY jvWeM2fq9thygNKAzR2YTZOUeQhistDnL4FtxVyzrEm43+qtr9osZuotw5rELkgaGEYzrmpF6RK Yf1sYoP9JOh2gF2z6JAvScqLaGbQ4Q5O6LY04hda9bWpo2tWEXd+AFt9ZNWliouF6KW7OpQURm2 bvK+Ev4vhBcCXSXE9fqYvUPZvVKCU8CTwLyhYt8XcKKWTJ80v9V+W9cW512+hN7/s7uSjuuJHQm pmIVVjrVswcoBe7B2N4fJF+vb3N2KGvuwTgs3tVZj/Eu6ZN3KYW2UVCB X-Google-Smtp-Source: AGHT+IEpZ9PaXNge5gggaswM8grdAbE7qn5UMWCZgDtX4BmC48cndXLVf7sy1H74LQs3vsjF1NgKpw== X-Received: by 2002:a05:600c:1ca3:b0:43b:c938:1d0e with SMTP id 5b1f17b1804b1-442f20bfcd5mr27466075e9.2.1747320774631; Thu, 15 May 2025 07:52:54 -0700 (PDT) Received: from localhost ([2a02:8308:a00c:e200:59f5:9ec:79d9:ffc]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-442f9053b4dsm29668385e9.4.2025.05.15.07.52.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 May 2025 07:52:54 -0700 (PDT) From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= To: kvm-riscv@lists.infradead.org Cc: kvm@vger.kernel.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Anup Patel , Atish Patra , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Andrew Jones Subject: [PATCH v3 1/2] RISC-V: KVM: add KVM_CAP_RISCV_MP_STATE_RESET Date: Thu, 15 May 2025 16:37:25 +0200 Message-ID: <20250515143723.2450630-5-rkrcmar@ventanamicro.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250515143723.2450630-4-rkrcmar@ventanamicro.com> References: <20250515143723.2450630-4-rkrcmar@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a toggleable VM capability to reset the VCPU from userspace by setting MP_STATE_INIT_RECEIVED through IOCTL. Reset through a mp_state to avoid adding a new IOCTL. Do not reset on a transition from STOPPED to RUNNABLE, because it's better to avoid side effects that would complicate userspace adoption. The MP_STATE_INIT_RECEIVED is not a permanent mp_state -- IOCTL resets the VCPU while preserving the original mp_state -- because we wouldn't gain much from having a new state it in the rest of KVM, but it's a very non-standard use of the IOCTL. Signed-off-by: Radim Kr=C4=8Dm=C3=A1=C5=99 Reviewed-by: Anup Patel --- If we want a permanent mp_state, I think that MP_STATE_UNINITIALIZED would be reasonable. KVM could reset on transition to any other state. v3: do not allow allow userspace to set the HSM reset state [Anup] v2: new --- Documentation/virt/kvm/api.rst | 11 +++++++++++ arch/riscv/include/asm/kvm_host.h | 3 +++ arch/riscv/include/asm/kvm_vcpu_sbi.h | 1 + arch/riscv/kvm/vcpu.c | 27 ++++++++++++++------------- arch/riscv/kvm/vcpu_sbi.c | 17 +++++++++++++++++ arch/riscv/kvm/vm.c | 13 +++++++++++++ include/uapi/linux/kvm.h | 1 + 7 files changed, 60 insertions(+), 13 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 47c7c3f92314..e107694fb41f 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8496,6 +8496,17 @@ aforementioned registers before the first KVM_RUN. T= hese registers are VM scoped, meaning that the same set of values are presented on all vCPUs in a given VM. =20 +7.43 KVM_CAP_RISCV_MP_STATE_RESET +--------------------------------- + +:Architectures: riscv +:Type: VM +:Parameters: None +:Returns: 0 on success, -EINVAL if arg[0] is not zero + +When this capability is enabled, KVM resets the VCPU when setting +MP_STATE_INIT_RECEIVED through IOCTL. The original MP_STATE is preserved. + 8. Other capabilities. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm= _host.h index f673ebfdadf3..85cfebc32e4c 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -119,6 +119,9 @@ struct kvm_arch { =20 /* AIA Guest/VM context */ struct kvm_aia aia; + + /* KVM_CAP_RISCV_MP_STATE_RESET */ + bool mp_state_reset; }; =20 struct kvm_cpu_trap { diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm= /kvm_vcpu_sbi.h index da28235939d1..439ab2b3534f 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -57,6 +57,7 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcp= u, 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_sbi_load_reset_state(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 a78f9ec2fa0e..521cd41bfffa 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -51,11 +51,11 @@ const struct kvm_stats_header kvm_vcpu_stats_header =3D= { sizeof(kvm_vcpu_stats_desc), }; =20 -static void kvm_riscv_vcpu_context_reset(struct kvm_vcpu *vcpu) +static void kvm_riscv_vcpu_context_reset(struct kvm_vcpu *vcpu, + bool kvm_sbi_reset) { struct kvm_vcpu_csr *csr =3D &vcpu->arch.guest_csr; struct kvm_cpu_context *cntx =3D &vcpu->arch.guest_context; - struct kvm_vcpu_reset_state *reset_state =3D &vcpu->arch.reset_state; void *vector_datap =3D cntx->vector.datap; =20 memset(cntx, 0, sizeof(*cntx)); @@ -65,13 +65,8 @@ static void kvm_riscv_vcpu_context_reset(struct kvm_vcpu= *vcpu) /* Restore datap as it's not a part of the guest context. */ cntx->vector.datap =3D vector_datap; =20 - /* Load SBI reset values */ - cntx->a0 =3D vcpu->vcpu_id; - - spin_lock(&reset_state->lock); - cntx->sepc =3D reset_state->pc; - cntx->a1 =3D reset_state->a1; - spin_unlock(&reset_state->lock); + if (kvm_sbi_reset) + kvm_riscv_vcpu_sbi_load_reset_state(vcpu); =20 /* Setup reset state of shadow SSTATUS and HSTATUS CSRs */ cntx->sstatus =3D SR_SPP | SR_SPIE; @@ -84,7 +79,7 @@ static void kvm_riscv_vcpu_context_reset(struct kvm_vcpu = *vcpu) csr->scounteren =3D 0x7; } =20 -static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) +static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu, bool kvm_sbi_reset) { bool loaded; =20 @@ -100,7 +95,7 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) =20 vcpu->arch.last_exit_cpu =3D -1; =20 - kvm_riscv_vcpu_context_reset(vcpu); + kvm_riscv_vcpu_context_reset(vcpu, kvm_sbi_reset); =20 kvm_riscv_vcpu_fp_reset(vcpu); =20 @@ -177,7 +172,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) kvm_riscv_vcpu_sbi_init(vcpu); =20 /* Reset VCPU */ - kvm_riscv_reset_vcpu(vcpu); + kvm_riscv_reset_vcpu(vcpu, false); =20 return 0; } @@ -526,6 +521,12 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *v= cpu, case KVM_MP_STATE_STOPPED: __kvm_riscv_vcpu_power_off(vcpu); break; + case KVM_MP_STATE_INIT_RECEIVED: + if (vcpu->kvm->arch.mp_state_reset) + kvm_riscv_reset_vcpu(vcpu, false); + else + ret =3D -EINVAL; + break; default: ret =3D -EINVAL; } @@ -714,7 +715,7 @@ static void kvm_riscv_check_vcpu_requests(struct kvm_vc= pu *vcpu) } =20 if (kvm_check_request(KVM_REQ_VCPU_RESET, vcpu)) - kvm_riscv_reset_vcpu(vcpu); + kvm_riscv_reset_vcpu(vcpu, true); =20 if (kvm_check_request(KVM_REQ_UPDATE_HGATP, vcpu)) kvm_riscv_gstage_update_hgatp(vcpu); diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 0afef0bb261d..31fd3cc98d66 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -167,6 +167,23 @@ void kvm_riscv_vcpu_sbi_request_reset(struct kvm_vcpu = *vcpu, kvm_make_request(KVM_REQ_VCPU_RESET, vcpu); } =20 +void kvm_riscv_vcpu_sbi_load_reset_state(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_csr *csr =3D &vcpu->arch.guest_csr; + struct kvm_cpu_context *cntx =3D &vcpu->arch.guest_context; + struct kvm_vcpu_reset_state *reset_state =3D &vcpu->arch.reset_state; + + cntx->a0 =3D vcpu->vcpu_id; + + spin_lock(&vcpu->arch.reset_state.lock); + cntx->sepc =3D reset_state->pc; + cntx->a1 =3D reset_state->a1; + spin_unlock(&vcpu->arch.reset_state.lock); + + cntx->sstatus &=3D ~SR_SIE; + csr->vsatp =3D 0; +} + int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct kvm_cpu_context *cp =3D &vcpu->arch.guest_context; diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c index 7396b8654f45..b27ec8f96697 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c @@ -209,6 +209,19 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long= ext) return r; } =20 +int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) +{ + switch (cap->cap) { + case KVM_CAP_RISCV_MP_STATE_RESET: + if (cap->flags) + return -EINVAL; + kvm->arch.mp_state_reset =3D true; + return 0; + default: + return -EINVAL; + } +} + int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long= arg) { return -EINVAL; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index b6ae8ad8934b..454b7d4a0448 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -930,6 +930,7 @@ struct kvm_enable_cap { #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 #define KVM_CAP_X86_GUEST_MODE 238 #define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239 +#define KVM_CAP_RISCV_MP_STATE_RESET 240 =20 struct kvm_irq_routing_irqchip { __u32 irqchip; --=20 2.49.0 From nobody Sun Feb 8 03:30:49 2026 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF6B21F8EFF for ; Thu, 15 May 2025 14:52:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747320779; cv=none; b=Hb23s87TzbmYHLRaH07Ywqujn7hRqveq9PJvbbabCQoJXComZHF0PU9fakjttF+l9MRPP0XHxBuyXPQ840ZuxZG7LZ0P7Uovfn3TOa63xSg2xiHl62ZMFq9bJMkQOBsNQp3WvDaJ1A/iAGM0JF1aPsRg3KIhyvgCFl7u9jeRcD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747320779; c=relaxed/simple; bh=hFaYWBEBY0HzajektsAiaj35JqVI8lq3iUn/Da+pW+g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=U0ykAxbgkgcKWKEnsSDE9tU4Udb3CPkKWdfgNTTPF13n2QJySO99vM2YEoKyGaW6gK+H8RTrifmnQldvv/HEy5guJivduyzkWVOlt8U7xSzsuQk+mRsGEMMyfA3iTTqubSfn0nK+IASqCdql/dgDw9jexgm3lCz4R0qIq/Qkw9Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=CdVgUHc3; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="CdVgUHc3" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-3a35c339e95so25807f8f.3 for ; Thu, 15 May 2025 07:52:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1747320776; x=1747925576; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uIZgXNME8r0sE5ooEmr0L318UA8GXpBZxCC2zWvfkBI=; b=CdVgUHc3aPOJF8xa2T1P0zm2lOtqGRscU610DflboK02fU8+FCpTXYVWQMZ4jTwECk Yh7dIhJOcbmDuxXmskmHQ8H168jUADlpXvAUxCkzdvlRyrRRM65C3yzi7k7B8OuCjhTt NoRjtDILSXD7mbJEtEqMwLsriS/llg0uXR872qPkp5Tp0m4hcVvx3YX2UK9NDeCV6epv WYzb4vM8OPSTTikniTjgSogL+alNphqQqJkf6ZPId1cJj9yIPZCeS4Gz+zHAekwGdo43 pfsxN2+cC1nc4Ztk/f82jQTs7KcnuX69agHJQcwKW7s0QAb+C1OSRe87rBM8FfNxk4t0 fF3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747320776; x=1747925576; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uIZgXNME8r0sE5ooEmr0L318UA8GXpBZxCC2zWvfkBI=; b=T6rbpbZ1Hehpm4/rCEQyTg4Bm9opAGAS/bFKM2KiO0Ht60+zVP5DVFYlvZE2pTSu/7 Es2v5B8i6h8LW+pTJ6EHHZP3UVzqm8vvJ76EX42HDEm/+FGE/EAWjqR+clejT2hFJdiB 1B/aClVWZVxjJH1OHLVJRFnyU9rBT99jHrr2Ald6j9wMjpKKJE0Vod5eYDpSN1hWVdQ4 k1QyazPTDy3zQw9I+drxHw9hv0FFK66SDK0TPQXEo4BnAFfv+eRiEZBRBZL2OiISGdZ4 Ptff+kIGOAo+hUHn8Gv06ScnaSghw33liC9KBjDazzLd9Oox1adyU0uuR+Xj6f8lR1Dn 3Myg== X-Forwarded-Encrypted: i=1; AJvYcCVq4aDLqhB0BKGUQrBgV9cA7NhwT7nncxdH6x8c3ES1plqr0oeZWw/3ThddNSyrfPQZReBJotgMUYVNxJk=@vger.kernel.org X-Gm-Message-State: AOJu0YzVY/MqtHay/kB9f6V67mKryfseTgb5LX8GY3K2F1uQrw03UdNB h4wHBalmla7yKUYYRgU/HzTWhGbzK803vpnOu5ZY1gFHXkF+73JjMGZT9ugnL/fG4Uo= X-Gm-Gg: ASbGncu/CYQ6+a1Y3HiNh4Dxvh1XM0e6BkJrNoj143CbICcOOgiFMWaUeXFtoC/0Fae q2Ow5FsG4MmTt6L1ScH5HZZqffZQgC/zTVrUSYyNR6DOJ8p3hUfJG4jTHpC9PPzZHREmphE9vSp Q8AHfOuPCula3pyHTo7973+klqv+J3Qwy7tLNUV/FYQySVBBzEKwOqG7b87szpPYAyiFS3uE3Pu /kqaRynqkmBSZ7Mof1FKzhk2LXuQBPXVclwcPEHfRFPE/pk1sC8G6V8Zv6hB6PREl1Ov7t3+w2E ok26v1Lw8FmsnnVkTfcJSpjP8eytMjrKKWRehCZQIB7+iCfaCQkH2QtQ X-Google-Smtp-Source: AGHT+IGy6O2tOnw9TErwlciOBkx2moBTrgZcoot58P13AHHzScWNRRUCcYrPv0m2LluesoiEnXCjmQ== X-Received: by 2002:a5d:5f4d:0:b0:3a3:55b4:1abb with SMTP id ffacd0b85a97d-3a35c84c356mr10937f8f.12.1747320775665; Thu, 15 May 2025 07:52:55 -0700 (PDT) Received: from localhost ([2a02:8308:a00c:e200:59f5:9ec:79d9:ffc]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a35573f32bsm1842946f8f.17.2025.05.15.07.52.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 May 2025 07:52:55 -0700 (PDT) From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= To: kvm-riscv@lists.infradead.org Cc: kvm@vger.kernel.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Anup Patel , Atish Patra , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Andrew Jones Subject: [PATCH v3 2/2] RISC-V: KVM: add KVM_CAP_RISCV_USERSPACE_SBI Date: Thu, 15 May 2025 16:37:26 +0200 Message-ID: <20250515143723.2450630-6-rkrcmar@ventanamicro.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250515143723.2450630-4-rkrcmar@ventanamicro.com> References: <20250515143723.2450630-4-rkrcmar@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The new capability allows userspace to implement SBI extensions that KVM does not handle. This allows userspace to implement any SBI ecall as userspace already has the ability to disable acceleration of selected SBI extensions. This is a VM capability, because userspace will most likely want to have the same behavior for all VCPUs. We can easily make it both a VCPU and a VM capability if there is demand in the future. Signed-off-by: Radim Kr=C4=8Dm=C3=A1=C5=99 --- v3: new --- Documentation/virt/kvm/api.rst | 11 +++++++++++ arch/riscv/include/asm/kvm_host.h | 3 +++ arch/riscv/kvm/vcpu_sbi.c | 10 ++++++++-- arch/riscv/kvm/vm.c | 5 +++++ include/uapi/linux/kvm.h | 1 + 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index e107694fb41f..c9d627d13a5e 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8507,6 +8507,17 @@ given VM. When this capability is enabled, KVM resets the VCPU when setting MP_STATE_INIT_RECEIVED through IOCTL. The original MP_STATE is preserved. =20 +7.44 KVM_CAP_RISCV_USERSPACE_SBI +-------------------------------- + +:Architectures: riscv +:Type: VM +:Parameters: None +:Returns: 0 on success, -EINVAL if arg[0] is not zero + +When this capability is enabled, KVM forwards ecalls from disabled or unkn= own +SBI extensions to userspace. + 8. Other capabilities. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm= _host.h index 85cfebc32e4c..6f17cd923889 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -122,6 +122,9 @@ struct kvm_arch { =20 /* KVM_CAP_RISCV_MP_STATE_RESET */ bool mp_state_reset; + + /* KVM_CAP_RISCV_USERSPACE_SBI */ + bool userspace_sbi; }; =20 struct kvm_cpu_trap { diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 31fd3cc98d66..6d4a55d276cb 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -471,8 +471,14 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, st= ruct kvm_run *run) #endif ret =3D sbi_ext->handler(vcpu, run, &sbi_ret); } else { - /* Return error for unsupported SBI calls */ - cp->a0 =3D SBI_ERR_NOT_SUPPORTED; + if (vcpu->kvm->arch.userspace_sbi) { + next_sepc =3D false; + ret =3D 0; + kvm_riscv_vcpu_sbi_forward(vcpu, run); + } else { + /* Return error for unsupported SBI calls */ + cp->a0 =3D SBI_ERR_NOT_SUPPORTED; + } goto ecall_done; } =20 diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c index b27ec8f96697..0b6378b83955 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c @@ -217,6 +217,11 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kv= m_enable_cap *cap) return -EINVAL; kvm->arch.mp_state_reset =3D true; return 0; + case KVM_CAP_RISCV_USERSPACE_SBI: + if (cap->flags) + return -EINVAL; + kvm->arch.userspace_sbi =3D true; + return 0; default: return -EINVAL; } diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 454b7d4a0448..f5796c5b8dae 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -931,6 +931,7 @@ struct kvm_enable_cap { #define KVM_CAP_X86_GUEST_MODE 238 #define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239 #define KVM_CAP_RISCV_MP_STATE_RESET 240 +#define KVM_CAP_RISCV_USERSPACE_SBI 241 =20 struct kvm_irq_routing_irqchip { __u32 irqchip; --=20 2.49.0