Received: by 2002:a05:6358:11c7:b0:104:8066:f915 with SMTP id i7csp1406021rwl; Fri, 31 Mar 2023 10:36:14 -0700 (PDT) X-Google-Smtp-Source: AKy350b+5pCcPA+lD9Y6U5jsQy51KNvJt6f0vNAWX4EtxKENnxbCrsTjBqhLwFzUwqwKn8vKwzOy X-Received: by 2002:a17:906:2098:b0:930:7f40:c1bb with SMTP id 24-20020a170906209800b009307f40c1bbmr5441517ejq.4.1680284173992; Fri, 31 Mar 2023 10:36:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680284173; cv=none; d=google.com; s=arc-20160816; b=RR/iV2zCsSzdA/IA51BZsxlgz1SddcUHNgWBmQ0NZMOGxDhBFFp1Nvrcirb32cBNex Reo4Ez8iQeAlWKsXDreo4eGdMmcpP1URRA8KOhe5PKowoy+5WJ8KZ6YnPQwbrf3XxwlE OzyItrd0ANJ+E+68TmZxNN5kVrfur01gyfk1knZ1Kw4g8KY8qGOq23Kf19mVYgZAjVUe wKmle9dfu6/PgzuaYHhF6EFgyeuDMp8sjjgC0zY06j7g3RPHDaZJkIdCjkwpNW9rqKA5 ZvNVd4y0ayrDhq12216PLwxERZ40pBjrZ5hJFPov0Op2sJisJoSZtxZIXswszJ/iI5y8 efAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=fDHGgUBzeIFVYGhvCm1Win8m4P7KOEPhzt5sED+Esfs=; b=TxJw6R0HwQmIY6vxSLfjSkMs4Z8Lnfk1EbpgVLPixaIIyiNlZbEgKUN68brH8GppKO 2M5qXKy20syEVYlRGiD7WouyqGIOirHIOzr7I6F/Rm0hy8/Erfhe/Nl72vIpzM5xzc4T +7pNjMG4r5Q8tyaR1LT/5APTzDQnuxBv6cRCfHYcT1IyajUpoHKMY56YnrzhyreuFxGx 3FXodqtBA3AIhaYzGwkwj8wYGkbHDl11mKeEEzjUaZC1DfCUkHIT/WBgKWfxie3xKt2Q r3yRyAHOcXRTr6cm4J83V2VQHg6BFCvUeT7aabUjof+QYgl652Qa48X6W1tSgiF1zhCg fgWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@brainfault-org.20210112.gappssmtp.com header.s=20210112 header.b=P480eZUf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g6-20020a170906198600b0092bb392d660si2012610ejd.249.2023.03.31.10.35.49; Fri, 31 Mar 2023 10:36:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@brainfault-org.20210112.gappssmtp.com header.s=20210112 header.b=P480eZUf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231818AbjCaR2c (ORCPT + 99 others); Fri, 31 Mar 2023 13:28:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231232AbjCaR2a (ORCPT ); Fri, 31 Mar 2023 13:28:30 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E1DC1D2CA for ; Fri, 31 Mar 2023 10:28:27 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id t10so92363388edd.12 for ; Fri, 31 Mar 2023 10:28:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; t=1680283706; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=fDHGgUBzeIFVYGhvCm1Win8m4P7KOEPhzt5sED+Esfs=; b=P480eZUfhRHvnrku7ZpNlDovErMc/IlKCs/VBGQKIzKzVmcDitoXBptZnaECMn9N0T vlqT7vIqyW8UaZLZaYjOfu7Mx4eTIETQzPBkt8VYkGthAFZkHUhCsVVF4AAf9uNSyXPn EIOYDH08XHeJqkSWDM4tek/jO1yEFlvT9sbLO1QkU9WvN+omSRL3+uMhDpfAUv5gogly Pic6CCJs9wAfqyy3LeyCoI/WMiW9SontCPtTTQPEk8laDhYMGJtUajR5npV/2fLcx/D6 GcJmiQkFVoMM+BAzWDvs2YxRj0ZHpuPVf152EGQruEH+hIe2tPgNG0v+MhPZee0QpPxc yrNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680283706; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fDHGgUBzeIFVYGhvCm1Win8m4P7KOEPhzt5sED+Esfs=; b=A4a/FZWwe6g54gnSubvVVou2uVq3Kr6driuJnwYLIjbdf4hYBXHzk6ZZzuhtro/85l ZmtB/3BYVR0UaNQW3SrHjHvfDLTyM49Sr3gkwHIGt+BvfFRe99rHfAL+TVq4Fb1Nnud5 fHqRFXJMf/6Jo6Tc4+GK0GX51m8GCDUH93+ohXfurGjTo+KnOOy37YTSkJZMesXDlOB1 GOQVxpfKxhcW6RW4aDjelNSTJZHSDZqgkynrhOJvtfhVriyUj+qHbZCHEQYBS80pDgwd i63Ufb+vikmK+hEk5DBGvx0DmtsZIxCXOL7nbDMxBuAZts/N91GygKC4/gorD3L0MKEw iIvg== X-Gm-Message-State: AAQBX9fXPbWh/pAl4Dc7hA5KnvIn5QHwvGhY9diaFZH6XCyoGoA8ZGSt dp0UMjL0SndxHE6koMPeLb61EOjJympjEXV3B5rdpw== X-Received: by 2002:a17:906:7c54:b0:932:6a66:fc43 with SMTP id g20-20020a1709067c5400b009326a66fc43mr13576245ejp.13.1680283705871; Fri, 31 Mar 2023 10:28:25 -0700 (PDT) MIME-Version: 1.0 References: <20230331123655.1991260-1-apatel@ventanamicro.com> <20230331123655.1991260-2-apatel@ventanamicro.com> In-Reply-To: From: Anup Patel Date: Fri, 31 Mar 2023 22:58:13 +0530 Message-ID: Subject: Re: [PATCH v3 1/1] RISC-V: KVM: Add ONE_REG interface to enable/disable SBI extensions To: Andrew Jones Cc: Anup Patel , Paolo Bonzini , Atish Patra , Palmer Dabbelt , Paul Walmsley , kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=0.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Mar 31, 2023 at 7:17=E2=80=AFPM Andrew Jones wrote: > > On Fri, Mar 31, 2023 at 06:06:55PM +0530, Anup Patel wrote: > > We add ONE_REG interface to enable/disable SBI extensions (just > > like the ONE_REG interface for ISA extensions). This allows KVM > > user-space to decide the set of SBI extension enabled for a Guest > > and by default all SBI extensions are enabled. > > > > Signed-off-by: Anup Patel > > --- > > arch/riscv/include/asm/kvm_vcpu_sbi.h | 8 +- > > arch/riscv/include/uapi/asm/kvm.h | 32 ++++ > > arch/riscv/kvm/vcpu.c | 2 + > > arch/riscv/kvm/vcpu_sbi.c | 245 ++++++++++++++++++++++++-- > > arch/riscv/kvm/vcpu_sbi_base.c | 2 +- > > 5 files changed, 270 insertions(+), 19 deletions(-) > > > > diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include= /asm/kvm_vcpu_sbi.h > > index 8425556af7d1..4278125a38a5 100644 > > --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h > > +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h > > @@ -16,6 +16,7 @@ > > > > struct kvm_vcpu_sbi_context { > > int return_handled; > > + bool extension_disabled[KVM_RISCV_SBI_EXT_MAX]; > > This could be a bitmap too, but maybe we can defer the conversion until > later when there are more SBI extensions. > > > }; > > > > struct kvm_vcpu_sbi_return { > > @@ -45,7 +46,12 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu= *vcpu, > > struct kvm_run *run, > > u32 type, u64 flags); > > int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *r= un); > > -const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned lo= ng extid); > > +int kvm_riscv_vcpu_set_reg_sbi_ext(struct kvm_vcpu *vcpu, > > + const struct kvm_one_reg *reg); > > +int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu, > > + const struct kvm_one_reg *reg); > > +const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext( > > + struct kvm_vcpu *vcpu, unsigned long exti= d); > > int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *ru= n); > > > > #ifdef CONFIG_RISCV_SBI_V01 > > diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uap= i/asm/kvm.h > > index 92af6f3f057c..d8ead5952ed9 100644 > > --- a/arch/riscv/include/uapi/asm/kvm.h > > +++ b/arch/riscv/include/uapi/asm/kvm.h > > @@ -12,6 +12,7 @@ > > #ifndef __ASSEMBLY__ > > > > #include > > +#include > > #include > > > > #define __KVM_HAVE_READONLY_MEM > > @@ -108,6 +109,23 @@ enum KVM_RISCV_ISA_EXT_ID { > > KVM_RISCV_ISA_EXT_MAX, > > }; > > > > +/* > > + * SBI extension IDs specific to KVM. This is not the same as the SBI > > + * extension IDs defined by the RISC-V SBI specification. > > + */ > > +enum KVM_RISCV_SBI_EXT_ID { > > + KVM_RISCV_SBI_EXT_V01 =3D 0, > > + KVM_RISCV_SBI_EXT_TIME, > > + KVM_RISCV_SBI_EXT_IPI, > > + KVM_RISCV_SBI_EXT_RFENCE, > > + KVM_RISCV_SBI_EXT_SRST, > > + KVM_RISCV_SBI_EXT_HSM, > > + KVM_RISCV_SBI_EXT_PMU, > > + KVM_RISCV_SBI_EXT_EXPERIMENTAL, > > + KVM_RISCV_SBI_EXT_VENDOR, > > + KVM_RISCV_SBI_EXT_MAX, > > +}; > > + > > /* Possible states for kvm_riscv_timer */ > > #define KVM_RISCV_TIMER_STATE_OFF 0 > > #define KVM_RISCV_TIMER_STATE_ON 1 > > @@ -118,6 +136,8 @@ enum KVM_RISCV_ISA_EXT_ID { > > /* If you need to interpret the index values, here is the key: */ > > #define KVM_REG_RISCV_TYPE_MASK 0x00000000FF000000 > > #define KVM_REG_RISCV_TYPE_SHIFT 24 > > +#define KVM_REG_RISCV_SUBTYPE_MASK 0x0000000000FF0000 > > +#define KVM_REG_RISCV_SUBTYPE_SHIFT 16 > > > > /* Config registers are mapped as type 1 */ > > #define KVM_REG_RISCV_CONFIG (0x01 << KVM_REG_RISCV_TYPE_SHIFT= ) > > @@ -152,6 +172,18 @@ enum KVM_RISCV_ISA_EXT_ID { > > /* ISA Extension registers are mapped as type 7 */ > > #define KVM_REG_RISCV_ISA_EXT (0x07 << KVM_REG_RISCV_TY= PE_SHIFT) > > > > +/* SBI extension registers are mapped as type 8 */ > > +#define KVM_REG_RISCV_SBI_EXT (0x08 << KVM_REG_RISCV_TY= PE_SHIFT) > > +#define KVM_REG_RISCV_SBI_SINGLE (0x0 << KVM_REG_RISCV_SUBTYPE_SHI= FT) > > +#define KVM_REG_RISCV_SBI_MULTI_EN (0x1 << KVM_REG_RISCV_SUBTYPE_SHI= FT) > > +#define KVM_REG_RISCV_SBI_MULTI_DIS (0x2 << KVM_REG_RISCV_SUBTYPE_SHI= FT) > > +#define KVM_REG_RISCV_SBI_MULTI_REG(__ext_id) \ > > + ((__ext_id) / __BITS_PER_LONG) > > +#define KVM_REG_RISCV_SBI_MULTI_MASK(__ext_id) \ > > + (1UL << ((__ext_id) % __BITS_PER_LONG)) > > +#define KVM_REG_RISCV_SBI_MULTI_REG_LAST \ > > + KVM_REG_RISCV_SBI_MULTI_REG(KVM_RISCV_SBI_EXT_MAX - 1) > > + > > #endif > > > > #endif /* __LINUX_KVM_RISCV_H */ > > diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c > > index 7d010b0be54e..311fd347c5a8 100644 > > --- a/arch/riscv/kvm/vcpu.c > > +++ b/arch/riscv/kvm/vcpu.c > > @@ -601,6 +601,8 @@ static int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *= vcpu, > > KVM_REG_RISCV_FP_D); > > case KVM_REG_RISCV_ISA_EXT: > > return kvm_riscv_vcpu_set_reg_isa_ext(vcpu, reg); > > + case KVM_REG_RISCV_SBI_EXT: > > + return kvm_riscv_vcpu_set_reg_sbi_ext(vcpu, reg); > > default: > > break; > > } > > Missing the kvm_riscv_vcpu_get_reg() change. I totally missed this one. Good catch. > > > diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c > > index 15fde15f9fb8..89e3e7bace6c 100644 > > --- a/arch/riscv/kvm/vcpu_sbi.c > > +++ b/arch/riscv/kvm/vcpu_sbi.c > > @@ -30,17 +30,52 @@ static const struct kvm_vcpu_sbi_extension vcpu_sbi= _ext_pmu =3D { > > }; > > #endif > > > > -static const struct kvm_vcpu_sbi_extension *sbi_ext[] =3D { > > - &vcpu_sbi_ext_v01, > > - &vcpu_sbi_ext_base, > > - &vcpu_sbi_ext_time, > > - &vcpu_sbi_ext_ipi, > > - &vcpu_sbi_ext_rfence, > > - &vcpu_sbi_ext_srst, > > - &vcpu_sbi_ext_hsm, > > - &vcpu_sbi_ext_pmu, > > - &vcpu_sbi_ext_experimental, > > - &vcpu_sbi_ext_vendor, > > +struct kvm_riscv_sbi_extension_entry { > > + enum KVM_RISCV_SBI_EXT_ID dis_idx; > > + const struct kvm_vcpu_sbi_extension *ext_ptr; > > +}; > > + > > +static const struct kvm_riscv_sbi_extension_entry sbi_ext[] =3D { > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_V01, > > + .ext_ptr =3D &vcpu_sbi_ext_v01, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_MAX, /* Can't be disabled = */ > > + .ext_ptr =3D &vcpu_sbi_ext_base, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_TIME, > > + .ext_ptr =3D &vcpu_sbi_ext_time, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_IPI, > > + .ext_ptr =3D &vcpu_sbi_ext_ipi, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_RFENCE, > > + .ext_ptr =3D &vcpu_sbi_ext_rfence, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_SRST, > > + .ext_ptr =3D &vcpu_sbi_ext_srst, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_HSM, > > + .ext_ptr =3D &vcpu_sbi_ext_hsm, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_PMU, > > + .ext_ptr =3D &vcpu_sbi_ext_pmu, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_EXPERIMENTAL, > > + .ext_ptr =3D &vcpu_sbi_ext_experimental, > > + }, > > + { > > + .dis_idx =3D KVM_RISCV_SBI_EXT_VENDOR, > > + .ext_ptr =3D &vcpu_sbi_ext_vendor, > > + }, > > }; > > > > void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run = *run) > > @@ -99,14 +134,190 @@ int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vc= pu, struct kvm_run *run) > > return 0; > > } > > > > -const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned lo= ng extid) > > +static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu, > > + unsigned long reg_num, > > + unsigned long reg_val) > > +{ > > + unsigned long i; > > + const struct kvm_riscv_sbi_extension_entry *sext =3D NULL; > > + struct kvm_vcpu_sbi_context *scontext =3D &vcpu->arch.sbi_context= ; > > + > > + if (reg_num >=3D KVM_RISCV_SBI_EXT_MAX || > > + (reg_val !=3D 1 && reg_val !=3D 0)) > > + return -EINVAL; > > + > > + for (i =3D 0; i < ARRAY_SIZE(sbi_ext); i++) { > > + if (sbi_ext[i].dis_idx =3D=3D reg_num) { > > + sext =3D &sbi_ext[i]; > > + break; > > + } > > + } > > + if (!sext) > > + return -ENOENT; > > + > > + scontext->extension_disabled[sext->dis_idx] =3D !reg_val; > > + > > + return 0; > > +} > > + > > +static int riscv_vcpu_get_sbi_ext_single(struct kvm_vcpu *vcpu, > > + unsigned long reg_num, > > + unsigned long *reg_val) > > +{ > > + unsigned long i; > > + const struct kvm_riscv_sbi_extension_entry *sext =3D NULL; > > + struct kvm_vcpu_sbi_context *scontext =3D &vcpu->arch.sbi_context= ; > > + > > + if (reg_num >=3D KVM_RISCV_SBI_EXT_MAX) > > + return -EINVAL; > > + > > + for (i =3D 0; i < ARRAY_SIZE(sbi_ext); i++) { > > + if (sbi_ext[i].dis_idx =3D=3D reg_num) { > > + sext =3D &sbi_ext[i]; > > + break; > > + } > > + } > > + if (!sext) > > + return -ENOENT; > > + > > + *reg_val =3D !scontext->extension_disabled[sext->dis_idx]; > > + > > + return 0; > > +} > > + > > +static int riscv_vcpu_set_sbi_ext_multi(struct kvm_vcpu *vcpu, > > + unsigned long reg_num, > > + unsigned long reg_val, bool enabl= e) > > +{ > > + unsigned long i, ext_id; > > + > > + if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST) > > + return -EINVAL; > > + > > + for_each_set_bit(i, ®_val, BITS_PER_LONG) { > > + ext_id =3D i + reg_num * BITS_PER_LONG; > > + if (ext_id >=3D KVM_RISCV_SBI_EXT_MAX) > > + break; > > + > > + riscv_vcpu_set_sbi_ext_single(vcpu, ext_id, enable); > > + } > > + > > + return 0; > > +} > > + > > +static int riscv_vcpu_get_sbi_ext_multi(struct kvm_vcpu *vcpu, > > + unsigned long reg_num, > > + unsigned long *reg_val) > > +{ > > + unsigned long i, ext_id, ext_val; > > + > > + if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST) > > + return -EINVAL; > > + > > + for (i =3D 0; i < BITS_PER_LONG; i++) { > > + ext_id =3D i + reg_num * BITS_PER_LONG; > > + if (ext_id >=3D KVM_RISCV_SBI_EXT_MAX) > > + break; > > + > > + ext_val =3D 0; > > + riscv_vcpu_get_sbi_ext_single(vcpu, ext_id, &ext_val); > > + if (ext_val) > > + *reg_val |=3D KVM_REG_RISCV_SBI_MULTI_MASK(ext_id= ); > > + } > > + > > + return 0; > > +} > > + > > +int kvm_riscv_vcpu_set_reg_sbi_ext(struct kvm_vcpu *vcpu, > > + const struct kvm_one_reg *reg) > > +{ > > + unsigned long __user *uaddr =3D > > + (unsigned long __user *)(unsigned long)reg->addr; > > + unsigned long reg_num =3D reg->id & ~(KVM_REG_ARCH_MASK | > > + KVM_REG_SIZE_MASK | > > + KVM_REG_RISCV_SBI_EXT); > > + unsigned long reg_val, reg_subtype; > > + > > + if (KVM_REG_SIZE(reg->id) !=3D sizeof(unsigned long)) > > + return -EINVAL; > > + > > + if (vcpu->arch.ran_atleast_once) > > + return -EBUSY; > > + > > + reg_subtype =3D reg_num & KVM_REG_RISCV_SUBTYPE_MASK; > > + reg_num &=3D ~KVM_REG_RISCV_SUBTYPE_MASK; > > + > > + if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id))) > > + return -EFAULT; > > + > > + switch (reg_subtype) { > > + case KVM_REG_RISCV_SBI_SINGLE: > > + return riscv_vcpu_set_sbi_ext_single(vcpu, reg_num, reg_v= al); > > + case KVM_REG_RISCV_SBI_MULTI_EN: > > + return riscv_vcpu_set_sbi_ext_multi(vcpu, reg_num, reg_va= l, true); > > + case KVM_REG_RISCV_SBI_MULTI_DIS: > > + return riscv_vcpu_set_sbi_ext_multi(vcpu, reg_num, reg_va= l, false); > > + default: > > + return -EINVAL; > > + }; > > + > > + return 0; > > +} > > + > > +int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu, > > + const struct kvm_one_reg *reg) > > +{ > > + int rc; > > + unsigned long __user *uaddr =3D > > + (unsigned long __user *)(unsigned long)reg->addr; > > + unsigned long reg_num =3D reg->id & ~(KVM_REG_ARCH_MASK | > > + KVM_REG_SIZE_MASK | > > + KVM_REG_RISCV_SBI_EXT); > > + unsigned long reg_val, reg_subtype; > > + > > + if (KVM_REG_SIZE(reg->id) !=3D sizeof(unsigned long)) > > + return -EINVAL; > > + > > + reg_subtype =3D reg_num & KVM_REG_RISCV_SUBTYPE_MASK; > > + reg_num &=3D ~KVM_REG_RISCV_SUBTYPE_MASK; > > + > > + reg_val =3D 0; > > + switch (reg_subtype) { > > + case KVM_REG_RISCV_SBI_SINGLE: > > + rc =3D riscv_vcpu_get_sbi_ext_single(vcpu, reg_num, ®_= val); > > + break; > > + case KVM_REG_RISCV_SBI_MULTI_EN: > > + case KVM_REG_RISCV_SBI_MULTI_DIS: > > + rc =3D riscv_vcpu_get_sbi_ext_multi(vcpu, reg_num, ®_v= al); > > It seems odd that a user calling GET(KVM_REG_RISCV_SBI_MULTI_DIS) will ge= t > all the enabled extensions. Okay, let's return bit mask of disabled extensions for GET(KVM_REG_RISCV_SBI_MULTI_DIS). > > > + break; > > + default: > > + rc =3D -EINVAL; > > + }; > > + if (rc) > > + return rc; > > + > > + if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id))) > > + return -EFAULT; > > + > > + return 0; > > +} > > + > > +const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext( > > + struct kvm_vcpu *vcpu, unsigned long exti= d) > > { > > - int i =3D 0; > > + int i; > > + const struct kvm_riscv_sbi_extension_entry *sext; > > + struct kvm_vcpu_sbi_context *scontext =3D &vcpu->arch.sbi_context= ; > > > > for (i =3D 0; i < ARRAY_SIZE(sbi_ext); i++) { > > - if (sbi_ext[i]->extid_start <=3D extid && > > - sbi_ext[i]->extid_end >=3D extid) > > - return sbi_ext[i]; > > + sext =3D &sbi_ext[i]; > > + if (sext->ext_ptr->extid_start <=3D extid && > > + sext->ext_ptr->extid_end >=3D extid) { > > + if (sext->dis_idx < KVM_RISCV_SBI_EXT_MAX && > > + scontext->extension_disabled[sext->dis_idx]) > > + return NULL; > > + return sbi_ext[i].ext_ptr; > > + } > > } > > > > return NULL; > > @@ -126,7 +337,7 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu,= struct kvm_run *run) > > }; > > bool ext_is_v01 =3D false; > > > > - sbi_ext =3D kvm_vcpu_sbi_find_ext(cp->a7); > > + sbi_ext =3D kvm_vcpu_sbi_find_ext(vcpu, cp->a7); > > if (sbi_ext && sbi_ext->handler) { > > #ifdef CONFIG_RISCV_SBI_V01 > > if (cp->a7 >=3D SBI_EXT_0_1_SET_TIMER && > > diff --git a/arch/riscv/kvm/vcpu_sbi_base.c b/arch/riscv/kvm/vcpu_sbi_b= ase.c > > index 9945aff34c14..5bc570b984f4 100644 > > --- a/arch/riscv/kvm/vcpu_sbi_base.c > > +++ b/arch/riscv/kvm/vcpu_sbi_base.c > > @@ -44,7 +44,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *= vcpu, struct kvm_run *run, > > kvm_riscv_vcpu_sbi_forward(vcpu, run); > > retdata->uexit =3D true; > > } else { > > - sbi_ext =3D kvm_vcpu_sbi_find_ext(cp->a0); > > + sbi_ext =3D kvm_vcpu_sbi_find_ext(vcpu, cp->a0); > > *out_val =3D sbi_ext && sbi_ext->probe ? > > sbi_ext->probe(vcpu) : !!sbi_e= xt; > > } > > -- > > 2.34.1 > > > > Thanks, > drew Regards, Anup