Skip to content

Commit 56e62a7

Browse files
svens-s390Vasily Gorbik
authored andcommitted
s390: convert to generic entry
This patch converts s390 to use the generic entry infrastructure from kernel/entry/*. There are a few special things on s390: - PIF_PER_TRAP is moved to TIF_PER_TRAP as the generic code doesn't know about our PIF flags in exit_to_user_mode_loop(). - The old code had several ways to restart syscalls: a) PIF_SYSCALL_RESTART, which was only set during execve to force a restart after upgrading a process (usually qemu-kvm) to pgste page table extensions. b) PIF_SYSCALL, which is set by do_signal() to indicate that the current syscall should be restarted. This is changed so that do_signal() now also uses PIF_SYSCALL_RESTART. Continuing to use PIF_SYSCALL doesn't work with the generic code, and changing it to PIF_SYSCALL_RESTART makes PIF_SYSCALL and PIF_SYSCALL_RESTART more unique. - On s390 calling sys_sigreturn or sys_rt_sigreturn is implemented by executing a svc instruction on the process stack which causes a fault. While handling that fault the fault code sets PIF_SYSCALL to hand over processing to the syscall code on exit to usermode. The patch introduces PIF_SYSCALL_RET_SET, which is set if ptrace sets a return value for a syscall. The s390x ptrace ABI uses r2 both for the syscall number and return value, so ptrace cannot set the syscall number + return value at the same time. The flag makes handling that a bit easier. do_syscall() will just skip executing the syscall if PIF_SYSCALL_RET_SET is set. CONFIG_DEBUG_ASCE was removd in favour of the generic CONFIG_DEBUG_ENTRY. CR1/7/13 will be checked both on kernel entry and exit to contain the correct asces. Signed-off-by: Sven Schnelle <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent ac94a29 commit 56e62a7

39 files changed

+652
-920
lines changed

arch/s390/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ config S390
123123
select GENERIC_ALLOCATOR
124124
select GENERIC_CPU_AUTOPROBE
125125
select GENERIC_CPU_VULNERABILITIES
126+
select GENERIC_ENTRY
126127
select GENERIC_FIND_FIRST_BIT
127128
select GENERIC_GETTIMEOFDAY
128129
select GENERIC_PTDUMP

arch/s390/Kconfig.debug

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ config TRACE_IRQFLAGS_SUPPORT
66
config EARLY_PRINTK
77
def_bool y
88

9-
config DEBUG_USER_ASCE
10-
bool "Debug User ASCE"
9+
config DEBUG_ENTRY
10+
bool "Debug low-level entry code"
11+
depends on DEBUG_KERNEL
1112
help
12-
Check on exit to user space that address space control
13-
elements are setup correctly.
13+
This option enables sanity checks in s390 low-level entry code.
14+
Some of these sanity checks may slow down kernel entries and
15+
exits or otherwise impact performance.
1416

1517
If unsure, say N.

arch/s390/configs/debug_defconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,6 @@ CONFIG_BPF_KPROBE_OVERRIDE=y
833833
CONFIG_HIST_TRIGGERS=y
834834
CONFIG_FTRACE_STARTUP_TEST=y
835835
# CONFIG_EVENT_TRACE_STARTUP_TEST is not set
836-
CONFIG_DEBUG_USER_ASCE=y
837836
CONFIG_NOTIFIER_ERROR_INJECTION=m
838837
CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
839838
CONFIG_FAULT_INJECTION=y
@@ -857,3 +856,4 @@ CONFIG_PERCPU_TEST=m
857856
CONFIG_ATOMIC64_SELFTEST=y
858857
CONFIG_TEST_BITOPS=m
859858
CONFIG_TEST_BPF=m
859+
CONFIG_DEBUG_ENTRY=y

arch/s390/configs/defconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,6 @@ CONFIG_FTRACE_SYSCALLS=y
781781
CONFIG_BLK_DEV_IO_TRACE=y
782782
CONFIG_BPF_KPROBE_OVERRIDE=y
783783
CONFIG_HIST_TRIGGERS=y
784-
CONFIG_DEBUG_USER_ASCE=y
785784
CONFIG_LKDTM=m
786785
CONFIG_PERCPU_TEST=m
787786
CONFIG_ATOMIC64_SELFTEST=y

arch/s390/include/asm/cputime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ u64 arch_cpu_idle_time(int cpu);
3535

3636
#define arch_idle_time(cpu) arch_cpu_idle_time(cpu)
3737

38+
void account_idle_time_irq(void);
39+
3840
#endif /* _S390_CPUTIME_H */

arch/s390/include/asm/elf.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,7 @@ extern char elf_platform[];
233233
do { \
234234
set_personality(PER_LINUX | \
235235
(current->personality & (~PER_MASK))); \
236-
current->thread.sys_call_table = \
237-
(unsigned long) &sys_call_table; \
236+
current->thread.sys_call_table = sys_call_table; \
238237
} while (0)
239238
#else /* CONFIG_COMPAT */
240239
#define SET_PERSONALITY(ex) \
@@ -245,11 +244,11 @@ do { \
245244
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
246245
set_thread_flag(TIF_31BIT); \
247246
current->thread.sys_call_table = \
248-
(unsigned long) &sys_call_table_emu; \
247+
sys_call_table_emu; \
249248
} else { \
250249
clear_thread_flag(TIF_31BIT); \
251250
current->thread.sys_call_table = \
252-
(unsigned long) &sys_call_table; \
251+
sys_call_table; \
253252
} \
254253
} while (0)
255254
#endif /* CONFIG_COMPAT */

arch/s390/include/asm/entry-common.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef ARCH_S390_ENTRY_COMMON_H
3+
#define ARCH_S390_ENTRY_COMMON_H
4+
5+
#include <linux/sched.h>
6+
#include <linux/audit.h>
7+
#include <linux/tracehook.h>
8+
#include <linux/processor.h>
9+
#include <linux/uaccess.h>
10+
#include <asm/fpu/api.h>
11+
12+
#define ARCH_EXIT_TO_USER_MODE_WORK (_TIF_GUARDED_STORAGE | _TIF_PER_TRAP)
13+
14+
void do_per_trap(struct pt_regs *regs);
15+
void do_syscall(struct pt_regs *regs);
16+
17+
typedef void (*pgm_check_func)(struct pt_regs *regs);
18+
19+
extern pgm_check_func pgm_check_table[128];
20+
21+
#ifdef CONFIG_DEBUG_ENTRY
22+
static __always_inline void arch_check_user_regs(struct pt_regs *regs)
23+
{
24+
debug_user_asce(0);
25+
}
26+
27+
#define arch_check_user_regs arch_check_user_regs
28+
#endif /* CONFIG_DEBUG_ENTRY */
29+
30+
static __always_inline void arch_exit_to_user_mode_work(struct pt_regs *regs,
31+
unsigned long ti_work)
32+
{
33+
if (ti_work & _TIF_PER_TRAP) {
34+
clear_thread_flag(TIF_PER_TRAP);
35+
do_per_trap(regs);
36+
}
37+
38+
if (ti_work & _TIF_GUARDED_STORAGE)
39+
gs_load_bc_cb(regs);
40+
}
41+
42+
#define arch_exit_to_user_mode_work arch_exit_to_user_mode_work
43+
44+
static __always_inline void arch_exit_to_user_mode(void)
45+
{
46+
if (test_cpu_flag(CIF_FPU))
47+
__load_fpu_regs();
48+
49+
if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
50+
debug_user_asce(1);
51+
}
52+
53+
#define arch_exit_to_user_mode arch_exit_to_user_mode
54+
55+
static inline bool on_thread_stack(void)
56+
{
57+
return !(((unsigned long)(current->stack) ^ current_stack_pointer()) & ~(THREAD_SIZE - 1));
58+
}
59+
60+
#endif

arch/s390/include/asm/fpu/api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#include <linux/preempt.h>
4848

4949
void save_fpu_regs(void);
50+
void load_fpu_regs(void);
51+
void __load_fpu_regs(void);
5052

5153
static inline int test_fp_ctl(u32 fpc)
5254
{

arch/s390/include/asm/idle.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ struct s390_idle_data {
2020
unsigned long long clock_idle_exit;
2121
unsigned long long timer_idle_enter;
2222
unsigned long long timer_idle_exit;
23+
unsigned long mt_cycles_enter[8];
2324
};
2425

2526
extern struct device_attribute dev_attr_idle_count;
2627
extern struct device_attribute dev_attr_idle_time_us;
2728

28-
void psw_idle(struct s390_idle_data *, unsigned long);
29+
void psw_idle(struct s390_idle_data *data, unsigned long psw_mask);
30+
void psw_idle_exit(void);
2931

3032
#endif /* _S390_IDLE_H */

arch/s390/include/asm/lowcore.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ struct lowcore {
8181
psw_t return_mcck_psw; /* 0x02a0 */
8282

8383
/* CPU accounting and timing values. */
84-
__u64 sync_enter_timer; /* 0x02b0 */
85-
__u64 async_enter_timer; /* 0x02b8 */
84+
__u64 sys_enter_timer; /* 0x02b0 */
85+
__u8 pad_0x02b8[0x02c0-0x02b8]; /* 0x02b8 */
8686
__u64 mcck_enter_timer; /* 0x02c0 */
8787
__u64 exit_timer; /* 0x02c8 */
8888
__u64 user_timer; /* 0x02d0 */

0 commit comments

Comments
 (0)