diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-02-11 15:31:24 +0100 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-15 18:45:49 +0100 |
commit | 5c39c0ab5e862cf71cda1fc39a5cedd4e2f18c6e (patch) | |
tree | 5241b832c2e64f581b55bb8c56bf3cb49836423b /arch/arc/include/asm/ptrace.h | |
parent | ARC: Signal handling (diff) | |
download | linux-5c39c0ab5e862cf71cda1fc39a5cedd4e2f18c6e.tar.xz linux-5c39c0ab5e862cf71cda1fc39a5cedd4e2f18c6e.zip |
ARC: [Review] Preparing to fix incorrect syscall restarts due to signals
To avoid multiple syscall restarts (multiple signals) or no restart at
all (sigreturn), we need just an extra bit of state "literally 1 bit" in
struct pt_regs. orig_r8 is the best place to do this, however given the
way it is encoded currently, we can't add anything simplistically.
Current orig_r8:
* syscalls -> 1 to NR_SYSCALLS
* Exceptions -> NR_SYSCALLS + 1
* Break-point-> NR_SYSCALLS + 2
In new scheme it is a bit-field
* lower short word contains the exact event type (and a new bit to represent
restart semantics : if syscall was already / can't be restarted)
* upper short word optionally containing the syscall num - needed by
likes of tracehooks etc
This patch only changes how orig_r8 is organised and nothing should
change behaviourily.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Diffstat (limited to 'arch/arc/include/asm/ptrace.h')
-rw-r--r-- | arch/arc/include/asm/ptrace.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 3afadefe335f..3ec89f467ac3 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -50,7 +50,17 @@ struct pt_regs { long r0; long sp; /* user/kernel sp depending on where we came from */ long orig_r0; - long orig_r8; /*to distinguish bet excp, sys call, int1 or int2 */ + + /*to distinguish bet excp, syscall, irq */ + union { +#ifdef CONFIG_CPU_BIG_ENDIAN + /* so that assembly code is same for LE/BE */ + unsigned long orig_r8:16, event:16; +#else + unsigned long event:16, orig_r8:16; +#endif + long orig_r8_word; + }; }; /* Callee saved registers - need to be saved only when you are scheduled out */ @@ -87,9 +97,8 @@ struct callee_regs { sp; \ }) -/* return 1 if in syscall, 0 if Intr or Exception */ -#define in_syscall(regs) (((regs->orig_r8) >= 0 && \ - (regs->orig_r8 <= NR_syscalls)) ? 1 : 0) +#define in_syscall(regs) (regs->event & orig_r8_IS_SCALL) +#define in_brkpt_trap(regs) (regs->event & orig_r8_IS_BRKPT) #define current_pt_regs() \ ({ \ @@ -101,6 +110,13 @@ struct callee_regs { #endif /* !__ASSEMBLY__ */ +#define orig_r8_IS_SCALL 0x0001 +#define orig_r8_IS_SCALL_RESTARTED 0x0002 +#define orig_r8_IS_BRKPT 0x0004 +#define orig_r8_IS_EXCPN 0x0004 +#define orig_r8_IS_IRQ1 0x0010 +#define orig_r8_IS_IRQ2 0x0020 + #endif /* __KERNEL__ */ #ifndef __ASSEMBLY__ |