Skip to content

Commit 01d1dff

Browse files
committed
Merge tag 's390-5.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Vasily Gorbik: - Make stack unwinder reliable and suitable for livepatching. Add unwinder testing module. - Fixes for CALL_ON_STACK helper used for stack switching. - Fix unwinding from bpf code. - Fix getcpu and remove compat support in vdso code. - Fix address space control registers initialization. - Save KASLR offset for early dumps. - Handle new FILTERED_BY_HYPERVISOR reply code in crypto code. - Minor perf code cleanup and potential memory leak fix. - Add couple of error messages for corner cases during PCI device creation. * tag 's390-5.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (33 commits) s390: remove compat vdso code s390/livepatch: Implement reliable stack tracing for the consistency model s390/unwind: add stack pointer alignment sanity checks s390/unwind: filter out unreliable bogus %r14 s390/unwind: start unwinding from reliable state s390/test_unwind: add program check context tests s390/test_unwind: add irq context tests s390/test_unwind: print verbose unwinding results s390/test_unwind: add CALL_ON_STACK tests s390: fix register clobbering in CALL_ON_STACK s390/test_unwind: require that unwinding ended successfully s390/unwind: add a test for the internal API s390/unwind: always inline get_stack_pointer s390/pci: add error message on device number limit s390/pci: add error message for UID collision s390/cpum_sf: Check for SDBT and SDB consistency s390/cpum_sf: Use TEAR_REG macro consistantly s390/cpum_sf: Remove unnecessary check for pending SDBs s390/cpum_sf: Replace function name in debug statements s390/kaslr: store KASLR offset for early dumps ...
2 parents 4d7048f + 2115fbf commit 01d1dff

35 files changed

+627
-768
lines changed

arch/s390/Kconfig

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ config S390
170170
select HAVE_PERF_EVENTS
171171
select HAVE_RCU_TABLE_FREE
172172
select HAVE_REGS_AND_STACK_ACCESS_API
173+
select HAVE_RELIABLE_STACKTRACE
173174
select HAVE_RSEQ
174175
select HAVE_SYSCALL_TRACEPOINTS
175176
select HAVE_VIRT_CPU_ACCOUNTING
@@ -426,9 +427,6 @@ config COMPAT
426427
(and some other stuff like libraries and such) is needed for
427428
executing 31 bit applications. It is safe to say "Y".
428429

429-
config COMPAT_VDSO
430-
def_bool COMPAT && !CC_IS_CLANG
431-
432430
config SYSVIPC_COMPAT
433431
def_bool y if COMPAT && SYSVIPC
434432

@@ -1018,3 +1016,17 @@ config S390_GUEST
10181016
the KVM hypervisor.
10191017

10201018
endmenu
1019+
1020+
menu "Selftests"
1021+
1022+
config S390_UNWIND_SELFTEST
1023+
def_tristate n
1024+
prompt "Test unwind functions"
1025+
help
1026+
This option enables s390 specific stack unwinder testing kernel
1027+
module. This option is not useful for distributions or general
1028+
kernels, but only for kernel developers working on architecture code.
1029+
1030+
Say N if you are unsure.
1031+
1032+
endmenu

arch/s390/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ zfcpdump:
157157

158158
vdso_install:
159159
$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@
160-
$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@
161160

162161
archclean:
163162
$(Q)$(MAKE) $(clean)=$(boot)

arch/s390/boot/startup.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ void startup_kernel(void)
170170
handle_relocs(__kaslr_offset);
171171

172172
if (__kaslr_offset) {
173+
/*
174+
* Save KASLR offset for early dumps, before vmcore_info is set.
175+
* Mark as uneven to distinguish from real vmcore_info pointer.
176+
*/
177+
S390_lowcore.vmcore_info = __kaslr_offset | 0x1UL;
173178
/* Clear non-relocated kernel */
174179
if (IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED))
175180
memset(img, 0, vmlinux.image_size);

arch/s390/include/asm/cpu_mf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ static inline unsigned long *trailer_entry_ptr(unsigned long v)
313313
return (unsigned long *) ret;
314314
}
315315

316-
/* Return if the entry in the sample data block table (sdbt)
316+
/* Return true if the entry in the sample data block table (sdbt)
317317
* is a link to the next sdbt */
318318
static inline int is_link_entry(unsigned long *s)
319319
{

arch/s390/include/asm/perf_event.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <linux/perf_event.h>
1414
#include <linux/device.h>
15+
#include <asm/stacktrace.h>
1516

1617
/* Per-CPU flags for PMU states */
1718
#define PMU_F_RESERVED 0x1000
@@ -73,4 +74,10 @@ struct perf_sf_sde_regs {
7374
#define SDB_FULL_BLOCKS(hwc) (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_FULL_BLOCKS)
7475
#define SAMPLE_FREQ_MODE(hwc) (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_FREQ_MODE)
7576

77+
#define perf_arch_fetch_caller_regs(regs, __ip) do { \
78+
(regs)->psw.addr = (__ip); \
79+
(regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) - \
80+
offsetof(struct stack_frame, back_chain); \
81+
} while (0)
82+
7683
#endif /* _ASM_S390_PERF_EVENT_H */

arch/s390/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ void enabled_wait(void);
310310
/*
311311
* Function to drop a processor into disabled wait state
312312
*/
313-
static inline void __noreturn disabled_wait(void)
313+
static __always_inline void __noreturn disabled_wait(void)
314314
{
315315
psw_t psw;
316316

arch/s390/include/asm/stacktrace.h

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ static inline bool on_stack(struct stack_info *info,
3333
return addr >= info->begin && addr + len <= info->end;
3434
}
3535

36-
static inline unsigned long get_stack_pointer(struct task_struct *task,
37-
struct pt_regs *regs)
36+
static __always_inline unsigned long get_stack_pointer(struct task_struct *task,
37+
struct pt_regs *regs)
3838
{
3939
if (regs)
4040
return (unsigned long) kernel_stack_pointer(regs);
41-
if (!task || task == current)
41+
if (task == current)
4242
return current_stack_pointer();
4343
return (unsigned long) task->thread.ksp;
4444
}
@@ -62,6 +62,17 @@ struct stack_frame {
6262
};
6363
#endif
6464

65+
/*
66+
* Unlike current_stack_pointer() which simply returns current value of %r15
67+
* current_frame_address() returns function stack frame address, which matches
68+
* %r15 upon function invocation. It may differ from %r15 later if function
69+
* allocates stack for local variables or new stack frame to call other
70+
* functions.
71+
*/
72+
#define current_frame_address() \
73+
((unsigned long)__builtin_frame_address(0) - \
74+
offsetof(struct stack_frame, back_chain))
75+
6576
#define CALL_ARGS_0() \
6677
register unsigned long r2 asm("2")
6778
#define CALL_ARGS_1(arg1) \
@@ -95,20 +106,33 @@ struct stack_frame {
95106

96107
#define CALL_ON_STACK(fn, stack, nr, args...) \
97108
({ \
109+
unsigned long frame = current_frame_address(); \
98110
CALL_ARGS_##nr(args); \
99111
unsigned long prev; \
100112
\
101113
asm volatile( \
102114
" la %[_prev],0(15)\n" \
103-
" la 15,0(%[_stack])\n" \
104-
" stg %[_prev],%[_bc](15)\n" \
115+
" lg 15,%[_stack]\n" \
116+
" stg %[_frame],%[_bc](15)\n" \
105117
" brasl 14,%[_fn]\n" \
106118
" la 15,0(%[_prev])\n" \
107119
: [_prev] "=&a" (prev), CALL_FMT_##nr \
108-
[_stack] "a" (stack), \
120+
[_stack] "R" (stack), \
109121
[_bc] "i" (offsetof(struct stack_frame, back_chain)), \
122+
[_frame] "d" (frame), \
110123
[_fn] "X" (fn) : CALL_CLOBBER_##nr); \
111124
r2; \
112125
})
113126

127+
#define CALL_ON_STACK_NORETURN(fn, stack) \
128+
({ \
129+
asm volatile( \
130+
" la 15,0(%[_stack])\n" \
131+
" xc %[_bc](8,15),%[_bc](15)\n" \
132+
" brasl 14,%[_fn]\n" \
133+
::[_bc] "i" (offsetof(struct stack_frame, back_chain)), \
134+
[_stack] "a" (stack), [_fn] "X" (fn)); \
135+
BUG(); \
136+
})
137+
114138
#endif /* _ASM_S390_STACKTRACE_H */

arch/s390/include/asm/unwind.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ struct unwind_state {
3535
struct task_struct *task;
3636
struct pt_regs *regs;
3737
unsigned long sp, ip;
38-
bool reuse_sp;
3938
int graph_idx;
4039
bool reliable;
4140
bool error;
@@ -59,10 +58,11 @@ static inline bool unwind_error(struct unwind_state *state)
5958
static inline void unwind_start(struct unwind_state *state,
6059
struct task_struct *task,
6160
struct pt_regs *regs,
62-
unsigned long sp)
61+
unsigned long first_frame)
6362
{
64-
sp = sp ? : get_stack_pointer(task, regs);
65-
__unwind_start(state, task, regs, sp);
63+
task = task ?: current;
64+
first_frame = first_frame ?: get_stack_pointer(task, regs);
65+
__unwind_start(state, task, regs, first_frame);
6666
}
6767

6868
static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)

arch/s390/include/asm/vdso.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,17 @@ struct vdso_data {
4141
struct vdso_per_cpu_data {
4242
__u64 ectg_timer_base;
4343
__u64 ectg_user_time;
44-
__u32 cpu_nr;
45-
__u32 node_id;
44+
/*
45+
* Note: node_id and cpu_nr must be at adjacent memory locations.
46+
* VDSO userspace must read both values with a single instruction.
47+
*/
48+
union {
49+
__u64 getcpu_val;
50+
struct {
51+
__u32 node_id;
52+
__u32 cpu_nr;
53+
};
54+
};
4655
};
4756

4857
extern struct vdso_data *vdso_data;

arch/s390/kernel/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,3 @@ obj-$(CONFIG_TRACEPOINTS) += trace.o
8181

8282
# vdso
8383
obj-y += vdso64/
84-
obj-$(CONFIG_COMPAT_VDSO) += vdso32/

0 commit comments

Comments
 (0)