[PATCH 1/3] RISC-V: Framework for vendor extensions

Charlie Jenkins charlie at rivosinc.com
Wed Jul 5 20:30:17 PDT 2023


Create Kconfig files, Makefiles, and functions to enable vendors to
provide information via the riscv_hwprobe syscall about which vendor
extensions are available.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/Kbuild                     |  1 +
 arch/riscv/Kconfig                    |  1 +
 arch/riscv/Kconfig.vendor             |  3 +++
 arch/riscv/include/asm/hwprobe.h      |  1 +
 arch/riscv/kernel/sys_riscv.c         | 40 ++++++++++++++++++++++++++++++++---
 arch/riscv/vendor_extensions/Makefile |  3 +++
 6 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/Kbuild b/arch/riscv/Kbuild
index afa83e307a2e..bea38010d9db 100644
--- a/arch/riscv/Kbuild
+++ b/arch/riscv/Kbuild
@@ -3,6 +3,7 @@
 obj-y += kernel/ mm/ net/
 obj-$(CONFIG_BUILTIN_DTB) += boot/dts/
 obj-y += errata/
+obj-y += vendor_extensions/
 obj-$(CONFIG_KVM) += kvm/
 
 obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += purgatory/
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index c1505c7729ec..19404ede0ee3 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -276,6 +276,7 @@ config AS_HAS_OPTION_ARCH
 
 source "arch/riscv/Kconfig.socs"
 source "arch/riscv/Kconfig.errata"
+source "arch/riscv/Kconfig.vendor"
 
 menu "Platform type"
 
diff --git a/arch/riscv/Kconfig.vendor b/arch/riscv/Kconfig.vendor
new file mode 100644
index 000000000000..213ac3e6fed5
--- /dev/null
+++ b/arch/riscv/Kconfig.vendor
@@ -0,0 +1,3 @@
+menu "Vendor extensions selection"
+
+endmenu # "Vendor extensions selection"
diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
index 78936f4ff513..fadb38b83243 100644
--- a/arch/riscv/include/asm/hwprobe.h
+++ b/arch/riscv/include/asm/hwprobe.h
@@ -9,5 +9,6 @@
 #include <uapi/asm/hwprobe.h>
 
 #define RISCV_HWPROBE_MAX_KEY 5
+#define RISCV_HWPROBE_VENDOR_EXTENSION_SPACE (UL(1)<<63)
 
 #endif
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index 26ef5526bfb4..2351a5f7b8b1 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -188,9 +188,35 @@ static u64 hwprobe_misaligned(const struct cpumask *cpus)
 	return perf;
 }
 
+static int hwprobe_vendor(__u64 mvendorid, struct riscv_hwprobe *pair,
+			 const struct cpumask *cpus)
+{
+	switch (mvendorid) {
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 static void hwprobe_one_pair(struct riscv_hwprobe *pair,
 			     const struct cpumask *cpus)
 {
+	int err;
+
+	if (((unsigned long) pair->key) >= RISCV_HWPROBE_VENDOR_EXTENSION_SPACE) {
+		struct riscv_hwprobe mvendorid = {
+			.key = RISCV_HWPROBE_KEY_MVENDORID,
+			.value = 0
+		};
+
+		hwprobe_arch_id(&mvendorid, cpus);
+		if (mvendorid.value != -1ULL)
+			err = hwprobe_vendor(mvendorid.value, pair, cpus);
+		else
+			err = -1;
+	}
+
 	switch (pair->key) {
 	case RISCV_HWPROBE_KEY_MVENDORID:
 	case RISCV_HWPROBE_KEY_MARCHID:
@@ -217,13 +243,21 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
 
 	/*
 	 * For forward compatibility, unknown keys don't fail the whole
-	 * call, but get their element key set to -1 and value set to 0
-	 * indicating they're unrecognized.
+	 * call, instead an error is raised to indicate the element key
+	 * is unrecognized.
 	 */
 	default:
+		err = -1;
+		break;
+	}
+
+	/*
+	 * Setting the element key to -1 and value to 0 indicates that
+	 * hwprobe was unable to find the requested key.
+	 */
+	if (err != 0) {
 		pair->key = -1;
 		pair->value = 0;
-		break;
 	}
 }
 
diff --git a/arch/riscv/vendor_extensions/Makefile b/arch/riscv/vendor_extensions/Makefile
new file mode 100644
index 000000000000..e815895e9372
--- /dev/null
+++ b/arch/riscv/vendor_extensions/Makefile
@@ -0,0 +1,3 @@
+ifdef CONFIG_RELOCATABLE
+KBUILD_CFLAGS += -fno-pie
+endif

-- 
2.41.0




More information about the linux-riscv mailing list