[kvm-unit-tests PATCH 7/7] riscv: Add BRS SBI requirement tests

Xiang W wangxiang at iscas.ac.cn
Tue Oct 6 06:03:03 PDT 2026


在 2026-09-30三的 13:19 +0200,Andrew Jones写道:
> On Thu, Sep 24, 2026 at 11:39:45AM +0800, Xiang W wrote:
> > Add a riscv-brs unit test for the SBI rules in the RISC-V Boot and
> > Runtime Services specification:
> > 
> >   SBI_010  spec version must be v2.0 or later
> >   SBI_020  HSM must be implemented
> >   SBI_030  TIME is required unless Sstc is present
> >   SBI_040  IPI is required unless Ssaia is present
> >   SBI_050  RFENCE is required unless Ssaia is present
> >   SBI_060  PMU is required unless Smcsrind, Sscsrind, Smcdeleg
> >            and Ssccfg are all present
> >   SBI_070  DBCN is required when ACPI SPCR Interface Type is 0x15
> > 
> > Parse the extra ISA names used as skip conditions, and add the RFNC
> > and PMU extension IDs needed to probe those extensions.
> > 
> > Signed-off-by: Xiang W <wangxiang at iscas.ac.cn>
> > ---
> >  lib/riscv/asm/isa.h |   5 ++
> >  lib/riscv/asm/sbi.h |   2 +
> >  lib/riscv/isa.c     |  14 +++-
> >  riscv/Makefile      |   1 +
> >  riscv/riscv-brs.c   | 171 ++++++++++++++++++++++++++++++++++++++++++++
> >  riscv/unittests.cfg |   4 ++
> >  6 files changed, 195 insertions(+), 2 deletions(-)
> >  create mode 100644 riscv/riscv-brs.c
> > 
> > diff --git a/lib/riscv/asm/isa.h b/lib/riscv/asm/isa.h
> > index fb3af67d..8a124881 100644
> > --- a/lib/riscv/asm/isa.h
> > +++ b/lib/riscv/asm/isa.h
> > @@ -13,7 +13,12 @@
> >   * by name not tracked here with cpu_has_extension_name()
> >   */
> >  enum {
> > +	ISA_SMCDELEG,
> > +	ISA_SMCSRIND,
> 
> I'm not sure we should expect machine level ISA extensions to be in the
> S-mode ISA string.
> 
> Indeed the spec says
> 
> """
> The Performance Monitoring Extension (PMU) MUST be implemented, if the
> counter delegation-related S-Mode ISA extensions (Sscsrind [13] and Ssccfg [14])
> are not present.
> """
> 
> So I'm not sure why you're looking for the M-mode extensions at all.
https://github.com/riscv-non-isa/riscv-brs/blob/main/brs_tests.adoc
OE_SBI_060_010:
  . If Smcsrind,Sscsrind,Smcdeleg,Ssccfg extensions were present(See ME_HR_010_010). ..
  Report Smcsrind,Sscsrind,Smcdeleg,Ssccfg was present and Skip the test. . Else ..
  Probe the presence of PMU extension by sbi_probe_extension(). ..
  Verify that the result is true.
> 
> > +	ISA_SSAIA,
> > +	ISA_SSCCFG,
> >  	ISA_SSTC,
> > +	ISA_SSCSRIND,
> >  	ISA_MAX,
> >  };
> >  __static_assert(ISA_MAX <= __riscv_xlen, "Need to increase thread_info.isa");
> > diff --git a/lib/riscv/asm/sbi.h b/lib/riscv/asm/sbi.h
> > index 289a6a24..c92a66dc 100644
> > --- a/lib/riscv/asm/sbi.h
> > +++ b/lib/riscv/asm/sbi.h
> > @@ -45,8 +45,10 @@ enum sbi_ext_id {
> >  	SBI_EXT_BASE = 0x10,
> >  	SBI_EXT_TIME = 0x54494d45,
> >  	SBI_EXT_IPI = 0x735049,
> > +	SBI_EXT_RFNC = 0x52464E43,
> >  	SBI_EXT_HSM = 0x48534d,
> >  	SBI_EXT_SRST = 0x53525354,
> > +	SBI_EXT_PMU = 0x504D55,
> >  	SBI_EXT_DBCN = 0x4442434E,
> >  	SBI_EXT_SUSP = 0x53555350,
> >  	SBI_EXT_FWFT = 0x46574654,
> > diff --git a/lib/riscv/isa.c b/lib/riscv/isa.c
> > index b0257979..f5e2a61b 100644
> > --- a/lib/riscv/isa.c
> > +++ b/lib/riscv/isa.c
> > @@ -39,8 +39,18 @@ static void isa_bit(const char *name, int len, void *data)
> >  {
> >  	struct thread_info *info = (struct thread_info *)data;
> >  
> > -	if (isa_match("sstc", name, len))
> > -		set_bit(ISA_SSTC, info->isa);
> > +#define ISA_MATCH_AND_SET(ext) \
> > +	if (isa_match(#ext, name, len)) \
> > +		set_bit(ISA_##ext, info->isa)
> > +
> > +	ISA_MATCH_AND_SET(SMCDELEG);
> > +	ISA_MATCH_AND_SET(SMCSRIND);
> > +	ISA_MATCH_AND_SET(SSAIA);
> > +	ISA_MATCH_AND_SET(SSCCFG);
> > +	ISA_MATCH_AND_SET(SSCSRIND);
> > +	ISA_MATCH_AND_SET(SSTC);
> > +
> > +#undef ISA_MATCH_AND_SET
> >  }
> >  
> >  static void isa_parse(const char *isa_string, int len, struct isa_info *info)
> > diff --git a/riscv/Makefile b/riscv/Makefile
> > index 348a30a7..7da7526f 100644
> > --- a/riscv/Makefile
> > +++ b/riscv/Makefile
> > @@ -15,6 +15,7 @@ tests += $(TEST_DIR)/sbi.$(exe)
> >  tests += $(TEST_DIR)/selftest.$(exe)
> >  tests += $(TEST_DIR)/sieve.$(exe)
> >  tests += $(TEST_DIR)/isa-dbltrp.$(exe)
> > +tests += $(TEST_DIR)/riscv-brs.$(exe)
> >  
> >  all: $(tests)
> >  
> > diff --git a/riscv/riscv-brs.c b/riscv/riscv-brs.c
> > new file mode 100644
> > index 00000000..0d4a8f47
> > --- /dev/null
> > +++ b/riscv/riscv-brs.c
> > @@ -0,0 +1,171 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + *  RISC-V BRS SBI requirement tests
> > + *
> > + * Copyright (C) 2026, Institute of Software, CAS., Xiang W <wangxiang at iscas.ac.cn>
> > + */
> > +
> > +#include <libcflat.h>
> > +#include <devicetree.h>
> > +#include <asm/sbi.h>
> > +#include <asm/isa.h>
> > +#include <asm/smp.h>
> > +
> > +#ifdef CONFIG_EFI
> > +#include <acpi.h>
> > +#endif
> > +
> > +static void check_sbi_010(void)
> > +{
> > +	struct sbiret ret;
> > +
> > +	report_prefix_push("SBI_010");
> > +
> > +	ret = sbi_get_spec_version();
> > +	if (ret.error) {
> > +		report_fail("sbi_get_spec_version failed with %ld", ret.error);
> > +		report_prefix_pop();
> > +		return;
> > +	}
> > +
> > +	report_info("SBI spec version %lu.%lu",
> > +		    (ret.value >> SBI_SPEC_VERSION_MAJOR_SHIFT) &
> > +		    SBI_SPEC_VERSION_MAJOR_MASK,
> > +		    ret.value & SBI_SPEC_VERSION_MINOR_MASK);
> > +
> > +	report(ret.value >= sbi_mk_version(2, 0),
> > +	       "SBI spec version is v2.0 or later");
> > +
> > +	report_prefix_pop();
> > +}
> > +
> > +static void check_sbi_020(void)
> > +{
> > +	report_prefix_push("SBI_020");
> > +	report(sbi_probe(SBI_EXT_HSM), "HSM extension is implemented");
> > +	report_prefix_pop();
> > +}
> > +
> > +static void check_sbi_030(void)
> > +{
> > +	report_prefix_push("SBI_030");
> > +
> > +	if (cpu_has_extension(smp_processor_id(), ISA_SSTC)) {
> > +		report_skip("Sstc is present, TIME is not mandated");
> > +		report_prefix_pop();
> > +		return;
> > +	}
> > +
> > +	report(sbi_probe(SBI_EXT_TIME), "TIME extension is implemented");
> > +	report_prefix_pop();
> > +}
> > +
> > +static void check_sbi_040(void)
> > +{
> > +	report_prefix_push("SBI_040");
> > +
> > +	if (cpu_has_extension(smp_processor_id(), ISA_SSAIA)) {
> 
> I'm not sure this is a sufficient check. IIRC, the IMSIC is an optional
> feature of the AIA and the BRS rule states:
> 
> """
> The S-Mode IPI Extension (sPI) MUST be implemented, if the Incoming MSI
> Controller (IMSIC, [12]) is not available.
> """
> 
> I think we should check both ISA_SSAIA and ensure each hart has a nonzero
> acpi_madt_rintc.imsic_size. (And, unless, I'm mistaken, the BRS SBI rules
> apply to both BRS-I and BRS-B, so we should implement a DT equivalent
> IMSIC check too.)
> 
https://github.com/riscv-non-isa/riscv-brs/blob/main/brs_tests.adoc
OE_SBI_040_010:
  . If Ssaia extension was present(See ME_HR_010_010) .. Report Ssaia was 
  present and Skip the test. . Else .. Probe the presence of sPI extension 
  by sbi_probe_extension(). .. Verify that the result is true.
> 
> > +		report_skip("Ssaia is present, IPI is not mandated");
> > +		report_prefix_pop();
> > +		return;
> > +	}
> > +
> > +	report(sbi_probe(SBI_EXT_IPI), "IPI extension is implemented");
> > +	report_prefix_pop();
> > +}
> > +
> > +static void check_sbi_050(void)
> > +{
> > +	report_prefix_push("SBI_050");
> > +
> > +	if (cpu_has_extension(smp_processor_id(), ISA_SSAIA)) {
> > +		report_skip("Ssaia is present, RFENCE is not mandated");
> > +		report_prefix_pop();
> > +		return;
> > +	}
> > +
> > +	report(sbi_probe(SBI_EXT_RFNC), "RFENCE extension is implemented");
> > +	report_prefix_pop();
> > +}
> > +
> > +static void check_sbi_060(void)
> > +{
> > +	int cpu = smp_processor_id();
> > +	bool skip = true;
> > +	bool has_ext;
> > +
> > +	report_prefix_push("SBI_060");
> > +
> > +	has_ext = cpu_has_extension(cpu, ISA_SMCSRIND);
> > +	if (!has_ext)
> > +		report_info("Smcsrind is not present");
> > +	skip &= has_ext;
> > +
> > +	has_ext = cpu_has_extension(cpu, ISA_SSCSRIND);
> > +	if (!has_ext)
> > +		report_info("Sscsrind is not present");
> > +	skip &= has_ext;
> > +
> > +	has_ext = cpu_has_extension(cpu, ISA_SMCDELEG);
> > +	if (!has_ext)
> > +		report_info("Smcdeleg is not present");
> > +	skip &= has_ext;
> > +
> > +	has_ext = cpu_has_extension(cpu, ISA_SSCCFG);
> > +	if (!has_ext)
> > +		report_info("Ssccfg is not present");
> > +	skip &= has_ext;
> > +
> > +	if (skip) {
> > +		report_skip("Smcsrind, Sscsrind, Smcdeleg and Ssccfg are present, PMU is not mandated");
> > +		report_prefix_pop();
> > +		return;
> > +	}
> > +
> > +	report(sbi_probe(SBI_EXT_PMU), "PMU extension is implemented");
> > +	report_prefix_pop();
> > +}
> > +
> > +static void check_sbi_070(void)
> > +{
> > +	report_prefix_push("SBI_070");
> > +
> > +#ifdef CONFIG_EFI
> > +	if (!dt_available()) {
> > +		struct spcr_descriptor *spcr;
> > +
> > +		spcr = find_acpi_table_addr(SPCR_SIGNATURE);
> > +		if (spcr) {
> > +			report_info("SPCR interface type is %#x", spcr->interface_type);
> > +			if (spcr->interface_type == 0x15) {
> > +				report(sbi_probe(SBI_EXT_DBCN), "DBCN extension is implemented");
> > +				report_prefix_pop();
> > +				return;
> > +			}
> > +			report_skip("SPCR interface type is not 0x15, DBCN is not mandated");
> > +			report_prefix_pop();
> > +			return;
> > +		}
> > +		report_skip("SPCR is not present, DBCN is not mandated");
> > +		report_prefix_pop();
> > +		return;
> 
> nit: could use a goto to get rid of the repeated
> 
>   report_prefix_pop();
>   return;
> 
> lines.
> 
> > +	}
> > +#endif
> > +	report_skip("ACPI not available, DBCN is not mandated");
> > +	report_prefix_pop();
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > +	report_prefix_push("riscv-brs");
> > +
> > +	check_sbi_010();
> > +	check_sbi_020();
> > +	check_sbi_030();
> > +	check_sbi_040();
> > +	check_sbi_050();
> > +	check_sbi_060();
> > +	check_sbi_070();
> > +
> > +	return report_summary();
> > +}
> > diff --git a/riscv/unittests.cfg b/riscv/unittests.cfg
> > index 9e9f58d9..990f03db 100644
> > --- a/riscv/unittests.cfg
> > +++ b/riscv/unittests.cfg
> > @@ -22,3 +22,7 @@ groups = sbi
> >  [dbltrp]
> >  file = isa-dbltrp.flat
> >  groups = isa sbi
> > +
> > +[riscv-brs]
> > +file = riscv-brs.flat
> > +groups = riscv-brs nodefault
> > -- 
> > 2.47.3
> > 
> 
> Thanks,
> drew
drew
  Sorry, my previous reply went only to you. Resending to the list.




More information about the kvm-riscv mailing list