Commit f90dc9f3 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390 update (19/27): ptrace cleanup.

Rewrite s390 ptrace code in a more readable and less buggy way. As a part of
this, all psw related definitions are moved into ptrace.h from a number of
different locations.
parent 91b9f2e4
...@@ -75,9 +75,10 @@ void default_idle(void) ...@@ -75,9 +75,10 @@ void default_idle(void)
/* /*
* Wait for external, I/O or machine check interrupt and * Wait for external, I/O or machine check interrupt and
* switch of machine check bit after the wait has ended. * switch off machine check bit after the wait has ended.
*/ */
wait_psw.mask = _WAIT_PSW_MASK; wait_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK | PSW_MASK_WAIT |
PSW_MASK_IO | PSW_MASK_EXT;
asm volatile ( asm volatile (
" basr %0,0\n" " basr %0,0\n"
"0: la %0,1f-0b(%0)\n" "0: la %0,1f-0b(%0)\n"
...@@ -114,7 +115,7 @@ void show_regs(struct pt_regs *regs) ...@@ -114,7 +115,7 @@ void show_regs(struct pt_regs *regs)
show_registers(regs); show_registers(regs);
/* Show stack backtrace if pt_regs is from kernel mode */ /* Show stack backtrace if pt_regs is from kernel mode */
if (!(regs->psw.mask & PSW_PROBLEM_STATE)) if (!(regs->psw.mask & PSW_MASK_PSTATE))
show_trace((unsigned long *) regs->gprs[15]); show_trace((unsigned long *) regs->gprs[15]);
} }
...@@ -135,8 +136,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ...@@ -135,8 +136,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
struct pt_regs regs; struct pt_regs regs;
memset(&regs, 0, sizeof(regs)); memset(&regs, 0, sizeof(regs));
regs.psw.mask = _SVC_PSW_MASK; regs.psw.mask = PSW_KERNEL_BITS;
regs.psw.addr = (__u32) kernel_thread_starter | _ADDR_31; regs.psw.addr = (__u32) kernel_thread_starter | PSW_ADDR_AMODE31;
regs.gprs[7] = STACK_FRAME_OVERHEAD; regs.gprs[7] = STACK_FRAME_OVERHEAD;
regs.gprs[8] = __LC_KERNEL_STACK; regs.gprs[8] = __LC_KERNEL_STACK;
regs.gprs[9] = (unsigned long) fn; regs.gprs[9] = (unsigned long) fn;
......
This diff is collapsed.
...@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p)
unsigned long start_pfn, end_pfn; unsigned long start_pfn, end_pfn;
static unsigned int smptrap=0; static unsigned int smptrap=0;
unsigned long delay = 0; unsigned long delay = 0;
struct _lowcore *lowcore; struct _lowcore *lc;
int i; int i;
if (smptrap) if (smptrap)
...@@ -451,27 +451,26 @@ void __init setup_arch(char **cmdline_p) ...@@ -451,27 +451,26 @@ void __init setup_arch(char **cmdline_p)
/* /*
* Setup lowcore for boot cpu * Setup lowcore for boot cpu
*/ */
lowcore = (struct _lowcore *) lc = (struct _lowcore *) __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); memset(lc, 0, PAGE_SIZE);
memset(lowcore, 0, PAGE_SIZE); lc->restart_psw.mask = PSW_BASE_BITS;
lowcore->restart_psw.mask = _RESTART_PSW_MASK; lc->restart_psw.addr = PSW_ADDR_AMODE31 + (__u32) restart_int_handler;
lowcore->restart_psw.addr = _ADDR_31 + (addr_t) &restart_int_handler; lc->external_new_psw.mask = PSW_KERNEL_BITS;
lowcore->external_new_psw.mask = _EXT_PSW_MASK; lc->external_new_psw.addr = PSW_ADDR_AMODE31 + (__u32) ext_int_handler;
lowcore->external_new_psw.addr = _ADDR_31 + (addr_t) &ext_int_handler; lc->svc_new_psw.mask = PSW_KERNEL_BITS;
lowcore->svc_new_psw.mask = _SVC_PSW_MASK; lc->svc_new_psw.addr = PSW_ADDR_AMODE31 + (__u32) system_call;
lowcore->svc_new_psw.addr = _ADDR_31 + (addr_t) &system_call; lc->program_new_psw.mask = PSW_KERNEL_BITS;
lowcore->program_new_psw.mask = _PGM_PSW_MASK; lc->program_new_psw.addr = PSW_ADDR_AMODE31 + (__u32)pgm_check_handler;
lowcore->program_new_psw.addr = _ADDR_31 + (addr_t) &pgm_check_handler; lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK; lc->mcck_new_psw.addr = PSW_ADDR_AMODE31 + (__u32) mcck_int_handler;
lowcore->mcck_new_psw.addr = _ADDR_31 + (addr_t) &mcck_int_handler; lc->io_new_psw.mask = PSW_KERNEL_BITS;
lowcore->io_new_psw.mask = _IO_PSW_MASK; lc->io_new_psw.addr = PSW_ADDR_AMODE31 + (__u32) io_int_handler;
lowcore->io_new_psw.addr = _ADDR_31 + (addr_t) &io_int_handler; lc->ipl_device = S390_lowcore.ipl_device;
lowcore->ipl_device = S390_lowcore.ipl_device; lc->kernel_stack = ((__u32) &init_thread_union) + 8192;
lowcore->kernel_stack = ((__u32) &init_thread_union) + 8192; lc->async_stack = (__u32)
lowcore->async_stack = (__u32)
__alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0) + 8192; __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0) + 8192;
lowcore->jiffy_timer = -1LL; lc->jiffy_timer = -1LL;
set_prefix((__u32) lowcore); set_prefix((__u32) lc);
cpu_init(); cpu_init();
__cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
......
...@@ -167,8 +167,8 @@ static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs) ...@@ -167,8 +167,8 @@ static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs)
int err; int err;
err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common)); err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common));
regs->psw.mask = _USER_PSW_MASK | (regs->psw.mask & PSW_MASK_DEBUGCHANGE); regs->psw.mask = PSW_USER_BITS | (regs->psw.mask & PSW_MASK_CC);
regs->psw.addr |= _ADDR_31; regs->psw.addr |= PSW_ADDR_AMODE31;
if (err) if (err)
return err; return err;
...@@ -298,9 +298,9 @@ static void setup_frame(int sig, struct k_sigaction *ka, ...@@ -298,9 +298,9 @@ static void setup_frame(int sig, struct k_sigaction *ka,
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
already in userspace. */ already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) { if (ka->sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer); regs->gprs[14] = (__u32) ka->sa.sa_restorer | PSW_ADDR_AMODE31;
} else { } else {
regs->gprs[14] = FIX_PSW(frame->retcode); regs->gprs[14] = (__u32) frame->retcode | PSW_ADDR_AMODE31;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
(u16 *)(frame->retcode))) (u16 *)(frame->retcode)))
goto give_sigsegv; goto give_sigsegv;
...@@ -311,12 +311,12 @@ static void setup_frame(int sig, struct k_sigaction *ka, ...@@ -311,12 +311,12 @@ static void setup_frame(int sig, struct k_sigaction *ka,
goto give_sigsegv; goto give_sigsegv;
/* Set up registers for signal handler */ /* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame; regs->gprs[15] = (__u32) frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler); regs->psw.addr = (__u32) ka->sa.sa_handler | PSW_ADDR_AMODE31;
regs->psw.mask = _USER_PSW_MASK; regs->psw.mask = PSW_USER_BITS;
regs->gprs[2] = map_signal(sig); regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (addr_t)&frame->sc; regs->gprs[3] = (__u32) &frame->sc;
/* We forgot to include these in the sigcontext. /* We forgot to include these in the sigcontext.
To avoid breaking binary compatibility, they are passed as args. */ To avoid breaking binary compatibility, they are passed as args. */
...@@ -356,9 +356,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -356,9 +356,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
already in userspace. */ already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) { if (ka->sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer); regs->gprs[14] = (__u32) ka->sa.sa_restorer | PSW_ADDR_AMODE31;
} else { } else {
regs->gprs[14] = FIX_PSW(frame->retcode); regs->gprs[14] = (__u32) frame->retcode | PSW_ADDR_AMODE31;
err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
(u16 *)(frame->retcode)); (u16 *)(frame->retcode));
} }
...@@ -368,13 +368,13 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -368,13 +368,13 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
goto give_sigsegv; goto give_sigsegv;
/* Set up registers for signal handler */ /* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame; regs->gprs[15] = (__u32) frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler); regs->psw.addr = (__u32) ka->sa.sa_handler | PSW_ADDR_AMODE31;
regs->psw.mask = _USER_PSW_MASK; regs->psw.mask = PSW_USER_BITS;
regs->gprs[2] = map_signal(sig); regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (addr_t)&frame->info; regs->gprs[3] = (__u32) &frame->info;
regs->gprs[4] = (addr_t)&frame->uc; regs->gprs[4] = (__u32) &frame->uc;
return; return;
give_sigsegv: give_sigsegv:
......
...@@ -116,22 +116,22 @@ void show_trace(unsigned long * stack) ...@@ -116,22 +116,22 @@ void show_trace(unsigned long * stack)
stack = (unsigned long*)&stack; stack = (unsigned long*)&stack;
printk("Call Trace: "); printk("Call Trace: ");
low_addr = ((unsigned long) stack) & PSW_ADDR_MASK; low_addr = ((unsigned long) stack) & PSW_ADDR_INSN;
high_addr = (low_addr & (-THREAD_SIZE)) + THREAD_SIZE; high_addr = (low_addr & (-THREAD_SIZE)) + THREAD_SIZE;
/* Skip the first frame (biased stack) */ /* Skip the first frame (biased stack) */
backchain = *((unsigned long *) low_addr) & PSW_ADDR_MASK; backchain = *((unsigned long *) low_addr) & PSW_ADDR_INSN;
/* Print up to 8 lines */ /* Print up to 8 lines */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (backchain < low_addr || backchain >= high_addr) if (backchain < low_addr || backchain >= high_addr)
break; break;
ret_addr = *((unsigned long *) (backchain+56)) & PSW_ADDR_MASK; ret_addr = *((unsigned long *) (backchain+56)) & PSW_ADDR_INSN;
if (!kernel_text_address(ret_addr)) if (!kernel_text_address(ret_addr))
break; break;
if (i && ((i % 6) == 0)) if (i && ((i % 6) == 0))
printk("\n "); printk("\n ");
printk("[<%08lx>] ", ret_addr); printk("[<%08lx>] ", ret_addr);
low_addr = backchain; low_addr = backchain;
backchain = *((unsigned long *) backchain) & PSW_ADDR_MASK; backchain = *((unsigned long *) backchain) & PSW_ADDR_INSN;
} }
printk("\n"); printk("\n");
} }
...@@ -184,7 +184,7 @@ void show_registers(struct pt_regs *regs) ...@@ -184,7 +184,7 @@ void show_registers(struct pt_regs *regs)
char *mode; char *mode;
int i; int i;
mode = (regs->psw.mask & PSW_PROBLEM_STATE) ? "User" : "Krnl"; mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl";
printk("%s PSW : %08lx %08lx\n", printk("%s PSW : %08lx %08lx\n",
mode, (unsigned long) regs->psw.mask, mode, (unsigned long) regs->psw.mask,
(unsigned long) regs->psw.addr); (unsigned long) regs->psw.addr);
...@@ -210,7 +210,7 @@ void show_registers(struct pt_regs *regs) ...@@ -210,7 +210,7 @@ void show_registers(struct pt_regs *regs)
* time of the fault. * time of the fault.
*/ */
old_fs = get_fs(); old_fs = get_fs();
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
set_fs(USER_DS); set_fs(USER_DS);
else else
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
...@@ -287,10 +287,10 @@ static void inline do_trap(long interruption_code, int signr, char *str, ...@@ -287,10 +287,10 @@ static void inline do_trap(long interruption_code, int signr, char *str,
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
if (regs->psw.mask & PSW_PROBLEM_STATE) { if (regs->psw.mask & PSW_MASK_PSTATE) {
struct task_struct *tsk = current; struct task_struct *tsk = current;
tsk->thread.trap_no = interruption_code & 0xffff; tsk->thread.trap_no = interruption_code & 0xffff;
...@@ -322,12 +322,12 @@ static void inline do_trap(long interruption_code, int signr, char *str, ...@@ -322,12 +322,12 @@ static void inline do_trap(long interruption_code, int signr, char *str,
static inline void *get_check_address(struct pt_regs *regs) static inline void *get_check_address(struct pt_regs *regs)
{ {
return (void *) ADDR_BITS_REMOVE(regs->psw.addr-S390_lowcore.pgm_ilc); return (void *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
} }
int do_debugger_trap(struct pt_regs *regs,int signal) int do_debugger_trap(struct pt_regs *regs,int signal)
{ {
if(regs->psw.mask&PSW_PROBLEM_STATE) if(regs->psw.mask&PSW_MASK_PSTATE)
{ {
if(current->ptrace & PT_PTRACED) if(current->ptrace & PT_PTRACED)
force_sig(signal,current); force_sig(signal,current);
...@@ -423,10 +423,10 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) ...@@ -423,10 +423,10 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
get_user(*((__u16 *) opcode), location); get_user(*((__u16 *) opcode), location);
else else
*((__u16 *)opcode)=*((__u16 *)location); *((__u16 *)opcode)=*((__u16 *)location);
...@@ -436,7 +436,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) ...@@ -436,7 +436,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
signal = SIGILL; signal = SIGILL;
} }
#ifdef CONFIG_MATHEMU #ifdef CONFIG_MATHEMU
else if (regs->psw.mask & PSW_PROBLEM_STATE) else if (regs->psw.mask & PSW_MASK_PSTATE)
{ {
if (opcode[0] == 0xb3) { if (opcode[0] == 0xb3) {
get_user(*((__u16 *) (opcode+2)), location+1); get_user(*((__u16 *) (opcode+2)), location+1);
...@@ -484,10 +484,10 @@ specification_exception(struct pt_regs * regs, long interruption_code) ...@@ -484,10 +484,10 @@ specification_exception(struct pt_regs * regs, long interruption_code)
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
if (regs->psw.mask & PSW_PROBLEM_STATE) { if (regs->psw.mask & PSW_MASK_PSTATE) {
get_user(*((__u16 *) opcode), location); get_user(*((__u16 *) opcode), location);
switch (opcode[0]) { switch (opcode[0]) {
case 0x28: /* LDR Rx,Ry */ case 0x28: /* LDR Rx,Ry */
...@@ -547,7 +547,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) ...@@ -547,7 +547,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
if (MACHINE_HAS_IEEE) if (MACHINE_HAS_IEEE)
...@@ -555,7 +555,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) ...@@ -555,7 +555,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
: "=m" (current->thread.fp_regs.fpc)); : "=m" (current->thread.fp_regs.fpc));
#ifdef CONFIG_MATHEMU #ifdef CONFIG_MATHEMU
else if (regs->psw.mask & PSW_PROBLEM_STATE) { else if (regs->psw.mask & PSW_MASK_PSTATE) {
__u8 opcode[6]; __u8 opcode[6];
get_user(*((__u16 *) opcode), location); get_user(*((__u16 *) opcode), location);
switch (opcode[0]) { switch (opcode[0]) {
...@@ -679,21 +679,19 @@ void __init trap_init(void) ...@@ -679,21 +679,19 @@ void __init trap_init(void)
void handle_per_exception(struct pt_regs *regs) void handle_per_exception(struct pt_regs *regs)
{ {
if(regs->psw.mask&PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE) {
{
per_struct *per_info=&current->thread.per_info; per_struct *per_info=&current->thread.per_info;
per_info->lowcore.words.perc_atmid=S390_lowcore.per_perc_atmid; per_info->lowcore.words.perc_atmid=S390_lowcore.per_perc_atmid;
per_info->lowcore.words.address=S390_lowcore.per_address; per_info->lowcore.words.address=S390_lowcore.per_address;
per_info->lowcore.words.access_id=S390_lowcore.per_access_id; per_info->lowcore.words.access_id=S390_lowcore.per_access_id;
} }
if(do_debugger_trap(regs,SIGTRAP)) if (do_debugger_trap(regs,SIGTRAP)) {
{
/* I've seen this possibly a task structure being reused ? */ /* I've seen this possibly a task structure being reused ? */
printk("Spurious per exception detected\n"); printk("Spurious per exception detected\n");
printk("switching off per tracing for this task.\n"); printk("switching off per tracing for this task.\n");
show_regs(regs); show_regs(regs);
/* Hopefully switching off per tracing will help us survive */ /* Hopefully switching off per tracing will help us survive */
regs->psw.mask &= ~PSW_PER_MASK; regs->psw.mask &= ~PSW_MASK_PER;
} }
} }
...@@ -48,7 +48,7 @@ search_exception_table(unsigned long addr) ...@@ -48,7 +48,7 @@ search_exception_table(unsigned long addr)
addr &= 0x7fffffff; /* remove amode bit from address */ addr &= 0x7fffffff; /* remove amode bit from address */
/* There is only the kernel to search. */ /* There is only the kernel to search. */
ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
if (ret) ret = FIX_PSW(ret); if (ret) ret = ret | PSW_ADDR_AMODE31;
return ret; return ret;
#else #else
unsigned long flags; unsigned long flags;
...@@ -63,7 +63,7 @@ search_exception_table(unsigned long addr) ...@@ -63,7 +63,7 @@ search_exception_table(unsigned long addr)
ret = search_one_table(mp->ex_table_start, ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr); mp->ex_table_end - 1, addr);
if (ret) { if (ret) {
ret = FIX_PSW(ret); ret = ret | PSW_ADDR_AMODE31;
break; break;
} }
} }
......
...@@ -166,7 +166,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -166,7 +166,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
/* Low-address protection hit in kernel mode means /* Low-address protection hit in kernel mode means
NULL pointer write access in kernel mode. */ NULL pointer write access in kernel mode. */
if (!(regs->psw.mask & PSW_PROBLEM_STATE)) { if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
address = 0; address = 0;
user_address = 0; user_address = 0;
goto no_context; goto no_context;
...@@ -258,7 +258,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -258,7 +258,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
/* User mode accesses just cause a SIGSEGV */ /* User mode accesses just cause a SIGSEGV */
if (regs->psw.mask & PSW_PROBLEM_STATE) { if (regs->psw.mask & PSW_MASK_PSTATE) {
tsk->thread.prot_addr = address; tsk->thread.prot_addr = address;
tsk->thread.trap_no = error_code; tsk->thread.trap_no = error_code;
force_sigsegv(regs, error_code, si_code, address); force_sigsegv(regs, error_code, si_code, address);
...@@ -298,7 +298,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -298,7 +298,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
goto survive; goto survive;
} }
printk("VM: killing process %s\n", tsk->comm); printk("VM: killing process %s\n", tsk->comm);
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
do_exit(SIGKILL); do_exit(SIGKILL);
goto no_context; goto no_context;
...@@ -314,7 +314,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -314,7 +314,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
force_sig(SIGBUS, tsk); force_sig(SIGBUS, tsk);
/* Kernel mode? Handle exceptions or die */ /* Kernel mode? Handle exceptions or die */
if (!(regs->psw.mask & PSW_PROBLEM_STATE)) if (!(regs->psw.mask & PSW_MASK_PSTATE))
goto no_context; goto no_context;
} }
...@@ -393,7 +393,7 @@ do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -393,7 +393,7 @@ do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code)
spin_unlock(&pseudo_wait_spinlock); spin_unlock(&pseudo_wait_spinlock);
} else { } else {
/* Pseudo page faults in kernel mode is a bad idea */ /* Pseudo page faults in kernel mode is a bad idea */
if (!(regs->psw.mask & PSW_PROBLEM_STATE)) { if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
/* /*
* VM presents pseudo page faults if the interrupted * VM presents pseudo page faults if the interrupted
* state was not disabled for interrupts. So we can * state was not disabled for interrupts. So we can
...@@ -528,7 +528,7 @@ pfault_interrupt(struct pt_regs *regs, __u16 error_code) ...@@ -528,7 +528,7 @@ pfault_interrupt(struct pt_regs *regs, __u16 error_code)
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
if (subcode & 0x0080) { if (subcode & 0x0080) {
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
#include <linux/nfsd/nfsd.h> #include <linux/nfsd/nfsd.h>
#include <linux/nfsd/export.h> #include <linux/nfsd/export.h>
#ifdef CONFIG_S390_SUPPORT
/* Macro that masks the high order bit of an 32 bit pointer and converts it*/ /* Macro that masks the high order bit of an 32 bit pointer and converts it*/
/* to a 64 bit pointer */ /* to a 64 bit pointer */
#define A(__x) ((unsigned long)((__x) & 0x7FFFFFFFUL)) #define A(__x) ((unsigned long)((__x) & 0x7FFFFFFFUL))
...@@ -194,6 +192,32 @@ typedef struct ...@@ -194,6 +192,32 @@ typedef struct
__u32 addr; __u32 addr;
} _psw_t32 __attribute__ ((aligned(8))); } _psw_t32 __attribute__ ((aligned(8)));
#define PSW32_MASK_PER 0x40000000UL
#define PSW32_MASK_DAT 0x04000000UL
#define PSW32_MASK_IO 0x02000000UL
#define PSW32_MASK_EXT 0x01000000UL
#define PSW32_MASK_KEY 0x00F00000UL
#define PSW32_MASK_MCHECK 0x00040000UL
#define PSW32_MASK_WAIT 0x00020000UL
#define PSW32_MASK_PSTATE 0x00010000UL
#define PSW32_MASK_ASC 0x0000C000UL
#define PSW32_MASK_CC 0x00003000UL
#define PSW32_MASK_PM 0x00000f00UL
#define PSW32_ADDR_AMODE31 0x80000000UL
#define PSW32_ADDR_INSN 0x7FFFFFFFUL
#define PSW32_BASE_BITS 0x00080000UL
#define PSW32_ASC_PRIMARY 0x00000000UL
#define PSW32_ASC_ACCREG 0x00004000UL
#define PSW32_ASC_SECONDARY 0x00008000UL
#define PSW32_ASC_HOME 0x0000C000UL
#define PSW32_USER_BITS (PSW32_BASE_BITS | PSW32_MASK_DAT | PSW32_ASC_HOME | \
PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK | \
PSW32_MASK_PSTATE)
typedef struct typedef struct
{ {
_psw_t32 psw; _psw_t32 psw;
...@@ -241,6 +265,4 @@ struct ucontext32 { ...@@ -241,6 +265,4 @@ struct ucontext32 {
sigset_t32 uc_sigmask; /* mask last for extensibility */ sigset_t32 uc_sigmask; /* mask last for extensibility */
}; };
#endif /* !CONFIG_S390_SUPPORT */
#endif /* _ASM_S390X_S390_H */ #endif /* _ASM_S390X_S390_H */
...@@ -75,9 +75,10 @@ void default_idle(void) ...@@ -75,9 +75,10 @@ void default_idle(void)
/* /*
* Wait for external, I/O or machine check interrupt and * Wait for external, I/O or machine check interrupt and
* switch of machine check bit after the wait has ended. * switch off machine check bit after the wait has ended.
*/ */
wait_psw.mask = _WAIT_PSW_MASK; wait_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK | PSW_MASK_WAIT |
PSW_MASK_IO | PSW_MASK_EXT;
asm volatile ( asm volatile (
" larl %0,0f\n" " larl %0,0f\n"
" stg %0,8(%1)\n" " stg %0,8(%1)\n"
...@@ -111,7 +112,7 @@ void show_regs(struct pt_regs *regs) ...@@ -111,7 +112,7 @@ void show_regs(struct pt_regs *regs)
show_registers(regs); show_registers(regs);
/* Show stack backtrace if pt_regs is from kernel mode */ /* Show stack backtrace if pt_regs is from kernel mode */
if (!(regs->psw.mask & PSW_PROBLEM_STATE)) if (!(regs->psw.mask & PSW_MASK_PSTATE))
show_trace((unsigned long *) regs->gprs[15]); show_trace((unsigned long *) regs->gprs[15]);
} }
...@@ -132,7 +133,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ...@@ -132,7 +133,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
struct pt_regs regs; struct pt_regs regs;
memset(&regs, 0, sizeof(regs)); memset(&regs, 0, sizeof(regs));
regs.psw.mask = _SVC_PSW_MASK; regs.psw.mask = PSW_KERNEL_BITS;
regs.psw.addr = (__u64) kernel_thread_starter; regs.psw.addr = (__u64) kernel_thread_starter;
regs.gprs[7] = STACK_FRAME_OVERHEAD; regs.gprs[7] = STACK_FRAME_OVERHEAD;
regs.gprs[8] = __LC_KERNEL_STACK; regs.gprs[8] = __LC_KERNEL_STACK;
......
This diff is collapsed.
#ifndef _PTRACE32_H
#define _PTRACE32_H
#include "linux32.h" /* needed for _psw_t32 */
typedef struct
{
__u32 cr[3];
} per_cr_words32 __attribute__((packed));
typedef struct
{
__u16 perc_atmid; /* 0x096 */
__u32 address; /* 0x098 */
__u8 access_id; /* 0x0a1 */
} per_lowcore_words32 __attribute__((packed));
typedef struct
{
union {
per_cr_words32 words;
} control_regs __attribute__((packed));
/*
* Use these flags instead of setting em_instruction_fetch
* directly they are used so that single stepping can be
* switched on & off while not affecting other tracing
*/
unsigned single_step : 1;
unsigned instruction_fetch : 1;
unsigned : 30;
/*
* These addresses are copied into cr10 & cr11 if single
* stepping is switched off
*/
__u32 starting_addr;
__u32 ending_addr;
union {
per_lowcore_words32 words;
} lowcore;
} per_struct32 __attribute__((packed));
struct user_regs_struct32
{
_psw_t32 psw;
u32 gprs[NUM_GPRS];
u32 acrs[NUM_ACRS];
u32 orig_gpr2;
s390_fp_regs fp_regs;
/*
* These per registers are in here so that gdb can modify them
* itself as there is no "official" ptrace interface for hardware
* watchpoints. This is the way intel does it.
*/
per_struct32 per_info;
u32 ieee_instruction_pointer;
/* Used to give failing instruction back to user for ieee exceptions */
};
struct user32 {
/* We start with the registers, to mimic the way that "memory"
is returned from the ptrace(3,...) function. */
struct user_regs_struct32 regs; /* Where the registers are actually stored */
/* The rest of this junk is to help gdb figure out what goes where */
u32 u_tsize; /* Text segment size (pages). */
u32 u_dsize; /* Data segment size (pages). */
u32 u_ssize; /* Stack segment size (pages). */
u32 start_code; /* Starting virtual address of text. */
u32 start_stack; /* Starting virtual address of stack area.
This is actually the bottom of the stack,
the top of the stack is always found in the
esp register. */
s32 signal; /* Signal that caused the core dump. */
u32 u_ar0; /* Used by gdb to help find the values for */
/* the registers. */
u32 magic; /* To uniquely identify a core file */
char u_comm[32]; /* User command that was responsible */
};
typedef struct
{
__u32 len;
__u32 kernel_addr;
__u32 process_addr;
} ptrace_area_emu31;
#endif /* _PTRACE32_H */
...@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p)
unsigned long start_pfn, end_pfn; unsigned long start_pfn, end_pfn;
static unsigned int smptrap=0; static unsigned int smptrap=0;
unsigned long delay = 0; unsigned long delay = 0;
struct _lowcore *lowcore; struct _lowcore *lc;
int i; int i;
if (smptrap) if (smptrap)
...@@ -441,27 +441,30 @@ void __init setup_arch(char **cmdline_p) ...@@ -441,27 +441,30 @@ void __init setup_arch(char **cmdline_p)
/* /*
* Setup lowcore for boot cpu * Setup lowcore for boot cpu
*/ */
lowcore = (struct _lowcore *) lc = (struct _lowcore *) __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0);
__alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0); memset(lc, 0, 2*PAGE_SIZE);
memset(lowcore, 0, 2*PAGE_SIZE); lc->restart_psw.mask = PSW_BASE_BITS;
lowcore->restart_psw.mask = _RESTART_PSW_MASK; lc->restart_psw.addr = (addr_t) &restart_int_handler;
lowcore->restart_psw.addr = (addr_t) &restart_int_handler; lc->external_new_psw.mask = PSW_KERNEL_BITS;
lowcore->external_new_psw.mask = _EXT_PSW_MASK; lc->external_new_psw.addr = (addr_t) &ext_int_handler;
lowcore->external_new_psw.addr = (addr_t) &ext_int_handler; lc->svc_new_psw.mask = PSW_KERNEL_BITS;
lowcore->svc_new_psw.mask = _SVC_PSW_MASK; lc->svc_new_psw.addr = (addr_t) &system_call;
lowcore->svc_new_psw.addr = (addr_t) &system_call; lc->program_new_psw.mask = PSW_KERNEL_BITS;
lowcore->program_new_psw.mask = _PGM_PSW_MASK; lc->program_new_psw.addr = (addr_t) &pgm_check_handler;
lowcore->program_new_psw.addr = (addr_t) &pgm_check_handler; lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK; lc->mcck_new_psw.addr = (addr_t) &mcck_int_handler;
lowcore->mcck_new_psw.addr = (addr_t) &mcck_int_handler; lc->io_new_psw.mask = PSW_KERNEL_BITS;
lowcore->io_new_psw.mask = _IO_PSW_MASK; lc->io_new_psw.addr = (addr_t) &io_int_handler;
lowcore->io_new_psw.addr = (addr_t) &io_int_handler; lc->ipl_device = S390_lowcore.ipl_device;
lowcore->ipl_device = S390_lowcore.ipl_device; lc->kernel_stack = ((__u64) &init_thread_union) + 16384;
lowcore->kernel_stack = ((__u64) &init_thread_union) + 16384; lc->async_stack = (__u64)
lowcore->async_stack = (__u64)
__alloc_bootmem(4*PAGE_SIZE, 4*PAGE_SIZE, 0) + 16384; __alloc_bootmem(4*PAGE_SIZE, 4*PAGE_SIZE, 0) + 16384;
lowcore->jiffy_timer = -1LL; lc->jiffy_timer = -1LL;
set_prefix((__u32)(__u64) lowcore); if (MACHINE_HAS_DIAG44)
lc->diag44_opcode = 0x83000044;
else
lc->diag44_opcode = 0x07000700;
set_prefix((__u32)(__u64) lc);
cpu_init(); cpu_init();
__cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
......
...@@ -162,7 +162,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs) ...@@ -162,7 +162,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs)
int err; int err;
err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common)); err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common));
regs->psw.mask = _USER_PSW_MASK | (regs->psw.mask & PSW_MASK_DEBUGCHANGE); regs->psw.mask = PSW_USER_BITS | (regs->psw.mask & PSW_MASK_CC);
if (err) if (err)
return err; return err;
...@@ -292,9 +292,9 @@ static void setup_frame(int sig, struct k_sigaction *ka, ...@@ -292,9 +292,9 @@ static void setup_frame(int sig, struct k_sigaction *ka,
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
already in userspace. */ already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) { if (ka->sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer); regs->gprs[14] = (__u64) ka->sa.sa_restorer;
} else { } else {
regs->gprs[14] = FIX_PSW(frame->retcode); regs->gprs[14] = (__u64) frame->retcode;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
(u16 *)(frame->retcode))) (u16 *)(frame->retcode)))
goto give_sigsegv; goto give_sigsegv;
...@@ -305,12 +305,12 @@ static void setup_frame(int sig, struct k_sigaction *ka, ...@@ -305,12 +305,12 @@ static void setup_frame(int sig, struct k_sigaction *ka,
goto give_sigsegv; goto give_sigsegv;
/* Set up registers for signal handler */ /* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame; regs->gprs[15] = (__u64) frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler); regs->psw.addr = (__u64) ka->sa.sa_handler;
regs->psw.mask = _USER_PSW_MASK; regs->psw.mask = PSW_USER_BITS;
regs->gprs[2] = map_signal(sig); regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (addr_t)&frame->sc; regs->gprs[3] = (__u64) &frame->sc;
/* We forgot to include these in the sigcontext. /* We forgot to include these in the sigcontext.
To avoid breaking binary compatibility, they are passed as args. */ To avoid breaking binary compatibility, they are passed as args. */
...@@ -350,9 +350,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -350,9 +350,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
already in userspace. */ already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) { if (ka->sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer); regs->gprs[14] = (__u64) ka->sa.sa_restorer;
} else { } else {
regs->gprs[14] = FIX_PSW(frame->retcode); regs->gprs[14] = (__u64) frame->retcode;
err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
(u16 *)(frame->retcode)); (u16 *)(frame->retcode));
} }
...@@ -362,13 +362,13 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -362,13 +362,13 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
goto give_sigsegv; goto give_sigsegv;
/* Set up registers for signal handler */ /* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame; regs->gprs[15] = (__u64) frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler); regs->psw.addr = (__u64) ka->sa.sa_handler;
regs->psw.mask = _USER_PSW_MASK; regs->psw.mask = PSW_USER_BITS;
regs->gprs[2] = map_signal(sig); regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (addr_t)&frame->info; regs->gprs[3] = (__u64) &frame->info;
regs->gprs[4] = (addr_t)&frame->uc; regs->gprs[4] = (__u64) &frame->uc;
return; return;
give_sigsegv: give_sigsegv:
......
...@@ -29,15 +29,10 @@ ...@@ -29,15 +29,10 @@
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "linux32.h" #include "linux32.h"
#include "ptrace32.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
#define _ADDR_31 0x80000000
#define _USER_PSW_MASK_EMU32 0x070DC000
#define _USER_PSW_MASK32 0x0705C00080000000
#define PSW_MASK_DEBUGCHANGE32 0x00003000UL
#define PSW_ADDR_DEBUGCHANGE32 0x7FFFFFFFUL
typedef struct typedef struct
{ {
__u8 callee_used_stack[__SIGNAL_FRAMESIZE32]; __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
...@@ -297,9 +292,9 @@ static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) ...@@ -297,9 +292,9 @@ static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
_s390_regs_common32 regs32; _s390_regs_common32 regs32;
int err, i; int err, i;
regs32.psw.mask = _USER_PSW_MASK_EMU32 | regs32.psw.mask = PSW32_USER_BITS |
(__u32)((regs->psw.mask & PSW_MASK_DEBUGCHANGE) >> 32); ((__u32)(regs->psw.mask >> 32) & PSW32_MASK_CC);
regs32.psw.addr = _ADDR_31 | (__u32) regs->psw.addr; regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
for (i = 0; i < NUM_GPRS; i++) for (i = 0; i < NUM_GPRS; i++)
regs32.gprs[i] = (__u32) regs->gprs[i]; regs32.gprs[i] = (__u32) regs->gprs[i];
memcpy(regs32.acrs, regs->acrs, sizeof(regs32.acrs)); memcpy(regs32.acrs, regs->acrs, sizeof(regs32.acrs));
...@@ -320,9 +315,9 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) ...@@ -320,9 +315,9 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32)); err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
if (err) if (err)
return err; return err;
regs->psw.mask = _USER_PSW_MASK32 | regs->psw.mask = PSW_USER32_BITS |
(__u64)(regs32.psw.mask & PSW_MASK_DEBUGCHANGE32) << 32; (__u64)(regs32.psw.mask & PSW32_MASK_CC) << 32;
regs->psw.addr = (__u64)(regs32.psw.addr & PSW_ADDR_DEBUGCHANGE32); regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
for (i = 0; i < NUM_GPRS; i++) for (i = 0; i < NUM_GPRS; i++)
regs->gprs[i] = (__u64) regs32.gprs[i]; regs->gprs[i] = (__u64) regs32.gprs[i];
memcpy(regs->acrs, regs32.acrs, sizeof(regs32.acrs)); memcpy(regs->acrs, regs32.acrs, sizeof(regs32.acrs));
...@@ -467,9 +462,9 @@ static void setup_frame32(int sig, struct k_sigaction *ka, ...@@ -467,9 +462,9 @@ static void setup_frame32(int sig, struct k_sigaction *ka,
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
already in userspace. */ already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) { if (ka->sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer); regs->gprs[14] = (__u64) ka->sa.sa_restorer;
} else { } else {
regs->gprs[14] = FIX_PSW(frame->retcode); regs->gprs[14] = (__u64) frame->retcode;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
(u16 *)(frame->retcode))) (u16 *)(frame->retcode)))
goto give_sigsegv; goto give_sigsegv;
...@@ -480,12 +475,12 @@ static void setup_frame32(int sig, struct k_sigaction *ka, ...@@ -480,12 +475,12 @@ static void setup_frame32(int sig, struct k_sigaction *ka,
goto give_sigsegv; goto give_sigsegv;
/* Set up registers for signal handler */ /* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame; regs->gprs[15] = (__u64) frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler); regs->psw.addr = (__u64) ka->sa.sa_handler;
regs->psw.mask = _USER_PSW_MASK32; regs->psw.mask = PSW_USER32_BITS;
regs->gprs[2] = map_signal(sig); regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (addr_t)&frame->sc; regs->gprs[3] = (__u64) &frame->sc;
/* We forgot to include these in the sigcontext. /* We forgot to include these in the sigcontext.
To avoid breaking binary compatibility, they are passed as args. */ To avoid breaking binary compatibility, they are passed as args. */
...@@ -525,9 +520,9 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -525,9 +520,9 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
already in userspace. */ already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) { if (ka->sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer); regs->gprs[14] = (__u64) ka->sa.sa_restorer;
} else { } else {
regs->gprs[14] = FIX_PSW(frame->retcode); regs->gprs[14] = (__u64) frame->retcode;
err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
(u16 *)(frame->retcode)); (u16 *)(frame->retcode));
} }
...@@ -537,13 +532,13 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -537,13 +532,13 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
goto give_sigsegv; goto give_sigsegv;
/* Set up registers for signal handler */ /* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame; regs->gprs[15] = (__u64) frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler); regs->psw.addr = (__u64) ka->sa.sa_handler;
regs->psw.mask = _USER_PSW_MASK32; regs->psw.mask = PSW_USER32_BITS;
regs->gprs[2] = map_signal(sig); regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (addr_t)&frame->info; regs->gprs[3] = (__u64) &frame->info;
regs->gprs[4] = (addr_t)&frame->uc; regs->gprs[4] = (__u64) &frame->uc;
return; return;
give_sigsegv: give_sigsegv:
......
...@@ -118,22 +118,22 @@ void show_trace(unsigned long * stack) ...@@ -118,22 +118,22 @@ void show_trace(unsigned long * stack)
stack = (unsigned long*)&stack; stack = (unsigned long*)&stack;
printk("Call Trace: "); printk("Call Trace: ");
low_addr = ((unsigned long) stack) & PSW_ADDR_MASK; low_addr = (unsigned long) stack;
high_addr = (low_addr & (-THREAD_SIZE)) + THREAD_SIZE; high_addr = (low_addr & (-THREAD_SIZE)) + THREAD_SIZE;
/* Skip the first frame (biased stack) */ /* Skip the first frame (biased stack) */
backchain = *((unsigned long *) low_addr) & PSW_ADDR_MASK; backchain = *(unsigned long *) low_addr;
/* Print up to 8 lines */ /* Print up to 8 lines */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (backchain < low_addr || backchain >= high_addr) if (backchain < low_addr || backchain >= high_addr)
break; break;
ret_addr = *((unsigned long *) (backchain+112)) & PSW_ADDR_MASK; ret_addr = *(unsigned long *) (backchain+112);
if (!kernel_text_address(ret_addr)) if (!kernel_text_address(ret_addr))
break; break;
if (i && ((i % 3) == 0)) if (i && ((i % 3) == 0))
printk("\n "); printk("\n ");
printk("[<%016lx>] ", ret_addr); printk("[<%016lx>] ", ret_addr);
low_addr = backchain; low_addr = backchain;
backchain = *((unsigned long *) backchain) & PSW_ADDR_MASK; backchain = *(unsigned long *) backchain;
} }
printk("\n"); printk("\n");
} }
...@@ -186,7 +186,7 @@ void show_registers(struct pt_regs *regs) ...@@ -186,7 +186,7 @@ void show_registers(struct pt_regs *regs)
char *mode; char *mode;
int i; int i;
mode = (regs->psw.mask & PSW_PROBLEM_STATE) ? "User" : "Krnl"; mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl";
printk("%s PSW : %016lx %016lx\n", printk("%s PSW : %016lx %016lx\n",
mode, (unsigned long) regs->psw.mask, mode, (unsigned long) regs->psw.mask,
(unsigned long) regs->psw.addr); (unsigned long) regs->psw.addr);
...@@ -212,7 +212,7 @@ void show_registers(struct pt_regs *regs) ...@@ -212,7 +212,7 @@ void show_registers(struct pt_regs *regs)
* time of the fault. * time of the fault.
*/ */
old_fs = get_fs(); old_fs = get_fs();
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
set_fs(USER_DS); set_fs(USER_DS);
else else
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
...@@ -289,10 +289,10 @@ static void inline do_trap(long interruption_code, int signr, char *str, ...@@ -289,10 +289,10 @@ static void inline do_trap(long interruption_code, int signr, char *str,
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
if (regs->psw.mask & PSW_PROBLEM_STATE) { if (regs->psw.mask & PSW_MASK_PSTATE) {
struct task_struct *tsk = current; struct task_struct *tsk = current;
tsk->thread.trap_no = interruption_code & 0xffff; tsk->thread.trap_no = interruption_code & 0xffff;
if (info) if (info)
...@@ -323,12 +323,12 @@ static void inline do_trap(long interruption_code, int signr, char *str, ...@@ -323,12 +323,12 @@ static void inline do_trap(long interruption_code, int signr, char *str,
static inline void *get_check_address(struct pt_regs *regs) static inline void *get_check_address(struct pt_regs *regs)
{ {
return (void *) ADDR_BITS_REMOVE(regs->psw.addr-S390_lowcore.pgm_ilc); return (void *)(regs->psw.addr - S390_lowcore.pgm_ilc);
} }
int do_debugger_trap(struct pt_regs *regs,int signal) int do_debugger_trap(struct pt_regs *regs,int signal)
{ {
if(regs->psw.mask&PSW_PROBLEM_STATE) if(regs->psw.mask&PSW_MASK_PSTATE)
{ {
if(current->ptrace & PT_PTRACED) if(current->ptrace & PT_PTRACED)
force_sig(signal,current); force_sig(signal,current);
...@@ -426,14 +426,14 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) ...@@ -426,14 +426,14 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
/* WARNING don't change this check back to */ /* WARNING don't change this check back to */
/* int problem_state=(regs->psw.mask & PSW_PROBLEM_STATE); */ /* int problem_state=(regs->psw.mask & PSW_MASK_PSTATE); */
/* & then doing if(problem_state) an int is too small for this */ /* & then doing if(problem_state) an int is too small for this */
/* check on 64 bit. */ /* check on 64 bit. */
if(regs->psw.mask & PSW_PROBLEM_STATE) if(regs->psw.mask & PSW_MASK_PSTATE)
get_user(*((__u16 *) opcode), location); get_user(*((__u16 *) opcode), location);
else else
*((__u16 *)opcode)=*((__u16 *)location); *((__u16 *)opcode)=*((__u16 *)location);
...@@ -459,7 +459,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) ...@@ -459,7 +459,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
__asm__ volatile ("stfpc %0\n\t" __asm__ volatile ("stfpc %0\n\t"
...@@ -527,21 +527,19 @@ void __init trap_init(void) ...@@ -527,21 +527,19 @@ void __init trap_init(void)
void handle_per_exception(struct pt_regs *regs) void handle_per_exception(struct pt_regs *regs)
{ {
if(regs->psw.mask&PSW_PROBLEM_STATE) if (regs->psw.mask&PSW_MASK_PSTATE) {
{
per_struct *per_info=&current->thread.per_info; per_struct *per_info=&current->thread.per_info;
per_info->lowcore.words.perc_atmid=S390_lowcore.per_perc_atmid; per_info->lowcore.words.perc_atmid=S390_lowcore.per_perc_atmid;
per_info->lowcore.words.address=S390_lowcore.per_address; per_info->lowcore.words.address=S390_lowcore.per_address;
per_info->lowcore.words.access_id=S390_lowcore.per_access_id; per_info->lowcore.words.access_id=S390_lowcore.per_access_id;
} }
if(do_debugger_trap(regs,SIGTRAP)) if (do_debugger_trap(regs,SIGTRAP)) {
{
/* I've seen this possibly a task structure being reused ? */ /* I've seen this possibly a task structure being reused ? */
printk("Spurious per exception detected\n"); printk("Spurious per exception detected\n");
printk("switching off per tracing for this task.\n"); printk("switching off per tracing for this task.\n");
show_regs(regs); show_regs(regs);
/* Hopefully switching off per tracing will help us survive */ /* Hopefully switching off per tracing will help us survive */
regs->psw.mask &= ~PSW_PER_MASK; regs->psw.mask &= ~PSW_MASK_PER;
} }
} }
...@@ -166,7 +166,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -166,7 +166,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
/* Low-address protection hit in kernel mode means /* Low-address protection hit in kernel mode means
NULL pointer write access in kernel mode. */ NULL pointer write access in kernel mode. */
if (!(regs->psw.mask & PSW_PROBLEM_STATE)) { if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
address = 0; address = 0;
user_address = 0; user_address = 0;
goto no_context; goto no_context;
...@@ -258,7 +258,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -258,7 +258,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
/* User mode accesses just cause a SIGSEGV */ /* User mode accesses just cause a SIGSEGV */
if (regs->psw.mask & PSW_PROBLEM_STATE) { if (regs->psw.mask & PSW_MASK_PSTATE) {
tsk->thread.prot_addr = address; tsk->thread.prot_addr = address;
tsk->thread.trap_no = error_code; tsk->thread.trap_no = error_code;
force_sigsegv(regs, error_code, si_code, address); force_sigsegv(regs, error_code, si_code, address);
...@@ -298,7 +298,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -298,7 +298,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
goto survive; goto survive;
} }
printk("VM: killing process %s\n", tsk->comm); printk("VM: killing process %s\n", tsk->comm);
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
do_exit(SIGKILL); do_exit(SIGKILL);
goto no_context; goto no_context;
...@@ -314,7 +314,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code) ...@@ -314,7 +314,7 @@ extern inline void do_exception(struct pt_regs *regs, unsigned long error_code)
force_sig(SIGBUS, tsk); force_sig(SIGBUS, tsk);
/* Kernel mode? Handle exceptions or die */ /* Kernel mode? Handle exceptions or die */
if (!(regs->psw.mask & PSW_PROBLEM_STATE)) if (!(regs->psw.mask & PSW_MASK_PSTATE))
goto no_context; goto no_context;
} }
...@@ -440,7 +440,7 @@ pfault_interrupt(struct pt_regs *regs, __u16 error_code) ...@@ -440,7 +440,7 @@ pfault_interrupt(struct pt_regs *regs, __u16 error_code)
* We got all needed information from the lowcore and can * We got all needed information from the lowcore and can
* now safely switch on interrupts. * now safely switch on interrupts.
*/ */
if (regs->psw.mask & PSW_PROBLEM_STATE) if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable(); local_irq_enable();
if (subcode & 0x0080) { if (subcode & 0x0080) {
......
...@@ -98,7 +98,6 @@ static inline int ...@@ -98,7 +98,6 @@ static inline int
s390_do_sync_wait(int irq, int do_tpi) s390_do_sync_wait(int irq, int do_tpi)
{ {
unsigned long psw_mask; unsigned long psw_mask;
int ccode;
uint64_t time_start; uint64_t time_start;
uint64_t time_curr; uint64_t time_curr;
...@@ -116,31 +115,7 @@ s390_do_sync_wait(int irq, int do_tpi) ...@@ -116,31 +115,7 @@ s390_do_sync_wait(int irq, int do_tpi)
* sync. interrupt arrived we reset the I/O old PSW to * sync. interrupt arrived we reset the I/O old PSW to
* its original value. * its original value.
*/ */
psw_mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_WAIT;
ccode = iac ();
switch (ccode) {
case 0: /* primary-space */
psw_mask = _IO_PSW_MASK
| _PSW_PRIM_SPACE_MODE | _PSW_IO_WAIT;
break;
case 1: /* secondary-space */
psw_mask = _IO_PSW_MASK
| _PSW_SEC_SPACE_MODE | _PSW_IO_WAIT;
break;
case 2: /* access-register */
psw_mask = _IO_PSW_MASK
| _PSW_ACC_REG_MODE | _PSW_IO_WAIT;
break;
case 3: /* home-space */
psw_mask = _IO_PSW_MASK
| _PSW_HOME_SPACE_MODE | _PSW_IO_WAIT;
break;
default:
panic ("start_IO() : unexpected "
"address-space-control %d\n", ccode);
break;
}
/* /*
* Martin didn't like modifying the new PSW, now we take * Martin didn't like modifying the new PSW, now we take
...@@ -201,7 +176,6 @@ s390_do_sync_wait_haltclear(int irq, int halt) ...@@ -201,7 +176,6 @@ s390_do_sync_wait_haltclear(int irq, int halt)
int io_sub; int io_sub;
__u32 io_parm; __u32 io_parm;
unsigned long psw_mask; unsigned long psw_mask;
int ccode;
int ready = 0; int ready = 0;
...@@ -212,32 +186,7 @@ s390_do_sync_wait_haltclear(int irq, int halt) ...@@ -212,32 +186,7 @@ s390_do_sync_wait_haltclear(int irq, int halt)
* FIXME: Are there case where we can't rely on an interrupt * FIXME: Are there case where we can't rely on an interrupt
* to occurr? Need to check... * to occurr? Need to check...
*/ */
psw_mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_WAIT;
ccode = iac ();
switch (ccode) {
case 0: /* primary-space */
psw_mask = _IO_PSW_MASK
| _PSW_PRIM_SPACE_MODE | _PSW_IO_WAIT;
break;
case 1: /* secondary-space */
psw_mask = _IO_PSW_MASK
| _PSW_SEC_SPACE_MODE | _PSW_IO_WAIT;
break;
case 2: /* access-register */
psw_mask = _IO_PSW_MASK
| _PSW_ACC_REG_MODE | _PSW_IO_WAIT;
break;
case 3: /* home-space */
psw_mask = _IO_PSW_MASK
| _PSW_HOME_SPACE_MODE | _PSW_IO_WAIT;
break;
default: /* FIXME: isn't ccode only 2 bits anyway? */
panic (halt?"halt":"clear"
"_IO() : unexpected address-space-control %d\n",
ccode);
break;
}
/* /*
* Martin didn't like modifying the new PSW, now we take * Martin didn't like modifying the new PSW, now we take
...@@ -960,7 +909,7 @@ do_IRQ (struct pt_regs regs) ...@@ -960,7 +909,7 @@ do_IRQ (struct pt_regs regs)
* entry condition to synchronous I/O. * entry condition to synchronous I/O.
*/ */
if (*(__u32 *) __LC_SYNC_IO_WORD) { if (*(__u32 *) __LC_SYNC_IO_WORD) {
regs.psw.mask &= ~(_PSW_WAIT_MASK_BIT | _PSW_IO_MASK_BIT); regs.psw.mask &= ~(PSW_MASK_WAIT | PSW_MASK_IO);
return; return;
} }
/* endif */ /* endif */
......
...@@ -52,41 +52,12 @@ ...@@ -52,41 +52,12 @@
#define __LC_PFAULT_INTPARM 0x080 #define __LC_PFAULT_INTPARM 0x080
/* interrupt handler start with all io, external and mcck interrupt disabled */
#define _RESTART_PSW_MASK 0x00080000
#define _EXT_PSW_MASK 0x04080000
#define _PGM_PSW_MASK 0x04080000
#define _SVC_PSW_MASK 0x04080000
#define _MCCK_PSW_MASK 0x04080000
#define _IO_PSW_MASK 0x04080000
#define _USER_PSW_MASK 0x070DC000/* DAT, IO, EXT, Home-space */
#define _WAIT_PSW_MASK 0x070E0000/* DAT, IO, EXT, Wait, Home-space */
#define _DW_PSW_MASK 0x000A0000/* disabled wait PSW mask */
#define _PRIMARY_MASK 0x0000 /* MASK for SACF */
#define _SECONDARY_MASK 0x0100 /* MASK for SACF */
#define _ACCESS_MASK 0x0200 /* MASK for SACF */
#define _HOME_MASK 0x0300 /* MASK for SACF */
#define _PSW_PRIM_SPACE_MODE 0x00000000
#define _PSW_SEC_SPACE_MODE 0x00008000
#define _PSW_ACC_REG_MODE 0x00004000
#define _PSW_HOME_SPACE_MODE 0x0000C000
#define _PSW_WAIT_MASK_BIT 0x00020000 /* Wait bit */
#define _PSW_IO_MASK_BIT 0x02000000 /* IO bit */
#define _PSW_IO_WAIT 0x02020000 /* IO & Wait bit */
/* we run in 31 Bit mode */
#define _ADDR_31 0x80000000
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/config.h> #include <linux/config.h>
#include <asm/processor.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/processor.h>
#include <asm/sigp.h> #include <asm/sigp.h>
void restart_int_handler(void); void restart_int_handler(void);
......
...@@ -101,8 +101,8 @@ typedef struct thread_struct thread_struct; ...@@ -101,8 +101,8 @@ typedef struct thread_struct thread_struct;
/* need to define ... */ /* need to define ... */
#define start_thread(regs, new_psw, new_stackp) do { \ #define start_thread(regs, new_psw, new_stackp) do { \
regs->psw.mask = _USER_PSW_MASK; \ regs->psw.mask = PSW_USER_BITS; \
regs->psw.addr = new_psw | 0x80000000; \ regs->psw.addr = new_psw | PSW_ADDR_AMODE31; \
regs->gprs[15] = new_stackp ; \ regs->gprs[15] = new_stackp ; \
} while (0) } while (0)
...@@ -136,19 +136,6 @@ unsigned long get_wchan(struct task_struct *p); ...@@ -136,19 +136,6 @@ unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier() #define cpu_relax() barrier()
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
/* Only let our hackers near the condition codes */
#define PSW_MASK_DEBUGCHANGE 0x00003000UL
/* Don't let em near the addressing mode either */
#define PSW_ADDR_DEBUGCHANGE 0x7FFFFFFFUL
#define PSW_ADDR_MASK 0x7FFFFFFFUL
/* Program event recording mask */
#define PSW_PER_MASK 0x40000000UL
#define USER_STD_MASK 0x00000080UL
#define PSW_PROBLEM_STATE 0x00010000UL
/* /*
* Set PSW mask to specified value, while leaving the * Set PSW mask to specified value, while leaving the
* PSW addr pointing to the next instruction. * PSW addr pointing to the next instruction.
...@@ -178,7 +165,8 @@ static inline void enabled_wait(void) ...@@ -178,7 +165,8 @@ static inline void enabled_wait(void)
unsigned long reg; unsigned long reg;
psw_t wait_psw; psw_t wait_psw;
wait_psw.mask = 0x070e0000; wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
PSW_MASK_MCHECK | PSW_MASK_WAIT;
asm volatile ( asm volatile (
" basr %0,0\n" " basr %0,0\n"
"0: la %0,1f-0b(%0)\n" "0: la %0,1f-0b(%0)\n"
...@@ -200,7 +188,7 @@ static inline void disabled_wait(unsigned long code) ...@@ -200,7 +188,7 @@ static inline void disabled_wait(unsigned long code)
psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1) psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1)
& -sizeof(psw_t)); & -sizeof(psw_t));
dw_psw->mask = 0x000a0000; dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT;
dw_psw->addr = code; dw_psw->addr = code;
/* /*
* Store status and then load disabled wait psw, * Store status and then load disabled wait psw,
......
...@@ -114,7 +114,6 @@ ...@@ -114,7 +114,6 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/setup.h> #include <asm/setup.h>
/* this typedef defines how a Program Status Word looks like */ /* this typedef defines how a Program Status Word looks like */
...@@ -124,10 +123,32 @@ typedef struct ...@@ -124,10 +123,32 @@ typedef struct
__u32 addr; __u32 addr;
} __attribute__ ((aligned(8))) psw_t; } __attribute__ ((aligned(8))) psw_t;
#ifdef __KERNEL__ #define PSW_MASK_PER 0x40000000UL
#define FIX_PSW(addr) ((unsigned long)(addr)|0x80000000UL) #define PSW_MASK_DAT 0x04000000UL
#define ADDR_BITS_REMOVE(addr) ((addr)&0x7fffffff) #define PSW_MASK_IO 0x02000000UL
#endif #define PSW_MASK_EXT 0x01000000UL
#define PSW_MASK_KEY 0x00F00000UL
#define PSW_MASK_MCHECK 0x00040000UL
#define PSW_MASK_WAIT 0x00020000UL
#define PSW_MASK_PSTATE 0x00010000UL
#define PSW_MASK_ASC 0x0000C000UL
#define PSW_MASK_CC 0x00003000UL
#define PSW_MASK_PM 0x00000F00UL
#define PSW_ADDR_AMODE31 0x80000000UL
#define PSW_ADDR_INSN 0x7FFFFFFFUL
#define PSW_BASE_BITS 0x00080000UL
#define PSW_ASC_PRIMARY 0x00000000UL
#define PSW_ASC_ACCREG 0x00004000UL
#define PSW_ASC_SECONDARY 0x00008000UL
#define PSW_ASC_HOME 0x0000C000UL
#define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY)
#define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \
PSW_MASK_PSTATE)
typedef union typedef union
{ {
...@@ -328,8 +349,8 @@ struct user_regs_struct ...@@ -328,8 +349,8 @@ struct user_regs_struct
}; };
#ifdef __KERNEL__ #ifdef __KERNEL__
#define user_mode(regs) (((regs)->psw.mask & PSW_PROBLEM_STATE) != 0) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_MASK_INSN)
extern void show_regs(struct pt_regs * regs); extern void show_regs(struct pt_regs * regs);
#endif #endif
......
...@@ -56,32 +56,6 @@ ...@@ -56,32 +56,6 @@
#define __LC_PFAULT_INTPARM 0x11B8 #define __LC_PFAULT_INTPARM 0x11B8
/* interrupt handler start with all io, external and mcck interrupt disabled */
#define _RESTART_PSW_MASK 0x0000000180000000
#define _EXT_PSW_MASK 0x0400000180000000
#define _PGM_PSW_MASK 0x0400000180000000
#define _SVC_PSW_MASK 0x0400000180000000
#define _MCCK_PSW_MASK 0x0400000180000000
#define _IO_PSW_MASK 0x0400000180000000
#define _USER_PSW_MASK 0x0705C00180000000
#define _WAIT_PSW_MASK 0x0706000180000000
#define _DW_PSW_MASK 0x0002000180000000
#define _PRIMARY_MASK 0x0000 /* MASK for SACF */
#define _SECONDARY_MASK 0x0100 /* MASK for SACF */
#define _ACCESS_MASK 0x0200 /* MASK for SACF */
#define _HOME_MASK 0x0300 /* MASK for SACF */
#define _PSW_PRIM_SPACE_MODE 0x0000000000000000
#define _PSW_SEC_SPACE_MODE 0x0000800000000000
#define _PSW_ACC_REG_MODE 0x0000400000000000
#define _PSW_HOME_SPACE_MODE 0x0000C00000000000
#define _PSW_WAIT_MASK_BIT 0x0002000000000000
#define _PSW_IO_MASK_BIT 0x0200000000000000
#define _PSW_IO_WAIT 0x0202000000000000
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/config.h> #include <linux/config.h>
......
...@@ -111,13 +111,13 @@ typedef struct thread_struct thread_struct; ...@@ -111,13 +111,13 @@ typedef struct thread_struct thread_struct;
/* need to define ... */ /* need to define ... */
#define start_thread(regs, new_psw, new_stackp) do { \ #define start_thread(regs, new_psw, new_stackp) do { \
regs->psw.mask = _USER_PSW_MASK; \ regs->psw.mask = PSW_USER_BITS; \
regs->psw.addr = new_psw; \ regs->psw.addr = new_psw; \
regs->gprs[15] = new_stackp; \ regs->gprs[15] = new_stackp; \
} while (0) } while (0)
#define start_thread31(regs, new_psw, new_stackp) do { \ #define start_thread31(regs, new_psw, new_stackp) do { \
regs->psw.mask = _USER_PSW_MASK & ~(1L << 32); \ regs->psw.mask = PSW_USER32_BITS; \
regs->psw.addr = new_psw; \ regs->psw.addr = new_psw; \
regs->gprs[15] = new_stackp; \ regs->gprs[15] = new_stackp; \
} while (0) } while (0)
...@@ -153,19 +153,6 @@ unsigned long get_wchan(struct task_struct *p); ...@@ -153,19 +153,6 @@ unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier() #define cpu_relax() barrier()
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
/* Only let our hackers near the condition codes */
#define PSW_MASK_DEBUGCHANGE 0x0000300000000000UL
/* Don't let em near the addressing mode either */
#define PSW_ADDR_DEBUGCHANGE 0xFFFFFFFFFFFFFFFFUL
#define PSW_ADDR_MASK 0xFFFFFFFFFFFFFFFFUL
/* Program event recording mask */
#define PSW_PER_MASK 0x4000000000000000UL
#define USER_STD_MASK 0x0000000000000080UL
#define PSW_PROBLEM_STATE 0x0001000000000000UL
/* /*
* Set PSW mask to specified value, while leaving the * Set PSW mask to specified value, while leaving the
* PSW addr pointing to the next instruction. * PSW addr pointing to the next instruction.
...@@ -194,7 +181,8 @@ static inline void enabled_wait(void) ...@@ -194,7 +181,8 @@ static inline void enabled_wait(void)
unsigned long reg; unsigned long reg;
psw_t wait_psw; psw_t wait_psw;
wait_psw.mask = 0x0706000180000000; wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
PSW_MASK_MCHECK | PSW_MASK_WAIT;
asm volatile ( asm volatile (
" larl %0,0f\n" " larl %0,0f\n"
" stg %0,8(%1)\n" " stg %0,8(%1)\n"
...@@ -214,7 +202,7 @@ static inline void disabled_wait(addr_t code) ...@@ -214,7 +202,7 @@ static inline void disabled_wait(addr_t code)
psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1) psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1)
& -sizeof(psw_t)); & -sizeof(psw_t));
dw_psw->mask = 0x0002000180000000; dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT;
dw_psw->addr = code; dw_psw->addr = code;
/* /*
* Store status and then load disabled wait psw, * Store status and then load disabled wait psw,
......
...@@ -104,10 +104,33 @@ typedef struct ...@@ -104,10 +104,33 @@ typedef struct
__u64 addr; __u64 addr;
} __attribute__ ((aligned(8))) psw_t; } __attribute__ ((aligned(8))) psw_t;
#ifdef __KERNEL__ #define PSW_MASK_PER 0x4000000000000000UL
#define FIX_PSW(addr) ((unsigned long)(addr)) #define PSW_MASK_DAT 0x0400000000000000UL
#define ADDR_BITS_REMOVE(addr) ((addr)) #define PSW_MASK_IO 0x0200000000000000UL
#endif #define PSW_MASK_EXT 0x0100000000000000UL
#define PSW_MASK_KEY 0x00F0000000000000UL
#define PSW_MASK_MCHECK 0x0004000000000000UL
#define PSW_MASK_WAIT 0x0002000000000000UL
#define PSW_MASK_PSTATE 0x0001000000000000UL
#define PSW_MASK_ASC 0x0000C00000000000UL
#define PSW_MASK_CC 0x0000300000000000UL
#define PSW_MASK_PM 0x00000F0000000000UL
#define PSW_BASE_BITS 0x0000000180000000UL
#define PSW_BASE32_BITS 0x0000000080000000UL
#define PSW_ASC_PRIMARY 0x0000000000000000UL
#define PSW_ASC_ACCREG 0x0000400000000000UL
#define PSW_ASC_SECONDARY 0x0000800000000000UL
#define PSW_ASC_HOME 0x0000C00000000000UL
#define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY)
#define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \
PSW_MASK_PSTATE)
#define PSW_USER32_BITS (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \
PSW_MASK_PSTATE)
typedef union typedef union
{ {
...@@ -309,7 +332,7 @@ struct user_regs_struct ...@@ -309,7 +332,7 @@ struct user_regs_struct
}; };
#ifdef __KERNEL__ #ifdef __KERNEL__
#define user_mode(regs) (((regs)->psw.mask & PSW_PROBLEM_STATE) != 0) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr) #define instruction_pointer(regs) ((regs)->psw.addr)
extern void show_regs(struct pt_regs * regs); extern void show_regs(struct pt_regs * regs);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment