On Mon, Mar 17, 2025 at 06:06:09PM +0100, Clément Léger wrote:
This SBI extensions enables supervisor mode to control feature that are under M-mode control (For instance, Svadu menvcfg ADUE bit, Ssdbltrp DTE, etc). Add an interface to set local features for a specific cpu mask as well as for the online cpu mask.
Signed-off-by: Clément Léger cleger@rivosinc.com
arch/riscv/include/asm/sbi.h | 20 +++++++++++ arch/riscv/kernel/sbi.c | 69 ++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+)
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index d11d22717b49..1cecfa82c2e5 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -503,6 +503,26 @@ int sbi_remote_hfence_vvma_asid(const struct cpumask *cpu_mask, unsigned long asid); long sbi_probe_extension(int ext); +int sbi_fwft_local_set_cpumask(const cpumask_t *mask, u32 feature,
unsigned long value, unsigned long flags);
+/**
- sbi_fwft_local_set() - Set a feature on all online cpus
- @feature: The feature to be set
- @value: The feature value to be set
- @flags: FWFT feature set flags
- Return: 0 on success, appropriate linux error code otherwise.
- */
- static inline int sbi_fwft_local_set(u32 feature, unsigned long value,
unsigned long flags)
- {
return sbi_fwft_local_set_cpumask(cpu_online_mask, feature, value,
flags);
Let flags stick out. We have 100 chars.
- }
+int sbi_fwft_get(u32 feature, unsigned long *value); +int sbi_fwft_set(u32 feature, unsigned long value, unsigned long flags);
/* Check if current SBI specification version is 0.1 or not */ static inline int sbi_spec_is_0_1(void) { diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index 1989b8cade1b..d41a5642be24 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -299,6 +299,75 @@ static int __sbi_rfence_v02(int fid, const struct cpumask *cpu_mask, return 0; } +/**
- sbi_fwft_get() - Get a feature for the local hart
- @feature: The feature ID to be set
- @value: Will contain the feature value on success
- Return: 0 on success, appropriate linux error code otherwise.
- */
+int sbi_fwft_get(u32 feature, unsigned long *value) +{
- return -EOPNOTSUPP;
+}
+/**
- sbi_fwft_set() - Set a feature on the local hart
- @feature: The feature ID to be set
- @value: The feature value to be set
- @flags: FWFT feature set flags
- Return: 0 on success, appropriate linux error code otherwise.
- */
+int sbi_fwft_set(u32 feature, unsigned long value, unsigned long flags) +{
- return -EOPNOTSUPP;
+}
+struct fwft_set_req {
- u32 feature;
- unsigned long value;
- unsigned long flags;
- atomic_t error;
+};
+static void cpu_sbi_fwft_set(void *arg) +{
- struct fwft_set_req *req = arg;
- int ret;
- ret = sbi_fwft_set(req->feature, req->value, req->flags);
- if (ret)
atomic_set(&req->error, ret);
+}
+/**
- sbi_fwft_local_set() - Set a feature for the specified cpumask
sbi_fwft_local_set_cpumask
- @mask: CPU mask of cpus that need the feature to be set
- @feature: The feature ID to be set
- @value: The feature value to be set
- @flags: FWFT feature set flags
- Return: 0 on success, appropriate linux error code otherwise.
- */
+int sbi_fwft_local_set_cpumask(const cpumask_t *mask, u32 feature,
unsigned long value, unsigned long flags)
+{
- struct fwft_set_req req = {
.feature = feature,
.value = value,
.flags = flags,
.error = ATOMIC_INIT(0),
- };
- if (feature & SBI_FWFT_GLOBAL_FEATURE_BIT)
return -EINVAL;
- on_each_cpu_mask(mask, cpu_sbi_fwft_set, &req, 1);
- return atomic_read(&req.error);
+}
/**
- sbi_set_timer() - Program the timer for next timer event.
- @stime_value: The value after which next timer event should fire.
-- 2.47.2
Otherwise,
Reviewed-by: Andrew Jones ajones@ventanamicro.com