diff options
Diffstat (limited to 'arch/parisc/kernel/syscall.S')
-rw-r--r-- | arch/parisc/kernel/syscall.S | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 5f7e57fcaeef..f453997a7b8f 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -108,12 +108,8 @@ linux_gateway_entry: mtsp %r0,%sr6 /* get kernel space into sr6 */ #ifdef CONFIG_64BIT - /* for now we can *always* set the W bit on entry to the syscall - * since we don't support wide userland processes. We could - * also save the current SM other than in r0 and restore it on - * exit from the syscall, and also use that value to know - * whether to do narrow or wide syscalls. -PB - */ + /* Store W bit on entry to the syscall in case it's a wide userland + * process. */ ssm PSW_SM_W, %r1 extrd,u %r1,PSW_W_BIT,1,%r1 /* sp must be aligned on 4, so deposit the W bit setting into @@ -227,8 +223,7 @@ linux_gateway_entry: or,= %r2,%r2,%r2 ldo R%sys_call_table64(%r1), %r19 #else - ldil L%sys_call_table, %r1 - ldo R%sys_call_table(%r1), %r19 + load32 sys_call_table, %r19 #endif comiclr,>> __NR_Linux_syscalls, %r20, %r0 b,n .Lsyscall_nosys @@ -331,8 +326,6 @@ tracesys_next: * task->thread.regs.gr[20] above. */ copy %ret0,%r20 - ldil L%sys_call_table,%r1 - ldo R%sys_call_table(%r1), %r19 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ LDREG TI_TASK(%r1), %r1 @@ -354,6 +347,23 @@ tracesys_next: comiclr,>> __NR_Linux_syscalls, %r20, %r0 b,n .Ltracesys_nosys + /* Note! We cannot use the syscall table that is mapped + nearby since the gateway page is mapped execute-only. */ + +#ifdef CONFIG_64BIT + LDREG TASK_PT_GR30(%r1), %r19 /* get users sp back */ + extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ + + ldil L%sys_call_table, %r1 + or,= %r2,%r2,%r2 + addil L%(sys_call_table64-sys_call_table), %r1 + ldo R%sys_call_table(%r1), %r19 + or,= %r2,%r2,%r2 + ldo R%sys_call_table64(%r1), %r19 +#else + load32 sys_call_table, %r19 +#endif + LDREGX %r20(%r19), %r19 /* If this is a sys_rt_sigreturn call, and the signal was received @@ -464,16 +474,13 @@ tracesys_sigexit: lws_start: #ifdef CONFIG_64BIT - /* FIXME: If we are a 64-bit kernel just - * turn this on unconditionally. - */ ssm PSW_SM_W, %r1 extrd,u %r1,PSW_W_BIT,1,%r1 /* sp must be aligned on 4, so deposit the W bit setting into * the bottom of sp temporarily */ or,ev %r1,%r30,%r30 - /* Clip LWS number to a 32-bit value always */ + /* Clip LWS number to a 32-bit value for 32-bit processes */ depdi 0, 31, 32, %r20 #endif |