diff options
Diffstat (limited to 'arch/riscv/kernel/sys_riscv.c')
| -rw-r--r-- | arch/riscv/kernel/sys_riscv.c | 52 | 
1 files changed, 45 insertions, 7 deletions
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c index 5db29683ebee..26ef5526bfb4 100644 --- a/arch/riscv/kernel/sys_riscv.c +++ b/arch/riscv/kernel/sys_riscv.c @@ -10,6 +10,7 @@  #include <asm/cpufeature.h>  #include <asm/hwprobe.h>  #include <asm/sbi.h> +#include <asm/vector.h>  #include <asm/switch_to.h>  #include <asm/uaccess.h>  #include <asm/unistd.h> @@ -121,6 +122,49 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,  	pair->value = id;  } +static void hwprobe_isa_ext0(struct riscv_hwprobe *pair, +			     const struct cpumask *cpus) +{ +	int cpu; +	u64 missing = 0; + +	pair->value = 0; +	if (has_fpu()) +		pair->value |= RISCV_HWPROBE_IMA_FD; + +	if (riscv_isa_extension_available(NULL, c)) +		pair->value |= RISCV_HWPROBE_IMA_C; + +	if (has_vector()) +		pair->value |= RISCV_HWPROBE_IMA_V; + +	/* +	 * Loop through and record extensions that 1) anyone has, and 2) anyone +	 * doesn't have. +	 */ +	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; +	} + +	/* Now turn off reporting features if any CPU is missing it. */ +	pair->value &= ~missing; +} +  static u64 hwprobe_misaligned(const struct cpumask *cpus)  {  	int cpu; @@ -164,13 +208,7 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,  		break;  	case RISCV_HWPROBE_KEY_IMA_EXT_0: -		pair->value = 0; -		if (has_fpu()) -			pair->value |= RISCV_HWPROBE_IMA_FD; - -		if (riscv_isa_extension_available(NULL, c)) -			pair->value |= RISCV_HWPROBE_IMA_C; - +		hwprobe_isa_ext0(pair, cpus);  		break;  	case RISCV_HWPROBE_KEY_CPUPERF_0:  |