Skip to content

Commit

Permalink
Merge tag 'for-linus' of https://github.com/openrisc/linux
Browse files Browse the repository at this point in the history
Pull OpenRISC updates from Stafford Horne:

 - Added support for restartable sequences (me)

 - Migration to Generic built-in DTB (Masahiro Yamada)

* tag 'for-linus' of https://github.com/openrisc/linux:
  rseq/selftests: Add support for OpenRISC
  openrisc: Add support for restartable sequences
  openrisc: Add HAVE_REGS_AND_STACK_ACCESS_API support
  openrisc: migrate to the generic rule for built-in DTB
  • Loading branch information
Linus Torvalds committed Jan 25, 2025
2 parents 0f8e26b + ea1413e commit fd56e51
Show file tree
Hide file tree
Showing 16 changed files with 816 additions and 7 deletions.
1 change: 0 additions & 1 deletion arch/openrisc/Kbuild
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += lib/ kernel/ mm/
obj-y += boot/dts/

# for cleaning
subdir- += boot
5 changes: 4 additions & 1 deletion arch/openrisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config OPENRISC
select ARCH_HAS_DMA_SET_UNCACHED
select ARCH_HAS_DMA_CLEAR_UNCACHED
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select GENERIC_BUILTIN_DTB
select COMMON_CLK
select OF
select OF_EARLY_FLATTREE
Expand All @@ -26,6 +27,8 @@ config OPENRISC
select HAVE_PCI
select HAVE_UID16
select HAVE_PAGE_SIZE_8KB
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_RSEQ
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS_BROADCAST
select GENERIC_SMP_IDLE_THREAD
Expand Down Expand Up @@ -92,7 +95,7 @@ config DCACHE_WRITETHROUGH

If unsure say N here

config OPENRISC_BUILTIN_DTB
config BUILTIN_DTB_NAME
string "Builtin DTB"
default ""

Expand Down
2 changes: 1 addition & 1 deletion arch/openrisc/boot/dts/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += $(addsuffix .dtb.o, $(CONFIG_OPENRISC_BUILTIN_DTB))
dtb-y += $(addsuffix .dtb, $(CONFIG_BUILTIN_DTB_NAME))

#DTC_FLAGS ?= -p 1024
2 changes: 1 addition & 1 deletion arch/openrisc/configs/or1klitex_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_EXPERT=y
CONFIG_OPENRISC_BUILTIN_DTB="or1klitex"
CONFIG_BUILTIN_DTB_NAME="or1klitex"
CONFIG_HZ_100=y
CONFIG_OPENRISC_HAVE_SHADOW_GPRS=y
CONFIG_NET=y
Expand Down
2 changes: 1 addition & 1 deletion arch/openrisc/configs/or1ksim_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CONFIG_SLUB=y
CONFIG_SLUB_TINY=y
CONFIG_MODULES=y
# CONFIG_BLOCK is not set
CONFIG_OPENRISC_BUILTIN_DTB="or1ksim"
CONFIG_BUILTIN_DTB_NAME="or1ksim"
CONFIG_HZ_100=y
CONFIG_NET=y
CONFIG_PACKET=y
Expand Down
2 changes: 1 addition & 1 deletion arch/openrisc/configs/simple_smp_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ CONFIG_SLUB=y
CONFIG_SLUB_TINY=y
CONFIG_MODULES=y
# CONFIG_BLOCK is not set
CONFIG_OPENRISC_BUILTIN_DTB="simple_smp"
CONFIG_BUILTIN_DTB_NAME="simple_smp"
CONFIG_SMP=y
CONFIG_HZ_100=y
CONFIG_OPENRISC_HAVE_SHADOW_GPRS=y
Expand Down
73 changes: 72 additions & 1 deletion arch/openrisc/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <asm/spr_defs.h>
#include <uapi/asm/ptrace.h>
#include <linux/compiler.h>

/*
* Make kernel PTrace/register structures opaque to userspace... userspace can
Expand All @@ -42,6 +43,36 @@ struct pt_regs {
/* Named registers */
long sr; /* Stored in place of r0 */
long sp; /* r1 */
long gpr2;
long gpr3;
long gpr4;
long gpr5;
long gpr6;
long gpr7;
long gpr8;
long gpr9;
long gpr10;
long gpr11;
long gpr12;
long gpr13;
long gpr14;
long gpr15;
long gpr16;
long gpr17;
long gpr18;
long gpr19;
long gpr20;
long gpr21;
long gpr22;
long gpr23;
long gpr24;
long gpr25;
long gpr26;
long gpr27;
long gpr28;
long gpr29;
long gpr30;
long gpr31;
};
struct {
/* Old style */
Expand All @@ -66,16 +97,56 @@ struct pt_regs {
/* TODO: Rename this to REDZONE because that's what it is */
#define STACK_FRAME_OVERHEAD 128 /* size of minimum stack frame */

#define instruction_pointer(regs) ((regs)->pc)
#define MAX_REG_OFFSET offsetof(struct pt_regs, orig_gpr11)

/* Helpers for working with the instruction pointer */
static inline unsigned long instruction_pointer(struct pt_regs *regs)
{
return (unsigned long)regs->pc;
}
static inline void instruction_pointer_set(struct pt_regs *regs,
unsigned long val)
{
regs->pc = val;
}

#define user_mode(regs) (((regs)->sr & SPR_SR_SM) == 0)
#define user_stack_pointer(regs) ((unsigned long)(regs)->sp)
#define profile_pc(regs) instruction_pointer(regs)

/* Valid only for Kernel mode traps. */
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
{
return (unsigned long)regs->sp;
}

static inline long regs_return_value(struct pt_regs *regs)
{
return regs->gpr[11];
}

extern int regs_query_register_offset(const char *name);
extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
unsigned int n);

/**
* regs_get_register() - get register value from its offset
* @regs: pt_regs from which register value is gotten
* @offset: offset of the register.
*
* regs_get_register returns the value of a register whose offset from @regs.
* The @offset is the offset of the register in struct pt_regs.
* If @offset is bigger than MAX_REG_OFFSET, this returns 0.
*/
static inline unsigned long regs_get_register(struct pt_regs *regs,
unsigned int offset)
{
if (unlikely(offset > MAX_REG_OFFSET))
return 0;

return *(unsigned long *)((unsigned long)regs + offset);
}

#endif /* __ASSEMBLY__ */

/*
Expand Down
4 changes: 4 additions & 0 deletions arch/openrisc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,10 @@ _syscall_check_trace_leave:
* interrupts that set NEED_RESCHED or SIGNALPENDING... really true? */

_syscall_check_work:
#ifdef CONFIG_DEBUG_RSEQ
l.jal rseq_syscall
l.ori r3,r1,0
#endif
/* Here we need to disable interrupts */
DISABLE_INTERRUPTS(r27,r29)
TRACE_IRQS_OFF
Expand Down
96 changes: 96 additions & 0 deletions arch/openrisc/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,102 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
* in exit.c or in signal.c.
*/

struct pt_regs_offset {
const char *name;
int offset;
};

#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
#define REG_OFFSET_END {.name = NULL, .offset = 0}

static const struct pt_regs_offset regoffset_table[] = {
REG_OFFSET_NAME(sr),
REG_OFFSET_NAME(sp),
REG_OFFSET_NAME(gpr2),
REG_OFFSET_NAME(gpr3),
REG_OFFSET_NAME(gpr4),
REG_OFFSET_NAME(gpr5),
REG_OFFSET_NAME(gpr6),
REG_OFFSET_NAME(gpr7),
REG_OFFSET_NAME(gpr8),
REG_OFFSET_NAME(gpr9),
REG_OFFSET_NAME(gpr10),
REG_OFFSET_NAME(gpr11),
REG_OFFSET_NAME(gpr12),
REG_OFFSET_NAME(gpr13),
REG_OFFSET_NAME(gpr14),
REG_OFFSET_NAME(gpr15),
REG_OFFSET_NAME(gpr16),
REG_OFFSET_NAME(gpr17),
REG_OFFSET_NAME(gpr18),
REG_OFFSET_NAME(gpr19),
REG_OFFSET_NAME(gpr20),
REG_OFFSET_NAME(gpr21),
REG_OFFSET_NAME(gpr22),
REG_OFFSET_NAME(gpr23),
REG_OFFSET_NAME(gpr24),
REG_OFFSET_NAME(gpr25),
REG_OFFSET_NAME(gpr26),
REG_OFFSET_NAME(gpr27),
REG_OFFSET_NAME(gpr28),
REG_OFFSET_NAME(gpr29),
REG_OFFSET_NAME(gpr30),
REG_OFFSET_NAME(gpr31),
REG_OFFSET_NAME(pc),
REG_OFFSET_NAME(orig_gpr11),
REG_OFFSET_END,
};

/**
* regs_query_register_offset() - query register offset from its name
* @name: the name of a register
*
* regs_query_register_offset() returns the offset of a register in struct
* pt_regs from its name. If the name is invalid, this returns -EINVAL;
*/
int regs_query_register_offset(const char *name)
{
const struct pt_regs_offset *roff;

for (roff = regoffset_table; roff->name != NULL; roff++)
if (!strcmp(roff->name, name))
return roff->offset;
return -EINVAL;
}

/**
* regs_within_kernel_stack() - check the address in the stack
* @regs: pt_regs which contains kernel stack pointer.
* @addr: address which is checked.
*
* regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
* If @addr is within the kernel stack, it returns true. If not, returns false.
*/
static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
{
return (addr & ~(THREAD_SIZE - 1)) ==
(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1));
}

/**
* regs_get_kernel_stack_nth() - get Nth entry of the stack
* @regs: pt_regs which contains kernel stack pointer.
* @n: stack entry number.
*
* regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
* is specified by @regs. If the @n th entry is NOT in the kernel stack,
* this returns 0.
*/
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
{
unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);

addr += n;
if (regs_within_kernel_stack(regs, (unsigned long)addr))
return *addr;
else
return 0;
}

/*
* Called by kernel/ptrace.c when detaching..
Expand Down
2 changes: 2 additions & 0 deletions arch/openrisc/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
int ret;

rseq_signal_deliver(ksig, regs);

ret = setup_rt_frame(ksig, sigmask_to_save(), regs);

signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
Expand Down
24 changes: 24 additions & 0 deletions tools/testing/selftests/rseq/param_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,32 @@ unsigned int yield_mod_cnt, nr_abort;
"addi " INJECT_ASM_REG "," INJECT_ASM_REG ", -1\n\t" \
"bnez " INJECT_ASM_REG ", 222b\n\t" \
"333:\n\t"
#elif defined(__or1k__)

#define RSEQ_INJECT_INPUT \
, [loop_cnt_1]"m"(loop_cnt[1]) \
, [loop_cnt_2]"m"(loop_cnt[2]) \
, [loop_cnt_3]"m"(loop_cnt[3]) \
, [loop_cnt_4]"m"(loop_cnt[4]) \
, [loop_cnt_5]"m"(loop_cnt[5]) \
, [loop_cnt_6]"m"(loop_cnt[6])

#define INJECT_ASM_REG "r31"

#define RSEQ_INJECT_CLOBBER \
, INJECT_ASM_REG

#define RSEQ_INJECT_ASM(n) \
"l.lwz " INJECT_ASM_REG ", %[loop_cnt_" #n "]\n\t" \
"l.sfeqi " INJECT_ASM_REG ", 0\n\t" \
"l.bf 333f\n\t" \
" l.nop\n\t" \
"222:\n\t" \
"l.addi " INJECT_ASM_REG "," INJECT_ASM_REG ", -1\n\t" \
"l.sfeqi " INJECT_ASM_REG ", 0\n\t" \
"l.bf 222f\n\t" \
" l.nop\n\t" \
"333:\n\t"
#else
#error unsupported target
#endif
Expand Down
Loading

0 comments on commit fd56e51

Please sign in to comment.