Unverified Commit e2b6bc28 authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

Merge patch series "riscv: cbo.zero fixes"

Samuel Holland <samuel.holland@sifive.com> says:

This series fixes a couple of issues related to using the cbo.zero
instruction in userspace. The first patch fixes a bug where the wrong
enable bit gets set if the kernel is running in M-mode. The remaining
patches fix a bug where the enable bit gets reset to its default value
after a nonretentive idle state. I have hardware which reproduces this:

Before this series:
  $ tools/testing/selftests/riscv/hwprobe/cbo
  TAP version 13
  1..3
  ok 1 Zicboz block size
  # Zicboz block size: 64
  Illegal instruction

After applying this series:
  $ tools/testing/selftests/riscv/hwprobe/cbo
  TAP version 13
  1..3
  ok 1 Zicboz block size
  # Zicboz block size: 64
  ok 2 cbo.zero
  ok 3 cbo.zero check
  # Totals: pass:3 fail:0 xfail:0 xpass:0 skip:0 error:0

* b4-shazam-merge:
  riscv: Save/restore envcfg CSR during CPU suspend
  riscv: Add a custom ISA extension for the [ms]envcfg CSR
  riscv: Fix enabling cbo.zero when running in M-mode

Link: https://lore.kernel.org/r/20240228065559.3434837-1-samuel.holland@sifive.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parents 34b56786 05ab803d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -424,6 +424,7 @@
# define CSR_STATUS	CSR_MSTATUS
# define CSR_IE		CSR_MIE
# define CSR_TVEC	CSR_MTVEC
# define CSR_ENVCFG	CSR_MENVCFG
# define CSR_SCRATCH	CSR_MSCRATCH
# define CSR_EPC	CSR_MEPC
# define CSR_CAUSE	CSR_MCAUSE
@@ -448,6 +449,7 @@
# define CSR_STATUS	CSR_SSTATUS
# define CSR_IE		CSR_SIE
# define CSR_TVEC	CSR_STVEC
# define CSR_ENVCFG	CSR_SENVCFG
# define CSR_SCRATCH	CSR_SSCRATCH
# define CSR_EPC	CSR_SEPC
# define CSR_CAUSE	CSR_SCAUSE
+2 −0
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@
#define RISCV_ISA_EXT_ZTSO		72
#define RISCV_ISA_EXT_ZACAS		73

#define RISCV_ISA_EXT_XLINUXENVCFG	127

#define RISCV_ISA_EXT_MAX		128
#define RISCV_ISA_EXT_INVALID		U32_MAX

+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ struct suspend_context {
	struct pt_regs regs;
	/* Saved and restored by high-level functions */
	unsigned long scratch;
	unsigned long envcfg;
	unsigned long tvec;
	unsigned long ie;
#ifdef CONFIG_MMU
+13 −3
Original line number Diff line number Diff line
@@ -202,6 +202,16 @@ static const unsigned int riscv_zvbb_exts[] = {
	RISCV_ISA_EXT_ZVKB
};

/*
 * While the [ms]envcfg CSRs were not defined until version 1.12 of the RISC-V
 * privileged ISA, the existence of the CSRs is implied by any extension which
 * specifies [ms]envcfg bit(s). Hence, we define a custom ISA extension for the
 * existence of the CSR, and treat it as a subset of those other extensions.
 */
static const unsigned int riscv_xlinuxenvcfg_exts[] = {
	RISCV_ISA_EXT_XLINUXENVCFG
};

/*
 * The canonical order of ISA extension names in the ISA string is defined in
 * chapter 27 of the unprivileged specification.
@@ -251,8 +261,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
	__RISCV_ISA_EXT_DATA(c, RISCV_ISA_EXT_c),
	__RISCV_ISA_EXT_DATA(v, RISCV_ISA_EXT_v),
	__RISCV_ISA_EXT_DATA(h, RISCV_ISA_EXT_h),
	__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
	__RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ),
	__RISCV_ISA_EXT_SUPERSET(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts),
	__RISCV_ISA_EXT_SUPERSET(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts),
	__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
	__RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
	__RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR),
@@ -965,7 +975,7 @@ arch_initcall(check_unaligned_access_all_cpus);
void riscv_user_isa_enable(void)
{
	if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
		csr_set(CSR_SENVCFG, ENVCFG_CBZE);
		csr_set(CSR_ENVCFG, ENVCFG_CBZE);
}

#ifdef CONFIG_RISCV_ALTERNATIVE
+4 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
void suspend_save_csrs(struct suspend_context *context)
{
	context->scratch = csr_read(CSR_SCRATCH);
	if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
		context->envcfg = csr_read(CSR_ENVCFG);
	context->tvec = csr_read(CSR_TVEC);
	context->ie = csr_read(CSR_IE);

@@ -36,6 +38,8 @@ void suspend_save_csrs(struct suspend_context *context)
void suspend_restore_csrs(struct suspend_context *context)
{
	csr_write(CSR_SCRATCH, context->scratch);
	if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
		csr_write(CSR_ENVCFG, context->envcfg);
	csr_write(CSR_TVEC, context->tvec);
	csr_write(CSR_IE, context->ie);