Unverified Commit 0619ff9f authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

Merge patch series "Add support to handle misaligned accesses in S-mode"

Clément Léger <cleger@rivosinc.com> says:

Since commit 61cadb9 ("Provide new description of misaligned load/store
behavior compatible with privileged architecture.") in the RISC-V ISA
manual, it is stated that misaligned load/store might not be supported.
However, the RISC-V kernel uABI describes that misaligned accesses are
supported. In order to support that, this series adds support for S-mode
handling of misaligned accesses as well support for prctl(PR_UNALIGN).

Handling misaligned access in kernel allows for a finer grain control
of the misaligned accesses behavior, and thanks to the prctl() call,
can allow disabling misaligned access emulation to generate SIGBUS. User
space can then optimize its software by removing such access based on
SIGBUS generation.

This series is useful when using a SBI implementation that does not
handle misaligned traps as well as detecting misaligned accesses
generated by userspace application using the prctrl(PR_SET_UNALIGN)
feature.

This series can be tested using the spike simulator[1] and a modified
openSBI version[2] which allows to always delegate misaligned load/store to
S-mode. A test[3] that exercise various instructions/registers can be
executed to verify the unaligned access support.

[1] https://github.com/riscv-software-src/riscv-isa-sim
[2] https://github.com/rivosinc/opensbi/tree/dev/cleger/no_misaligned
[3] https://github.com/clementleger/unaligned_test

* b4-shazam-merge:
  riscv: add support for PR_SET_UNALIGN and PR_GET_UNALIGN
  riscv: report misaligned accesses emulation to hwprobe
  riscv: annotate check_unaligned_access_boot_cpu() with __init
  riscv: add support for sysctl unaligned_enabled control
  riscv: add floating point insn support to misaligned access emulation
  riscv: report perf event for misaligned fault
  riscv: add support for misaligned trap handling in S-mode
  riscv: remove unused functions in traps_misaligned.c

Link: https://lore.kernel.org/r/20231004151405.521596-1-cleger@rivosinc.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parents e1c05b3b 9f23a5d2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -643,6 +643,15 @@ config THREAD_SIZE_ORDER
	  Specify the Pages of thread stack size (from 4KB to 64KB), which also
	  affects irq stack size, which is equal to thread stack size.

config RISCV_MISALIGNED
	bool "Support misaligned load/store traps for kernel and userspace"
	select SYSCTL_ARCH_UNALIGN_ALLOW
	default y
	help
	  Say Y here if you want the kernel to embed support for misaligned
	  load/store for both kernel and userspace. When disable, misaligned
	  accesses will generate SIGBUS in userspace and panic in kernel.

endmenu # "Platform type"

menu "Kernel features"
+18 −0
Original line number Diff line number Diff line
@@ -33,4 +33,22 @@ extern struct riscv_isainfo hart_isa[NR_CPUS];
void check_unaligned_access(int cpu);
void riscv_user_isa_enable(void);

#ifdef CONFIG_RISCV_MISALIGNED
bool unaligned_ctl_available(void);
bool check_unaligned_access_emulated(int cpu);
void unaligned_emulation_finish(void);
#else
static inline bool unaligned_ctl_available(void)
{
	return false;
}

static inline bool check_unaligned_access_emulated(int cpu)
{
	return false;
}

static inline void unaligned_emulation_finish(void) {}
#endif

#endif
+14 −0
Original line number Diff line number Diff line
@@ -8,4 +8,18 @@
void handle_page_fault(struct pt_regs *regs);
void handle_break(struct pt_regs *regs);

#ifdef CONFIG_RISCV_MISALIGNED
int handle_misaligned_load(struct pt_regs *regs);
int handle_misaligned_store(struct pt_regs *regs);
#else
static inline int handle_misaligned_load(struct pt_regs *regs)
{
	return -1;
}
static inline int handle_misaligned_store(struct pt_regs *regs)
{
	return -1;
}
#endif

#endif /* _ASM_RISCV_ENTRY_COMMON_H */
+9 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@

#include <linux/const.h>
#include <linux/cache.h>
#include <linux/prctl.h>

#include <vdso/processor.h>

@@ -82,6 +83,7 @@ struct thread_struct {
	unsigned long bad_cause;
	unsigned long vstate_ctrl;
	struct __riscv_v_ext_state vstate;
	unsigned long align_ctl;
};

/* Whitelist the fstate from the task_struct for hardened usercopy */
@@ -94,6 +96,7 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,

#define INIT_THREAD {					\
	.sp = sizeof(init_stack) + (long)&init_stack,	\
	.align_ctl = PR_UNALIGN_NOPRINT,		\
}

#define task_pt_regs(tsk)						\
@@ -134,6 +137,12 @@ extern long riscv_v_vstate_ctrl_set_current(unsigned long arg);
extern long riscv_v_vstate_ctrl_get_current(void);
#endif /* CONFIG_RISCV_ISA_V */

extern int get_unalign_ctl(struct task_struct *tsk, unsigned long addr);
extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);

#define GET_UNALIGN_CTL(tsk, addr)	get_unalign_ctl((tsk), (addr))
#define SET_UNALIGN_CTL(tsk, val)	set_unalign_ctl((tsk), (val))

#endif /* __ASSEMBLY__ */

#endif /* _ASM_RISCV_PROCESSOR_H */
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ obj-y += patch.o
obj-y	+= probes/
obj-$(CONFIG_MMU) += vdso.o vdso/

obj-$(CONFIG_RISCV_M_MODE)	+= traps_misaligned.o
obj-$(CONFIG_RISCV_MISALIGNED)	+= traps_misaligned.o
obj-$(CONFIG_FPU)		+= fpu.o
obj-$(CONFIG_RISCV_ISA_V)	+= vector.o
obj-$(CONFIG_SMP)		+= smpboot.o
Loading