mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
riscv: Decouple emulated unaligned accesses from access speed
Detecting if a system traps into the kernel on an unaligned access can be performed separately from checking the speed of unaligned accesses. This decoupling will make it possible to selectively enable or disable each of these checks. Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Tested-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20240308-disable_misaligned_probe_config-v9-3-a388770ba0ce@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Change-Id: Ibdd387fc1a9729ef272901fef77db90cb5f1dd0c
This commit is contained in:
parent
429f0d5a78
commit
2f19d7b882
3 changed files with 36 additions and 12 deletions
|
@ -33,6 +33,32 @@ extern struct riscv_isainfo hart_isa[NR_CPUS];
|
||||||
|
|
||||||
void riscv_user_isa_enable(void);
|
void riscv_user_isa_enable(void);
|
||||||
|
|
||||||
|
#if defined(CONFIG_RISCV_MISALIGNED)
|
||||||
|
bool check_unaligned_access_emulated_all_cpus(void);
|
||||||
|
void unaligned_emulation_finish(void);
|
||||||
|
bool unaligned_ctl_available(void);
|
||||||
|
DECLARE_PER_CPU(long, misaligned_access_speed);
|
||||||
|
#else
|
||||||
|
static inline bool unaligned_ctl_available(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS)
|
||||||
|
DECLARE_STATIC_KEY_FALSE(fast_unaligned_access_speed_key);
|
||||||
|
static __always_inline bool has_fast_unaligned_accesses(void)
|
||||||
|
{
|
||||||
|
return static_branch_likely(&fast_unaligned_access_speed_key);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static __always_inline bool has_fast_unaligned_accesses(void)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
unsigned long riscv_get_elf_hwcap(void);
|
unsigned long riscv_get_elf_hwcap(void);
|
||||||
|
|
||||||
struct riscv_isa_ext_data {
|
struct riscv_isa_ext_data {
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
#include <linux/sched/task_stack.h>
|
#include <linux/sched/task_stack.h>
|
||||||
#include <linux/sched/mm.h>
|
#include <linux/sched/mm.h>
|
||||||
|
|
||||||
#include <asm/cpufeature.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/cpu_ops.h>
|
#include <asm/cpu_ops.h>
|
||||||
#include <asm/cpufeature.h>
|
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/numa.h>
|
#include <asm/numa.h>
|
||||||
|
@ -247,8 +246,7 @@ asmlinkage __visible void smp_callin(void)
|
||||||
riscv_ipi_enable();
|
riscv_ipi_enable();
|
||||||
|
|
||||||
numa_add_cpu(curr_cpuid);
|
numa_add_cpu(curr_cpuid);
|
||||||
check_unaligned_access(curr_cpuid);
|
set_cpu_online(curr_cpuid, true);
|
||||||
set_cpu_online(curr_cpuid, 1);
|
|
||||||
|
|
||||||
if (has_vector()) {
|
if (has_vector()) {
|
||||||
if (riscv_v_setup_vsize())
|
if (riscv_v_setup_vsize())
|
||||||
|
@ -261,6 +259,7 @@ asmlinkage __visible void smp_callin(void)
|
||||||
* Remote TLB flushes are ignored while the CPU is offline, so emit
|
* Remote TLB flushes are ignored while the CPU is offline, so emit
|
||||||
* a local TLB flush right now just in case.
|
* a local TLB flush right now just in case.
|
||||||
*/
|
*/
|
||||||
|
local_flush_icache_all();
|
||||||
local_flush_tlb_all();
|
local_flush_tlb_all();
|
||||||
complete(&cpu_running);
|
complete(&cpu_running);
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -600,7 +600,7 @@ int handle_misaligned_store(struct pt_regs *regs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_unaligned_access_emulated(int cpu)
|
static bool check_unaligned_access_emulated(int cpu)
|
||||||
{
|
{
|
||||||
long *mas_ptr = per_cpu_ptr(&misaligned_access_speed, cpu);
|
long *mas_ptr = per_cpu_ptr(&misaligned_access_speed, cpu);
|
||||||
unsigned long tmp_var, tmp_val;
|
unsigned long tmp_var, tmp_val;
|
||||||
|
@ -627,7 +627,7 @@ bool check_unaligned_access_emulated(int cpu)
|
||||||
return misaligned_emu_detected;
|
return misaligned_emu_detected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unaligned_emulation_finish(void)
|
bool check_unaligned_access_emulated_all_cpus(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
|
@ -636,13 +636,12 @@ void unaligned_emulation_finish(void)
|
||||||
* accesses emulated since tasks requesting such control can run on any
|
* accesses emulated since tasks requesting such control can run on any
|
||||||
* CPU.
|
* CPU.
|
||||||
*/
|
*/
|
||||||
for_each_present_cpu(cpu) {
|
for_each_online_cpu(cpu)
|
||||||
if (per_cpu(misaligned_access_speed, cpu) !=
|
if (!check_unaligned_access_emulated(cpu))
|
||||||
RISCV_HWPROBE_MISALIGNED_EMULATED) {
|
return false;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unaligned_ctl = true;
|
unaligned_ctl = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unaligned_ctl_available(void)
|
bool unaligned_ctl_available(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue