mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 22:22:08 +02:00
riscv: sbi: add FWFT extension interface
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> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Atish Patra <atishp@rivosinc.com> Link: https://lore.kernel.org/r/20250523101932.1594077-5-cleger@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
This commit is contained in:
parent
99cf5b7c73
commit
6d6d0641dc
|
|
@ -503,6 +503,23 @@ int sbi_remote_hfence_vvma_asid(const struct cpumask *cpu_mask,
|
|||
unsigned long asid);
|
||||
long sbi_probe_extension(int ext);
|
||||
|
||||
int sbi_fwft_set(u32 feature, unsigned long value, unsigned long flags);
|
||||
int sbi_fwft_set_cpumask(const cpumask_t *mask, u32 feature,
|
||||
unsigned long value, unsigned long flags);
|
||||
/**
|
||||
* sbi_fwft_set_online_cpus() - 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_set_online_cpus(u32 feature, unsigned long value,
|
||||
unsigned long flags)
|
||||
{
|
||||
return sbi_fwft_set_cpumask(cpu_online_mask, feature, value, flags);
|
||||
}
|
||||
|
||||
/* Check if current SBI specification version is 0.1 or not */
|
||||
static inline int sbi_spec_is_0_1(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -299,6 +299,63 @@ static int __sbi_rfence_v02(int fid, const struct cpumask *cpu_mask,
|
|||
return 0;
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* sbi_fwft_set_cpumask() - Set a feature for the specified 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_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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user