On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <[email protected]> wrote:
>
> Divide the monolithic SBI FWFT (Firmware Features) register list into
> separate sublists, each testing a specific FWFT feature independently
> with proper dependency checking.
>
> Previously, all FWFT features were tested together in a single sublist.
> This caused issues because:
> 1. Not all FWFT features are available on all platforms
> 2. Some features depend on specific ISA extensions (e.g., pointer_masking
> requires Smnpm)
> 3. Tests would fail if any single feature was unavailable
>
> Add the feature-specific SBI FWFT sublists with the following
> improvements:
> - Add check_fwft_feature() helper to verify FWFT feature availability
>   at runtime
> - Update filter_reg() to handle per-feature FWFT register filtering
>
> Signed-off-by: Yong-Xuan Wang <[email protected]>

LGTM.

Reviewed-by: Anup Patel <[email protected]>

Thanks,
Anup

> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 60 
> ++++++++++++++++++++++--
>  1 file changed, 57 insertions(+), 3 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c 
> b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 5033c09201ef..cb86cb6b3635 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -27,6 +27,7 @@ enum {
>  };
>
>  static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
> +static bool sbi_ext_enabled[KVM_RISCV_SBI_EXT_MAX];
>
>  bool filter_reg(__u64 reg)
>  {
> @@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | 
> KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | 
> KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
>                 return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
> +       /*
> +        * FWFT misaligned delegation registers are always visible when the 
> SBI FWFT
> +        * extension is enable and the host supports the misaligned 
> delegation.
> +        */
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | 
> KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | 
> KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | 
> KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
> +               return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
>         default:
>                 break;
>         }
> @@ -193,6 +202,27 @@ static int override_vector_reg_size(struct kvm_vcpu 
> *vcpu, struct vcpu_reg_subli
>         return 0;
>  }
>
> +void check_fwft_feature(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s, 
> u64 feature)
> +{
> +       unsigned long value;
> +       int rc;
> +
> +       /* Enable SBI FWFT extension so that we can check the supported 
> register */
> +       rc = __vcpu_set_reg(vcpu, feature, 1);
> +       if (rc)
> +               return;
> +
> +       for (int i = 0; i < s->regs_n; i++) {
> +               if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == 
> KVM_REG_RISCV_SBI_STATE) {
> +                       rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
> +                       __TEST_REQUIRE(!rc, "%s not available, skipping 
> tests", s->name);
> +               }
> +       }
> +
> +       /* We should assert if disabling failed here while enabling succeeded 
> before */
> +       vcpu_set_reg(vcpu, feature, 0);
> +}
> +
>  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  {
>         unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> @@ -235,6 +265,9 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct 
> vcpu_reg_list *c)
>                         break;
>                 case VCPU_FEATURE_SBI_EXT:
>                         feature = RISCV_SBI_EXT_REG(s->feature);
> +                       if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
> +                               check_fwft_feature(vcpu, s, feature);
> +                       sbi_ext_enabled[s->feature] = true;
>                         break;
>                 default:
>                         TEST_FAIL("Unknown feature type");
> @@ -897,11 +930,15 @@ static __u64 sbi_sta_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | 
> KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
>  };
>
> -static __u64 sbi_fwft_regs[] = {
> +static __u64 sbi_fwft_misaligned_deleg_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | 
> KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | 
> KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | 
> KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | 
> KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value),
> +};
> +
> +static __u64 sbi_fwft_pointer_masking_regs[] = {
> +       KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | 
> KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | 
> KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | 
> KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | 
> KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
> @@ -1129,7 +1166,6 @@ KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
>  KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
>  KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
> -KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
>
>  KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
>  KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
> @@ -1206,6 +1242,23 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvksed, ZVKSED);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvksh, ZVKSH);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
>
> +static struct vcpu_reg_list config_sbi_fwft_misaligned_deleg = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_SBI(fwft_misaligned_deleg, FWFT),
> +               {0},
> +       },
> +};
> +
> +static struct vcpu_reg_list config_sbi_fwft_pointer_masking = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_ISA(smnpm, SMNPM),
> +               SUBLIST_SBI(fwft_pointer_masking, FWFT),
> +               {0},
> +       },
> +};
> +
>  struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_base,
>         &config_sbi_sta,
> @@ -1213,7 +1266,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_dbcn,
>         &config_sbi_susp,
>         &config_sbi_mpxy,
> -       &config_sbi_fwft,
> +       &config_sbi_fwft_misaligned_deleg,
> +       &config_sbi_fwft_pointer_masking,
>         &config_aia,
>         &config_fp_f,
>         &config_fp_d,
>
> --
> 2.43.7
>

Reply via email to