s390/uaccess: always run the kernel in home space
Simplify the uaccess code by removing the user_mode=home option. The kernel will now always run in the home space mode. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
@@ -188,8 +188,8 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
|
||||
(__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 |
|
||||
(__u64)(regs32.psw.addr & PSW32_ADDR_AMODE);
|
||||
/* Check for invalid user address space control. */
|
||||
if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
|
||||
regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
|
||||
if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
|
||||
regs->psw.mask = PSW_ASC_PRIMARY |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
|
||||
for (i = 0; i < NUM_GPRS; i++)
|
||||
@@ -348,7 +348,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
|
||||
regs->gprs[15] = (__force __u64) frame;
|
||||
/* Force 31 bit amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(PSW_USER_BITS & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (__force __u64) ka->sa.sa_handler;
|
||||
|
||||
@@ -415,7 +415,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
regs->gprs[15] = (__force __u64) frame;
|
||||
/* Force 31 bit amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(PSW_USER_BITS & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (__u64 __force) ka->sa.sa_handler;
|
||||
|
||||
|
@@ -2051,12 +2051,12 @@ void s390_reset_system(void (*func)(void *), void *data)
|
||||
__ctl_clear_bit(0,28);
|
||||
|
||||
/* Set new machine check handler */
|
||||
S390_lowcore.mcck_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT;
|
||||
S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
|
||||
S390_lowcore.mcck_new_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
|
||||
|
||||
/* Set new program check handler */
|
||||
S390_lowcore.program_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT;
|
||||
S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
|
||||
S390_lowcore.program_new_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
|
||||
|
||||
|
@@ -139,7 +139,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
|
||||
if (unlikely(p->flags & PF_KTHREAD)) {
|
||||
/* kernel thread */
|
||||
memset(&frame->childregs, 0, sizeof(struct pt_regs));
|
||||
frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
|
||||
frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT |
|
||||
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
|
||||
frame->childregs.psw.addr = PSW_ADDR_AMODE |
|
||||
(unsigned long) kernel_thread_starter;
|
||||
|
@@ -200,7 +200,7 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
|
||||
tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
|
||||
if (addr == (addr_t) &dummy->regs.psw.mask)
|
||||
/* Return a clean psw mask. */
|
||||
tmp = psw_user_bits | (tmp & PSW_MASK_USER);
|
||||
tmp = PSW_USER_BITS | (tmp & PSW_MASK_USER);
|
||||
|
||||
} else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
|
||||
/*
|
||||
@@ -322,7 +322,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
|
||||
* psw and gprs are stored on the stack
|
||||
*/
|
||||
if (addr == (addr_t) &dummy->regs.psw.mask &&
|
||||
((data & ~PSW_MASK_USER) != psw_user_bits ||
|
||||
((data & ~PSW_MASK_USER) != PSW_USER_BITS ||
|
||||
((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))))
|
||||
/* Invalid psw mask. */
|
||||
return -EINVAL;
|
||||
|
@@ -40,8 +40,6 @@ static void disable_runtime_instr(void)
|
||||
static void init_runtime_instr_cb(struct runtime_instr_cb *cb)
|
||||
{
|
||||
cb->buf_limit = 0xfff;
|
||||
if (s390_user_mode == HOME_SPACE_MODE)
|
||||
cb->home_space = 1;
|
||||
cb->int_requested = 1;
|
||||
cb->pstate = 1;
|
||||
cb->pstate_set_buf = 1;
|
||||
|
@@ -64,12 +64,6 @@
|
||||
#include <asm/sclp.h>
|
||||
#include "entry.h"
|
||||
|
||||
long psw_kernel_bits = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY |
|
||||
PSW_MASK_EA | PSW_MASK_BA;
|
||||
long psw_user_bits = PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT |
|
||||
PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK |
|
||||
PSW_MASK_PSTATE | PSW_ASC_HOME;
|
||||
|
||||
/*
|
||||
* User copy operations.
|
||||
*/
|
||||
@@ -300,43 +294,14 @@ static int __init parse_vmalloc(char *arg)
|
||||
}
|
||||
early_param("vmalloc", parse_vmalloc);
|
||||
|
||||
unsigned int s390_user_mode = PRIMARY_SPACE_MODE;
|
||||
EXPORT_SYMBOL_GPL(s390_user_mode);
|
||||
|
||||
static void __init set_user_mode_primary(void)
|
||||
{
|
||||
psw_kernel_bits = (psw_kernel_bits & ~PSW_MASK_ASC) | PSW_ASC_HOME;
|
||||
psw_user_bits = (psw_user_bits & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY;
|
||||
#ifdef CONFIG_COMPAT
|
||||
psw32_user_bits =
|
||||
(psw32_user_bits & ~PSW32_MASK_ASC) | PSW32_ASC_PRIMARY;
|
||||
#endif
|
||||
uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos_switch : uaccess_pt;
|
||||
}
|
||||
|
||||
static int __init early_parse_user_mode(char *p)
|
||||
{
|
||||
if (p && strcmp(p, "primary") == 0)
|
||||
s390_user_mode = PRIMARY_SPACE_MODE;
|
||||
else if (!p || strcmp(p, "home") == 0)
|
||||
s390_user_mode = HOME_SPACE_MODE;
|
||||
else
|
||||
return 1;
|
||||
return 0;
|
||||
if (!p || strcmp(p, "primary") == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
early_param("user_mode", early_parse_user_mode);
|
||||
|
||||
static void __init setup_addressing_mode(void)
|
||||
{
|
||||
if (s390_user_mode != PRIMARY_SPACE_MODE)
|
||||
return;
|
||||
set_user_mode_primary();
|
||||
if (MACHINE_HAS_MVCOS)
|
||||
pr_info("Address spaces switched, mvcos available\n");
|
||||
else
|
||||
pr_info("Address spaces switched, mvcos not available\n");
|
||||
}
|
||||
|
||||
void *restart_stack __attribute__((__section__(".data")));
|
||||
|
||||
static void __init setup_lowcore(void)
|
||||
@@ -348,24 +313,24 @@ static void __init setup_lowcore(void)
|
||||
*/
|
||||
BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
|
||||
lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
|
||||
lc->restart_psw.mask = psw_kernel_bits;
|
||||
lc->restart_psw.mask = PSW_KERNEL_BITS;
|
||||
lc->restart_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
|
||||
lc->external_new_psw.mask = psw_kernel_bits |
|
||||
lc->external_new_psw.mask = PSW_KERNEL_BITS |
|
||||
PSW_MASK_DAT | PSW_MASK_MCHECK;
|
||||
lc->external_new_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
|
||||
lc->svc_new_psw.mask = psw_kernel_bits |
|
||||
lc->svc_new_psw.mask = PSW_KERNEL_BITS |
|
||||
PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
|
||||
lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
|
||||
lc->program_new_psw.mask = psw_kernel_bits |
|
||||
lc->program_new_psw.mask = PSW_KERNEL_BITS |
|
||||
PSW_MASK_DAT | PSW_MASK_MCHECK;
|
||||
lc->program_new_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) pgm_check_handler;
|
||||
lc->mcck_new_psw.mask = psw_kernel_bits;
|
||||
lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
|
||||
lc->mcck_new_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
|
||||
lc->io_new_psw.mask = psw_kernel_bits |
|
||||
lc->io_new_psw.mask = PSW_KERNEL_BITS |
|
||||
PSW_MASK_DAT | PSW_MASK_MCHECK;
|
||||
lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
|
||||
lc->clock_comparator = -1ULL;
|
||||
@@ -1043,10 +1008,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
init_mm.end_data = (unsigned long) &_edata;
|
||||
init_mm.brk = (unsigned long) &_end;
|
||||
|
||||
if (MACHINE_HAS_MVCOS)
|
||||
memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));
|
||||
else
|
||||
memcpy(&uaccess, &uaccess_std, sizeof(uaccess));
|
||||
uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos : uaccess_pt;
|
||||
|
||||
parse_early_param();
|
||||
detect_memory_layout(memory_chunk, memory_end);
|
||||
@@ -1054,7 +1016,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
setup_ipl();
|
||||
reserve_oldmem();
|
||||
setup_memory_end();
|
||||
setup_addressing_mode();
|
||||
reserve_crashkernel();
|
||||
setup_memory();
|
||||
setup_resources();
|
||||
|
@@ -57,7 +57,7 @@ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
|
||||
|
||||
/* Copy a 'clean' PSW mask to the user to avoid leaking
|
||||
information about whether PER is currently on. */
|
||||
user_sregs.regs.psw.mask = psw_user_bits |
|
||||
user_sregs.regs.psw.mask = PSW_USER_BITS |
|
||||
(regs->psw.mask & PSW_MASK_USER);
|
||||
user_sregs.regs.psw.addr = regs->psw.addr;
|
||||
memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs));
|
||||
@@ -85,12 +85,12 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
|
||||
err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs));
|
||||
if (err)
|
||||
return err;
|
||||
/* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */
|
||||
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
|
||||
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
||||
(user_sregs.regs.psw.mask & PSW_MASK_USER);
|
||||
/* Check for invalid user address space control. */
|
||||
if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
|
||||
regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
|
||||
if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
|
||||
regs->psw.mask = PSW_ASC_PRIMARY |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
/* Check for invalid amode */
|
||||
if (regs->psw.mask & PSW_MASK_EA)
|
||||
@@ -224,7 +224,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
|
||||
regs->gprs[15] = (unsigned long) frame;
|
||||
/* Force default amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(PSW_USER_BITS & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
|
||||
|
||||
@@ -295,7 +295,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
regs->gprs[15] = (unsigned long) frame;
|
||||
/* Force default amode and default user address space control. */
|
||||
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
|
||||
(psw_user_bits & PSW_MASK_ASC) |
|
||||
(PSW_USER_BITS & PSW_MASK_ASC) |
|
||||
(regs->psw.mask & ~PSW_MASK_ASC);
|
||||
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
|
||||
|
||||
|
@@ -283,7 +283,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
|
||||
struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices];
|
||||
unsigned long source_cpu = stap();
|
||||
|
||||
__load_psw_mask(psw_kernel_bits);
|
||||
__load_psw_mask(PSW_KERNEL_BITS);
|
||||
if (pcpu->address == source_cpu)
|
||||
func(data); /* should not return */
|
||||
/* Stop target cpu (if func returns this stops the current cpu). */
|
||||
@@ -395,7 +395,7 @@ void smp_send_stop(void)
|
||||
int cpu;
|
||||
|
||||
/* Disable all interrupts/machine checks */
|
||||
__load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
|
||||
__load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT);
|
||||
trace_hardirqs_off();
|
||||
|
||||
debug_set_critical();
|
||||
@@ -693,7 +693,7 @@ static void smp_start_secondary(void *cpuvoid)
|
||||
S390_lowcore.restart_source = -1UL;
|
||||
restore_access_regs(S390_lowcore.access_regs_save_area);
|
||||
__ctl_load(S390_lowcore.cregs_save_area, 0, 15);
|
||||
__load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
|
||||
__load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT);
|
||||
cpu_init();
|
||||
preempt_disable();
|
||||
init_cpu_timer();
|
||||
|
@@ -84,8 +84,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
|
||||
*/
|
||||
static void vdso_init_data(struct vdso_data *vd)
|
||||
{
|
||||
vd->ectg_available =
|
||||
s390_user_mode != HOME_SPACE_MODE && test_facility(31);
|
||||
vd->ectg_available = test_facility(31);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -102,7 +101,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
|
||||
|
||||
lowcore->vdso_per_cpu_data = __LC_PASTE;
|
||||
|
||||
if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
|
||||
if (!vdso_enabled)
|
||||
return 0;
|
||||
|
||||
segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER);
|
||||
@@ -147,7 +146,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore)
|
||||
unsigned long segment_table, page_table, page_frame;
|
||||
u32 *psal, *aste;
|
||||
|
||||
if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
|
||||
if (!vdso_enabled)
|
||||
return;
|
||||
|
||||
psal = (u32 *)(addr_t) lowcore->paste[4];
|
||||
@@ -165,7 +164,7 @@ static void vdso_init_cr5(void)
|
||||
{
|
||||
unsigned long cr5;
|
||||
|
||||
if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled)
|
||||
if (!vdso_enabled)
|
||||
return;
|
||||
cr5 = offsetof(struct _lowcore, paste);
|
||||
__ctl_load(cr5, 5, 5);
|
||||
|
@@ -161,7 +161,7 @@ void __kprobes vtime_stop_cpu(void)
|
||||
trace_hardirqs_on();
|
||||
|
||||
/* Wait for external, I/O or machine check interrupt. */
|
||||
psw_mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_DAT |
|
||||
psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT |
|
||||
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
|
||||
idle->nohz_delay = 0;
|
||||
|
||||
|
Reference in New Issue
Block a user