Skip to content

Commit 9ae24d5

Browse files
committed
Merge tag 's390-5.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Vasily Gorbik: - Add kretprobes framepointer verification and return address recovery in stacktrace. - Support control domain masks on custom zcrypt devices and filter admin requests. - Cleanup timer API usage. - Rework absolute lowcore access helpers. - Other various small improvements and fixes. * tag 's390-5.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (26 commits) s390/alternatives: avoid using jgnop mnemonic s390/pci: rename get_zdev_by_bus() to zdev_from_bus() s390/pci: improve zpci_dev reference counting s390/smp: use physical address for SIGP_SET_PREFIX command s390: cleanup timer API use s390/zcrypt: fix using the correct variable for sizeof() s390/vfio-ap: fix kernel doc and signature of group notifier functions s390/maccess: rework absolute lowcore accessors s390/smp: cleanup control register update routines s390/smp: cleanup target CPU callback starting s390/test_unwind: verify __kretprobe_trampoline is replaced s390/unwind: avoid duplicated unwinding entries for kretprobes s390/unwind: recover kretprobe modified return address in stacktrace s390/kprobes: enable kretprobes framepointer verification s390/test_unwind: extend kretprobe test s390/ap: adjust whitespace s390/ap: use insn format for new instructions s390/alternatives: use insn format for new instructions s390/alternatives: use instructions instead of byte patterns s390/traps: improve panic message for translation-specification exception ...
2 parents ba2d620 + faf7993 commit 9ae24d5

36 files changed

Lines changed: 296 additions & 192 deletions

arch/s390/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ config S390
5858
select ALTERNATE_USER_ADDRESS_SPACE
5959
select ARCH_32BIT_USTAT_F_TINODE
6060
select ARCH_BINFMT_ELF_STATE
61+
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
6162
select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM
6263
select ARCH_ENABLE_MEMORY_HOTREMOVE
6364
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2

arch/s390/include/asm/alternative-asm.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,15 @@
3737
* a 2-byte nop if the size of the area is not divisible by 6.
3838
*/
3939
.macro alt_pad_fill bytes
40-
.fill ( \bytes ) / 6, 6, 0xc0040000
41-
.fill ( \bytes ) % 6 / 4, 4, 0x47000000
42-
.fill ( \bytes ) % 6 % 4 / 2, 2, 0x0700
40+
.rept ( \bytes ) / 6
41+
brcl 0,0
42+
.endr
43+
.rept ( \bytes ) % 6 / 4
44+
nop
45+
.endr
46+
.rept ( \bytes ) % 6 % 4 / 2
47+
nopr
48+
.endr
4349
.endm
4450

4551
/*

arch/s390/include/asm/alternative.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,18 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
7171
".if " oldinstr_pad_len(num) " > 6\n" \
7272
"\tjg " e_oldinstr_pad_end "f\n" \
7373
"6620:\n" \
74-
"\t.fill (" oldinstr_pad_len(num) " - (6620b-662b)) / 2, 2, 0x0700\n" \
74+
"\t.rept (" oldinstr_pad_len(num) " - (6620b-662b)) / 2\n" \
75+
"\tnopr\n" \
7576
".else\n" \
76-
"\t.fill " oldinstr_pad_len(num) " / 6, 6, 0xc0040000\n" \
77-
"\t.fill " oldinstr_pad_len(num) " %% 6 / 4, 4, 0x47000000\n" \
78-
"\t.fill " oldinstr_pad_len(num) " %% 6 %% 4 / 2, 2, 0x0700\n" \
77+
"\t.rept " oldinstr_pad_len(num) " / 6\n" \
78+
"\t.brcl 0,0\n" \
79+
"\t.endr\n" \
80+
"\t.rept " oldinstr_pad_len(num) " %% 6 / 4\n" \
81+
"\tnop\n" \
82+
"\t.endr\n" \
83+
"\t.rept " oldinstr_pad_len(num) " %% 6 %% 4 / 2\n" \
84+
"\tnopr\n" \
85+
".endr\n" \
7986
".endif\n"
8087

8188
#define OLDINSTR(oldinstr, num) \

arch/s390/include/asm/ap.h

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ static inline bool ap_instructions_available(void)
6060
unsigned long reg1 = 0;
6161

6262
asm volatile(
63-
" lgr 0,%[reg0]\n" /* qid into gr0 */
64-
" lghi 1,0\n" /* 0 into gr1 */
65-
" lghi 2,0\n" /* 0 into gr2 */
66-
" .long 0xb2af0000\n" /* PQAP(TAPQ) */
67-
"0: la %[reg1],1\n" /* 1 into reg1 */
63+
" lgr 0,%[reg0]\n" /* qid into gr0 */
64+
" lghi 1,0\n" /* 0 into gr1 */
65+
" lghi 2,0\n" /* 0 into gr2 */
66+
" .insn rre,0xb2af0000,0,0\n" /* PQAP(TAPQ) */
67+
"0: la %[reg1],1\n" /* 1 into reg1 */
6868
"1:\n"
6969
EX_TABLE(0b, 1b)
7070
: [reg1] "+&d" (reg1)
@@ -86,11 +86,11 @@ static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
8686
unsigned long reg2;
8787

8888
asm volatile(
89-
" lgr 0,%[qid]\n" /* qid into gr0 */
90-
" lghi 2,0\n" /* 0 into gr2 */
91-
" .long 0xb2af0000\n" /* PQAP(TAPQ) */
92-
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
93-
" lgr %[reg2],2\n" /* gr2 into reg2 */
89+
" lgr 0,%[qid]\n" /* qid into gr0 */
90+
" lghi 2,0\n" /* 0 into gr2 */
91+
" .insn rre,0xb2af0000,0,0\n" /* PQAP(TAPQ) */
92+
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
93+
" lgr %[reg2],2\n" /* gr2 into reg2 */
9494
: [reg1] "=&d" (reg1), [reg2] "=&d" (reg2)
9595
: [qid] "d" (qid)
9696
: "cc", "0", "1", "2");
@@ -128,9 +128,9 @@ static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
128128
struct ap_queue_status reg1;
129129

130130
asm volatile(
131-
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
132-
" .long 0xb2af0000\n" /* PQAP(RAPQ) */
133-
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
131+
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
132+
" .insn rre,0xb2af0000,0,0\n" /* PQAP(RAPQ) */
133+
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
134134
: [reg1] "=&d" (reg1)
135135
: [reg0] "d" (reg0)
136136
: "cc", "0", "1");
@@ -149,9 +149,9 @@ static inline struct ap_queue_status ap_zapq(ap_qid_t qid)
149149
struct ap_queue_status reg1;
150150

151151
asm volatile(
152-
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
153-
" .long 0xb2af0000\n" /* PQAP(ZAPQ) */
154-
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
152+
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
153+
" .insn rre,0xb2af0000,0,0\n" /* PQAP(ZAPQ) */
154+
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
155155
: [reg1] "=&d" (reg1)
156156
: [reg0] "d" (reg0)
157157
: "cc", "0", "1");
@@ -190,10 +190,10 @@ static inline int ap_qci(struct ap_config_info *config)
190190
struct ap_config_info *reg2 = config;
191191

192192
asm volatile(
193-
" lgr 0,%[reg0]\n" /* QCI fc into gr0 */
194-
" lgr 2,%[reg2]\n" /* ptr to config into gr2 */
195-
" .long 0xb2af0000\n" /* PQAP(QCI) */
196-
"0: la %[reg1],0\n" /* good case, QCI fc available */
193+
" lgr 0,%[reg0]\n" /* QCI fc into gr0 */
194+
" lgr 2,%[reg2]\n" /* ptr to config into gr2 */
195+
" .insn rre,0xb2af0000,0,0\n" /* PQAP(QCI) */
196+
"0: la %[reg1],0\n" /* good case, QCI fc available */
197197
"1:\n"
198198
EX_TABLE(0b, 1b)
199199
: [reg1] "+&d" (reg1)
@@ -246,11 +246,11 @@ static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
246246
reg1.qirqctrl = qirqctrl;
247247

248248
asm volatile(
249-
" lgr 0,%[reg0]\n" /* qid param into gr0 */
250-
" lgr 1,%[reg1]\n" /* irq ctrl into gr1 */
251-
" lgr 2,%[reg2]\n" /* ni addr into gr2 */
252-
" .long 0xb2af0000\n" /* PQAP(AQIC) */
253-
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
249+
" lgr 0,%[reg0]\n" /* qid param into gr0 */
250+
" lgr 1,%[reg1]\n" /* irq ctrl into gr1 */
251+
" lgr 2,%[reg2]\n" /* ni addr into gr2 */
252+
" .insn rre,0xb2af0000,0,0\n" /* PQAP(AQIC) */
253+
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
254254
: [reg1] "+&d" (reg1)
255255
: [reg0] "d" (reg0), [reg2] "d" (reg2)
256256
: "cc", "0", "1", "2");
@@ -297,11 +297,11 @@ static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
297297
reg1.value = apinfo->val;
298298

299299
asm volatile(
300-
" lgr 0,%[reg0]\n" /* qid param into gr0 */
301-
" lgr 1,%[reg1]\n" /* qact in info into gr1 */
302-
" .long 0xb2af0000\n" /* PQAP(QACT) */
303-
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
304-
" lgr %[reg2],2\n" /* qact out info into reg2 */
300+
" lgr 0,%[reg0]\n" /* qid param into gr0 */
301+
" lgr 1,%[reg1]\n" /* qact in info into gr1 */
302+
" .insn rre,0xb2af0000,0,0\n" /* PQAP(QACT) */
303+
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
304+
" lgr %[reg2],2\n" /* qact out info into reg2 */
305305
: [reg1] "+&d" (reg1), [reg2] "=&d" (reg2)
306306
: [reg0] "d" (reg0)
307307
: "cc", "0", "1", "2");

arch/s390/include/asm/ctl_reg.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,17 @@ static __always_inline void __ctl_clear_bit(unsigned int cr, unsigned int bit)
7474
__ctl_load(reg, cr, cr);
7575
}
7676

77-
void smp_ctl_set_bit(int cr, int bit);
78-
void smp_ctl_clear_bit(int cr, int bit);
77+
void smp_ctl_set_clear_bit(int cr, int bit, bool set);
78+
79+
static inline void ctl_set_bit(int cr, int bit)
80+
{
81+
smp_ctl_set_clear_bit(cr, bit, true);
82+
}
83+
84+
static inline void ctl_clear_bit(int cr, int bit)
85+
{
86+
smp_ctl_set_clear_bit(cr, bit, false);
87+
}
7988

8089
union ctlreg0 {
8190
unsigned long val;
@@ -130,8 +139,5 @@ union ctlreg15 {
130139
};
131140
};
132141

133-
#define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit)
134-
#define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit)
135-
136142
#endif /* __ASSEMBLY__ */
137143
#endif /* __ASM_CTL_REG_H */

arch/s390/include/asm/processor.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,18 @@ extern void (*s390_base_pgm_handler_fn)(struct pt_regs *regs);
319319
extern int memcpy_real(void *, unsigned long, size_t);
320320
extern void memcpy_absolute(void *, void *, size_t);
321321

322-
#define mem_assign_absolute(dest, val) do { \
323-
__typeof__(dest) __tmp = (val); \
324-
\
325-
BUILD_BUG_ON(sizeof(__tmp) != sizeof(val)); \
326-
memcpy_absolute(&(dest), &__tmp, sizeof(__tmp)); \
322+
#define put_abs_lowcore(member, x) do { \
323+
unsigned long __abs_address = offsetof(struct lowcore, member); \
324+
__typeof__(((struct lowcore *)0)->member) __tmp = (x); \
325+
\
326+
memcpy_absolute(__va(__abs_address), &__tmp, sizeof(__tmp)); \
327+
} while (0)
328+
329+
#define get_abs_lowcore(x, member) do { \
330+
unsigned long __abs_address = offsetof(struct lowcore, member); \
331+
__typeof__(((struct lowcore *)0)->member) *__ptr = &(x); \
332+
\
333+
memcpy_absolute(__ptr, __va(__abs_address), sizeof(*__ptr)); \
327334
} while (0)
328335

329336
extern int s390_isolate_bp(void);

arch/s390/include/asm/spinlock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp)
7878
{
7979
typecheck(int, lp->lock);
8080
asm_inline volatile(
81-
ALTERNATIVE("", ".long 0xb2fa0070", 49) /* NIAI 7 */
81+
ALTERNATIVE("", ".insn rre,0xb2fa0000,7,0", 49) /* NIAI 7 */
8282
" sth %1,%0\n"
8383
: "=R" (((unsigned short *) &lp->lock)[1])
8484
: "d" (0) : "cc", "memory");

arch/s390/include/asm/syscall_wrapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,4 @@
162162
__diag_pop(); \
163163
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
164164

165-
#endif /* _ASM_X86_SYSCALL_WRAPPER_H */
165+
#endif /* _ASM_S390_SYSCALL_WRAPPER_H */

arch/s390/include/asm/unwind.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include <linux/sched.h>
66
#include <linux/ftrace.h>
7+
#include <linux/kprobes.h>
8+
#include <linux/llist.h>
79
#include <asm/ptrace.h>
810
#include <asm/stacktrace.h>
911

@@ -36,10 +38,21 @@ struct unwind_state {
3638
struct pt_regs *regs;
3739
unsigned long sp, ip;
3840
int graph_idx;
41+
struct llist_node *kr_cur;
3942
bool reliable;
4043
bool error;
4144
};
4245

46+
/* Recover the return address modified by kretprobe and ftrace_graph. */
47+
static inline unsigned long unwind_recover_ret_addr(struct unwind_state *state,
48+
unsigned long ip)
49+
{
50+
ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, NULL);
51+
if (is_kretprobe_trampoline(ip))
52+
ip = kretprobe_find_ret_addr(state->task, (void *)state->sp, &state->kr_cur);
53+
return ip;
54+
}
55+
4356
void __unwind_start(struct unwind_state *state, struct task_struct *task,
4457
struct pt_regs *regs, unsigned long first_frame);
4558
bool unwind_next_frame(struct unwind_state *state);

arch/s390/kernel/entry.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,22 @@ _LPP_OFFSET = __LC_LPP
121121
.endm
122122

123123
.macro BPOFF
124-
ALTERNATIVE "", ".long 0xb2e8c000", 82
124+
ALTERNATIVE "", ".insn rrf,0xb2e80000,0,0,12,0", 82
125125
.endm
126126

127127
.macro BPON
128-
ALTERNATIVE "", ".long 0xb2e8d000", 82
128+
ALTERNATIVE "", ".insn rrf,0xb2e80000,0,0,13,0", 82
129129
.endm
130130

131131
.macro BPENTER tif_ptr,tif_mask
132-
ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
132+
ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \
133133
"", 82
134134
.endm
135135

136136
.macro BPEXIT tif_ptr,tif_mask
137137
TSTMSK \tif_ptr,\tif_mask
138-
ALTERNATIVE "jz .+8; .long 0xb2e8c000", \
139-
"jnz .+8; .long 0xb2e8d000", 82
138+
ALTERNATIVE "jz .+8; .insn rrf,0xb2e80000,0,0,12,0", \
139+
"jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
140140
.endm
141141

142142
/*

0 commit comments

Comments
 (0)