Skip to content

Commit 6e5ce7f

Browse files
charlie-rivospalmer-dabbelt
authored andcommitted
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>
1 parent 313130c commit 6e5ce7f

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

arch/riscv/include/asm/cpufeature.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void riscv_user_isa_enable(void);
3737

3838
#ifdef CONFIG_RISCV_MISALIGNED
3939
bool unaligned_ctl_available(void);
40-
bool check_unaligned_access_emulated(int cpu);
40+
bool check_unaligned_access_emulated_all_cpus(void);
4141
void unaligned_emulation_finish(void);
4242
#else
4343
static inline bool unaligned_ctl_available(void)

arch/riscv/kernel/cpufeature.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,8 @@ static int check_unaligned_access(void *param)
719719
void *src;
720720
long speed = RISCV_HWPROBE_MISALIGNED_SLOW;
721721

722-
if (check_unaligned_access_emulated(cpu))
722+
if (IS_ENABLED(CONFIG_RISCV_MISALIGNED) &&
723+
per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN)
723724
return 0;
724725

725726
/* Make an unaligned destination buffer. */
@@ -896,8 +897,8 @@ static int riscv_offline_cpu(unsigned int cpu)
896897
return 0;
897898
}
898899

899-
/* Measure unaligned access on all CPUs present at boot in parallel. */
900-
static int check_unaligned_access_all_cpus(void)
900+
/* Measure unaligned access speed on all CPUs present at boot in parallel. */
901+
static int check_unaligned_access_speed_all_cpus(void)
901902
{
902903
unsigned int cpu;
903904
unsigned int cpu_count = num_possible_cpus();
@@ -935,7 +936,6 @@ static int check_unaligned_access_all_cpus(void)
935936
riscv_online_cpu, riscv_offline_cpu);
936937

937938
out:
938-
unaligned_emulation_finish();
939939
for_each_cpu(cpu, cpu_online_mask) {
940940
if (bufs[cpu])
941941
__free_pages(bufs[cpu], MISALIGNED_BUFFER_ORDER);
@@ -945,6 +945,23 @@ static int check_unaligned_access_all_cpus(void)
945945
return 0;
946946
}
947947

948+
#ifdef CONFIG_RISCV_MISALIGNED
949+
static int check_unaligned_access_all_cpus(void)
950+
{
951+
bool all_cpus_emulated = check_unaligned_access_emulated_all_cpus();
952+
953+
if (!all_cpus_emulated)
954+
return check_unaligned_access_speed_all_cpus();
955+
956+
return 0;
957+
}
958+
#else
959+
static int check_unaligned_access_all_cpus(void)
960+
{
961+
return check_unaligned_access_speed_all_cpus();
962+
}
963+
#endif
964+
948965
arch_initcall(check_unaligned_access_all_cpus);
949966

950967
void riscv_user_isa_enable(void)

arch/riscv/kernel/traps_misaligned.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ int handle_misaligned_store(struct pt_regs *regs)
596596
return 0;
597597
}
598598

599-
bool check_unaligned_access_emulated(int cpu)
599+
static bool check_unaligned_access_emulated(int cpu)
600600
{
601601
long *mas_ptr = per_cpu_ptr(&misaligned_access_speed, cpu);
602602
unsigned long tmp_var, tmp_val;
@@ -623,7 +623,7 @@ bool check_unaligned_access_emulated(int cpu)
623623
return misaligned_emu_detected;
624624
}
625625

626-
void unaligned_emulation_finish(void)
626+
bool check_unaligned_access_emulated_all_cpus(void)
627627
{
628628
int cpu;
629629

@@ -632,13 +632,12 @@ void unaligned_emulation_finish(void)
632632
* accesses emulated since tasks requesting such control can run on any
633633
* CPU.
634634
*/
635-
for_each_online_cpu(cpu) {
636-
if (per_cpu(misaligned_access_speed, cpu) !=
637-
RISCV_HWPROBE_MISALIGNED_EMULATED) {
638-
return;
639-
}
640-
}
635+
for_each_online_cpu(cpu)
636+
if (!check_unaligned_access_emulated(cpu))
637+
return false;
638+
641639
unaligned_ctl = true;
640+
return true;
642641
}
643642

644643
bool unaligned_ctl_available(void)

0 commit comments

Comments
 (0)