Unverified Commit 9c7646d5 authored by Andrew Jones's avatar Andrew Jones Committed by Palmer Dabbelt
Browse files

RISC-V: hwprobe: Expose Zicboz extension and its block size



Expose Zicboz through hwprobe and also provide a key to extract its
respective block size. Opportunistically add a macro and apply it to
current extensions in order to avoid duplicating code.

Signed-off-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Reviewed-by: default avatarEvan Green <evan@rivosinc.com>
Reviewed-by: default avatarConor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20230918131518.56803-11-ajones@ventanamicro.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 43c16d51
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -77,6 +77,9 @@ The following keys are defined:
  * :c:macro:`RISCV_HWPROBE_EXT_ZBS`: The Zbs extension is supported, as defined
       in version 1.0 of the Bit-Manipulation ISA extensions.

  * :c:macro:`RISCV_HWPROBE_EXT_ZICBOZ`: The Zicboz extension is supported, as
       ratified in commit 3dd606f ("Create cmobase-v1.0.pdf") of riscv-CMOs.

* :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: A bitmask that contains performance
  information about the selected set of processors.

@@ -96,3 +99,6 @@ The following keys are defined:

  * :c:macro:`RISCV_HWPROBE_MISALIGNED_UNSUPPORTED`: Misaligned accesses are
    not supported at all and will generate a misaligned address fault.

* :c:macro:`RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE`: An unsigned int which
  represents the size of the Zicboz block in bytes.
+1 −1
Original line number Diff line number Diff line
@@ -8,6 +8,6 @@

#include <uapi/asm/hwprobe.h>

#define RISCV_HWPROBE_MAX_KEY 5
#define RISCV_HWPROBE_MAX_KEY 6

#endif
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ struct riscv_hwprobe {
#define		RISCV_HWPROBE_EXT_ZBA		(1 << 3)
#define		RISCV_HWPROBE_EXT_ZBB		(1 << 4)
#define		RISCV_HWPROBE_EXT_ZBS		(1 << 5)
#define		RISCV_HWPROBE_EXT_ZICBOZ	(1 << 6)
#define RISCV_HWPROBE_KEY_CPUPERF_0	5
#define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
#define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
@@ -36,6 +37,7 @@ struct riscv_hwprobe {
#define		RISCV_HWPROBE_MISALIGNED_FAST		(3 << 0)
#define		RISCV_HWPROBE_MISALIGNED_UNSUPPORTED	(4 << 0)
#define		RISCV_HWPROBE_MISALIGNED_MASK		(7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE	6
/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */

#endif
+32 −14
Original line number Diff line number Diff line
@@ -145,26 +145,38 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
	for_each_cpu(cpu, cpus) {
		struct riscv_isainfo *isainfo = &hart_isa[cpu];

		if (riscv_isa_extension_available(isainfo->isa, ZBA))
			pair->value |= RISCV_HWPROBE_EXT_ZBA;
		else
			missing |= RISCV_HWPROBE_EXT_ZBA;

		if (riscv_isa_extension_available(isainfo->isa, ZBB))
			pair->value |= RISCV_HWPROBE_EXT_ZBB;
		else
			missing |= RISCV_HWPROBE_EXT_ZBB;

		if (riscv_isa_extension_available(isainfo->isa, ZBS))
			pair->value |= RISCV_HWPROBE_EXT_ZBS;
		else
			missing |= RISCV_HWPROBE_EXT_ZBS;
#define EXT_KEY(ext)									\
	do {										\
		if (__riscv_isa_extension_available(isainfo->isa, RISCV_ISA_EXT_##ext))	\
			pair->value |= RISCV_HWPROBE_EXT_##ext;				\
		else									\
			missing |= RISCV_HWPROBE_EXT_##ext;				\
	} while (false)

		/*
		 * Only use EXT_KEY() for extensions which can be exposed to userspace,
		 * regardless of the kernel's configuration, as no other checks, besides
		 * presence in the hart_isa bitmap, are made.
		 */
		EXT_KEY(ZBA);
		EXT_KEY(ZBB);
		EXT_KEY(ZBS);
		EXT_KEY(ZICBOZ);
#undef EXT_KEY
	}

	/* Now turn off reporting features if any CPU is missing it. */
	pair->value &= ~missing;
}

static bool hwprobe_ext0_has(const struct cpumask *cpus, unsigned long ext)
{
	struct riscv_hwprobe pair;

	hwprobe_isa_ext0(&pair, cpus);
	return (pair.value & ext);
}

static u64 hwprobe_misaligned(const struct cpumask *cpus)
{
	int cpu;
@@ -215,6 +227,12 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
		pair->value = hwprobe_misaligned(cpus);
		break;

	case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
		pair->value = 0;
		if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
			pair->value = riscv_cboz_block_size;
		break;

	/*
	 * For forward compatibility, unknown keys don't fail the whole
	 * call, but get their element key set to -1 and value set to 0