Skip to content

Commit fd56e51

Browse files
committed
Merge tag 'for-linus' of https://github.com/openrisc/linux
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
2 parents 0f8e26b + ea1413e commit fd56e51

File tree

16 files changed

+816
-7
lines changed

16 files changed

+816
-7
lines changed

arch/openrisc/Kbuild

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
22
obj-y += lib/ kernel/ mm/
3-
obj-y += boot/dts/
43

54
# for cleaning
65
subdir- += boot

arch/openrisc/Kconfig

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ config OPENRISC
1010
select ARCH_HAS_DMA_SET_UNCACHED
1111
select ARCH_HAS_DMA_CLEAR_UNCACHED
1212
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
13+
select GENERIC_BUILTIN_DTB
1314
select COMMON_CLK
1415
select OF
1516
select OF_EARLY_FLATTREE
@@ -26,6 +27,8 @@ config OPENRISC
2627
select HAVE_PCI
2728
select HAVE_UID16
2829
select HAVE_PAGE_SIZE_8KB
30+
select HAVE_REGS_AND_STACK_ACCESS_API
31+
select HAVE_RSEQ
2932
select GENERIC_ATOMIC64
3033
select GENERIC_CLOCKEVENTS_BROADCAST
3134
select GENERIC_SMP_IDLE_THREAD
@@ -92,7 +95,7 @@ config DCACHE_WRITETHROUGH
9295

9396
If unsure say N here
9497

95-
config OPENRISC_BUILTIN_DTB
98+
config BUILTIN_DTB_NAME
9699
string "Builtin DTB"
97100
default ""
98101

arch/openrisc/boot/dts/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0
2-
obj-y += $(addsuffix .dtb.o, $(CONFIG_OPENRISC_BUILTIN_DTB))
2+
dtb-y += $(addsuffix .dtb, $(CONFIG_BUILTIN_DTB_NAME))
33

44
#DTC_FLAGS ?= -p 1024

arch/openrisc/configs/or1klitex_defconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ CONFIG_BLK_DEV_INITRD=y
77
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
88
CONFIG_SGETMASK_SYSCALL=y
99
CONFIG_EXPERT=y
10-
CONFIG_OPENRISC_BUILTIN_DTB="or1klitex"
10+
CONFIG_BUILTIN_DTB_NAME="or1klitex"
1111
CONFIG_HZ_100=y
1212
CONFIG_OPENRISC_HAVE_SHADOW_GPRS=y
1313
CONFIG_NET=y

arch/openrisc/configs/or1ksim_defconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ CONFIG_SLUB=y
1414
CONFIG_SLUB_TINY=y
1515
CONFIG_MODULES=y
1616
# CONFIG_BLOCK is not set
17-
CONFIG_OPENRISC_BUILTIN_DTB="or1ksim"
17+
CONFIG_BUILTIN_DTB_NAME="or1ksim"
1818
CONFIG_HZ_100=y
1919
CONFIG_NET=y
2020
CONFIG_PACKET=y

arch/openrisc/configs/simple_smp_defconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ CONFIG_SLUB=y
2020
CONFIG_SLUB_TINY=y
2121
CONFIG_MODULES=y
2222
# CONFIG_BLOCK is not set
23-
CONFIG_OPENRISC_BUILTIN_DTB="simple_smp"
23+
CONFIG_BUILTIN_DTB_NAME="simple_smp"
2424
CONFIG_SMP=y
2525
CONFIG_HZ_100=y
2626
CONFIG_OPENRISC_HAVE_SHADOW_GPRS=y

arch/openrisc/include/asm/ptrace.h

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <asm/spr_defs.h>
1919
#include <uapi/asm/ptrace.h>
20+
#include <linux/compiler.h>
2021

2122
/*
2223
* Make kernel PTrace/register structures opaque to userspace... userspace can
@@ -42,6 +43,36 @@ struct pt_regs {
4243
/* Named registers */
4344
long sr; /* Stored in place of r0 */
4445
long sp; /* r1 */
46+
long gpr2;
47+
long gpr3;
48+
long gpr4;
49+
long gpr5;
50+
long gpr6;
51+
long gpr7;
52+
long gpr8;
53+
long gpr9;
54+
long gpr10;
55+
long gpr11;
56+
long gpr12;
57+
long gpr13;
58+
long gpr14;
59+
long gpr15;
60+
long gpr16;
61+
long gpr17;
62+
long gpr18;
63+
long gpr19;
64+
long gpr20;
65+
long gpr21;
66+
long gpr22;
67+
long gpr23;
68+
long gpr24;
69+
long gpr25;
70+
long gpr26;
71+
long gpr27;
72+
long gpr28;
73+
long gpr29;
74+
long gpr30;
75+
long gpr31;
4576
};
4677
struct {
4778
/* Old style */
@@ -66,16 +97,56 @@ struct pt_regs {
6697
/* TODO: Rename this to REDZONE because that's what it is */
6798
#define STACK_FRAME_OVERHEAD 128 /* size of minimum stack frame */
6899

69-
#define instruction_pointer(regs) ((regs)->pc)
100+
#define MAX_REG_OFFSET offsetof(struct pt_regs, orig_gpr11)
101+
102+
/* Helpers for working with the instruction pointer */
103+
static inline unsigned long instruction_pointer(struct pt_regs *regs)
104+
{
105+
return (unsigned long)regs->pc;
106+
}
107+
static inline void instruction_pointer_set(struct pt_regs *regs,
108+
unsigned long val)
109+
{
110+
regs->pc = val;
111+
}
112+
70113
#define user_mode(regs) (((regs)->sr & SPR_SR_SM) == 0)
71114
#define user_stack_pointer(regs) ((unsigned long)(regs)->sp)
72115
#define profile_pc(regs) instruction_pointer(regs)
73116

117+
/* Valid only for Kernel mode traps. */
118+
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
119+
{
120+
return (unsigned long)regs->sp;
121+
}
122+
74123
static inline long regs_return_value(struct pt_regs *regs)
75124
{
76125
return regs->gpr[11];
77126
}
78127

128+
extern int regs_query_register_offset(const char *name);
129+
extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
130+
unsigned int n);
131+
132+
/**
133+
* regs_get_register() - get register value from its offset
134+
* @regs: pt_regs from which register value is gotten
135+
* @offset: offset of the register.
136+
*
137+
* regs_get_register returns the value of a register whose offset from @regs.
138+
* The @offset is the offset of the register in struct pt_regs.
139+
* If @offset is bigger than MAX_REG_OFFSET, this returns 0.
140+
*/
141+
static inline unsigned long regs_get_register(struct pt_regs *regs,
142+
unsigned int offset)
143+
{
144+
if (unlikely(offset > MAX_REG_OFFSET))
145+
return 0;
146+
147+
return *(unsigned long *)((unsigned long)regs + offset);
148+
}
149+
79150
#endif /* __ASSEMBLY__ */
80151

81152
/*

arch/openrisc/kernel/entry.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,10 @@ _syscall_check_trace_leave:
714714
* interrupts that set NEED_RESCHED or SIGNALPENDING... really true? */
715715

716716
_syscall_check_work:
717+
#ifdef CONFIG_DEBUG_RSEQ
718+
l.jal rseq_syscall
719+
l.ori r3,r1,0
720+
#endif
717721
/* Here we need to disable interrupts */
718722
DISABLE_INTERRUPTS(r27,r29)
719723
TRACE_IRQS_OFF

arch/openrisc/kernel/ptrace.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,102 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
160160
* in exit.c or in signal.c.
161161
*/
162162

163+
struct pt_regs_offset {
164+
const char *name;
165+
int offset;
166+
};
167+
168+
#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
169+
#define REG_OFFSET_END {.name = NULL, .offset = 0}
170+
171+
static const struct pt_regs_offset regoffset_table[] = {
172+
REG_OFFSET_NAME(sr),
173+
REG_OFFSET_NAME(sp),
174+
REG_OFFSET_NAME(gpr2),
175+
REG_OFFSET_NAME(gpr3),
176+
REG_OFFSET_NAME(gpr4),
177+
REG_OFFSET_NAME(gpr5),
178+
REG_OFFSET_NAME(gpr6),
179+
REG_OFFSET_NAME(gpr7),
180+
REG_OFFSET_NAME(gpr8),
181+
REG_OFFSET_NAME(gpr9),
182+
REG_OFFSET_NAME(gpr10),
183+
REG_OFFSET_NAME(gpr11),
184+
REG_OFFSET_NAME(gpr12),
185+
REG_OFFSET_NAME(gpr13),
186+
REG_OFFSET_NAME(gpr14),
187+
REG_OFFSET_NAME(gpr15),
188+
REG_OFFSET_NAME(gpr16),
189+
REG_OFFSET_NAME(gpr17),
190+
REG_OFFSET_NAME(gpr18),
191+
REG_OFFSET_NAME(gpr19),
192+
REG_OFFSET_NAME(gpr20),
193+
REG_OFFSET_NAME(gpr21),
194+
REG_OFFSET_NAME(gpr22),
195+
REG_OFFSET_NAME(gpr23),
196+
REG_OFFSET_NAME(gpr24),
197+
REG_OFFSET_NAME(gpr25),
198+
REG_OFFSET_NAME(gpr26),
199+
REG_OFFSET_NAME(gpr27),
200+
REG_OFFSET_NAME(gpr28),
201+
REG_OFFSET_NAME(gpr29),
202+
REG_OFFSET_NAME(gpr30),
203+
REG_OFFSET_NAME(gpr31),
204+
REG_OFFSET_NAME(pc),
205+
REG_OFFSET_NAME(orig_gpr11),
206+
REG_OFFSET_END,
207+
};
208+
209+
/**
210+
* regs_query_register_offset() - query register offset from its name
211+
* @name: the name of a register
212+
*
213+
* regs_query_register_offset() returns the offset of a register in struct
214+
* pt_regs from its name. If the name is invalid, this returns -EINVAL;
215+
*/
216+
int regs_query_register_offset(const char *name)
217+
{
218+
const struct pt_regs_offset *roff;
219+
220+
for (roff = regoffset_table; roff->name != NULL; roff++)
221+
if (!strcmp(roff->name, name))
222+
return roff->offset;
223+
return -EINVAL;
224+
}
225+
226+
/**
227+
* regs_within_kernel_stack() - check the address in the stack
228+
* @regs: pt_regs which contains kernel stack pointer.
229+
* @addr: address which is checked.
230+
*
231+
* regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
232+
* If @addr is within the kernel stack, it returns true. If not, returns false.
233+
*/
234+
static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
235+
{
236+
return (addr & ~(THREAD_SIZE - 1)) ==
237+
(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1));
238+
}
239+
240+
/**
241+
* regs_get_kernel_stack_nth() - get Nth entry of the stack
242+
* @regs: pt_regs which contains kernel stack pointer.
243+
* @n: stack entry number.
244+
*
245+
* regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
246+
* is specified by @regs. If the @n th entry is NOT in the kernel stack,
247+
* this returns 0.
248+
*/
249+
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
250+
{
251+
unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
252+
253+
addr += n;
254+
if (regs_within_kernel_stack(regs, (unsigned long)addr))
255+
return *addr;
256+
else
257+
return 0;
258+
}
163259

164260
/*
165261
* Called by kernel/ptrace.c when detaching..

arch/openrisc/kernel/signal.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
244244
{
245245
int ret;
246246

247+
rseq_signal_deliver(ksig, regs);
248+
247249
ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
248250

249251
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));

tools/testing/selftests/rseq/param_test.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,32 @@ unsigned int yield_mod_cnt, nr_abort;
226226
"addi " INJECT_ASM_REG "," INJECT_ASM_REG ", -1\n\t" \
227227
"bnez " INJECT_ASM_REG ", 222b\n\t" \
228228
"333:\n\t"
229+
#elif defined(__or1k__)
229230

231+
#define RSEQ_INJECT_INPUT \
232+
, [loop_cnt_1]"m"(loop_cnt[1]) \
233+
, [loop_cnt_2]"m"(loop_cnt[2]) \
234+
, [loop_cnt_3]"m"(loop_cnt[3]) \
235+
, [loop_cnt_4]"m"(loop_cnt[4]) \
236+
, [loop_cnt_5]"m"(loop_cnt[5]) \
237+
, [loop_cnt_6]"m"(loop_cnt[6])
230238

239+
#define INJECT_ASM_REG "r31"
240+
241+
#define RSEQ_INJECT_CLOBBER \
242+
, INJECT_ASM_REG
243+
244+
#define RSEQ_INJECT_ASM(n) \
245+
"l.lwz " INJECT_ASM_REG ", %[loop_cnt_" #n "]\n\t" \
246+
"l.sfeqi " INJECT_ASM_REG ", 0\n\t" \
247+
"l.bf 333f\n\t" \
248+
" l.nop\n\t" \
249+
"222:\n\t" \
250+
"l.addi " INJECT_ASM_REG "," INJECT_ASM_REG ", -1\n\t" \
251+
"l.sfeqi " INJECT_ASM_REG ", 0\n\t" \
252+
"l.bf 222f\n\t" \
253+
" l.nop\n\t" \
254+
"333:\n\t"
231255
#else
232256
#error unsupported target
233257
#endif

0 commit comments

Comments
 (0)