aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-02-11 09:31:24 -0500
committerVineet Gupta <vgupta@synopsys.com>2013-02-15 12:45:49 -0500
commit5c39c0ab5e862cf71cda1fc39a5cedd4e2f18c6e (patch)
tree5241b832c2e64f581b55bb8c56bf3cb49836423b /arch/arc
parentc3581039b6c51a778a70accec53a9bb7ad9a4d32 (diff)
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')
-rw-r--r--arch/arc/include/asm/entry.h29
-rw-r--r--arch/arc/include/asm/ptrace.h24
-rw-r--r--arch/arc/kernel/asm-offsets.c2
-rw-r--r--arch/arc/kernel/entry.S4
4 files changed, 40 insertions, 19 deletions
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h
index 6b42bf5c45ec..9eada5b28be6 100644
--- a/arch/arc/include/asm/entry.h
+++ b/arch/arc/include/asm/entry.h
@@ -343,18 +343,12 @@
343 *-------------------------------------------------------------*/ 343 *-------------------------------------------------------------*/
344.macro SAVE_ALL_EXCEPTION marker 344.macro SAVE_ALL_EXCEPTION marker
345 345
346 st \marker, [sp, 8]
347 st r0, [sp, 4] /* orig_r0, needed only for sys calls */
348
346 /* Restore r9 used to code the early prologue */ 349 /* Restore r9 used to code the early prologue */
347 EXCPN_PROLOG_RESTORE_REG r9 350 EXCPN_PROLOG_RESTORE_REG r9
348 351
349 /* Save the complete regfile now */
350
351 /* orig_r8 marker:
352 * syscalls -> 1 to NR_SYSCALLS
353 * Exceptions -> NR_SYSCALLS + 1
354 * Break-point-> NR_SYSCALLS + 2
355 */
356 st \marker, [sp, 8]
357 st r0, [sp, 4] /* orig_r0, needed only for sys calls */
358 SAVE_CALLER_SAVED 352 SAVE_CALLER_SAVED
359 st.a r26, [sp, -4] /* gp */ 353 st.a r26, [sp, -4] /* gp */
360 st.a fp, [sp, -4] 354 st.a fp, [sp, -4]
@@ -384,14 +378,25 @@
384 * Save scratch regs for exceptions 378 * Save scratch regs for exceptions
385 *-------------------------------------------------------------*/ 379 *-------------------------------------------------------------*/
386.macro SAVE_ALL_SYS 380.macro SAVE_ALL_SYS
387 SAVE_ALL_EXCEPTION (NR_syscalls + 1) 381 SAVE_ALL_EXCEPTION orig_r8_IS_EXCPN
388.endm 382.endm
389 383
390/*-------------------------------------------------------------- 384/*--------------------------------------------------------------
391 * Save scratch regs for sys calls 385 * Save scratch regs for sys calls
392 *-------------------------------------------------------------*/ 386 *-------------------------------------------------------------*/
393.macro SAVE_ALL_TRAP 387.macro SAVE_ALL_TRAP
394 SAVE_ALL_EXCEPTION r8 388 /*
389 * Setup pt_regs->orig_r8.
390 * Encode syscall number (r8) in upper short word of event type (r9)
391 * N.B. #1: This is already endian safe (see ptrace.h)
392 * #2: Only r9 can be used as scratch as it is already clobbered
393 * and it's contents are no longer needed by the latter part
394 * of exception prologue
395 */
396 lsl r9, r8, 16
397 or r9, r9, orig_r8_IS_SCALL
398
399 SAVE_ALL_EXCEPTION r9
395.endm 400.endm
396 401
397/*-------------------------------------------------------------- 402/*--------------------------------------------------------------
@@ -442,7 +447,7 @@
442 ld r9, [@int1_saved_reg] 447 ld r9, [@int1_saved_reg]
443 448
444 /* now we are ready to save the remaining context :) */ 449 /* now we are ready to save the remaining context :) */
445 st -1, [sp, 8] /* orig_r8, -1 for interuppt level one */ 450 st orig_r8_IS_IRQ1, [sp, 8] /* Event Type */
446 st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ 451 st 0, [sp, 4] /* orig_r0 , N/A for IRQ */
447 SAVE_CALLER_SAVED 452 SAVE_CALLER_SAVED
448 st.a r26, [sp, -4] /* gp */ 453 st.a r26, [sp, -4] /* gp */
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 {
50 long r0; 50 long r0;
51 long sp; /* user/kernel sp depending on where we came from */ 51 long sp; /* user/kernel sp depending on where we came from */
52 long orig_r0; 52 long orig_r0;
53 long orig_r8; /*to distinguish bet excp, sys call, int1 or int2 */ 53
54 /*to distinguish bet excp, syscall, irq */
55 union {
56#ifdef CONFIG_CPU_BIG_ENDIAN
57 /* so that assembly code is same for LE/BE */
58 unsigned long orig_r8:16, event:16;
59#else
60 unsigned long event:16, orig_r8:16;
61#endif
62 long orig_r8_word;
63 };
54}; 64};
55 65
56/* Callee saved registers - need to be saved only when you are scheduled out */ 66/* Callee saved registers - need to be saved only when you are scheduled out */
@@ -87,9 +97,8 @@ struct callee_regs {
87 sp; \ 97 sp; \
88}) 98})
89 99
90/* return 1 if in syscall, 0 if Intr or Exception */ 100#define in_syscall(regs) (regs->event & orig_r8_IS_SCALL)
91#define in_syscall(regs) (((regs->orig_r8) >= 0 && \ 101#define in_brkpt_trap(regs) (regs->event & orig_r8_IS_BRKPT)
92 (regs->orig_r8 <= NR_syscalls)) ? 1 : 0)
93 102
94#define current_pt_regs() \ 103#define current_pt_regs() \
95({ \ 104({ \
@@ -101,6 +110,13 @@ struct callee_regs {
101 110
102#endif /* !__ASSEMBLY__ */ 111#endif /* !__ASSEMBLY__ */
103 112
113#define orig_r8_IS_SCALL 0x0001
114#define orig_r8_IS_SCALL_RESTARTED 0x0002
115#define orig_r8_IS_BRKPT 0x0004
116#define orig_r8_IS_EXCPN 0x0004
117#define orig_r8_IS_IRQ1 0x0010
118#define orig_r8_IS_IRQ2 0x0020
119
104#endif /* __KERNEL__ */ 120#endif /* __KERNEL__ */
105 121
106#ifndef __ASSEMBLY__ 122#ifndef __ASSEMBLY__
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c
index 64b2c2fa7b54..d7770cc9aee3 100644
--- a/arch/arc/kernel/asm-offsets.c
+++ b/arch/arc/kernel/asm-offsets.c
@@ -46,7 +46,7 @@ int main(void)
46 BLANK(); 46 BLANK();
47 47
48 DEFINE(PT_status32, offsetof(struct pt_regs, status32)); 48 DEFINE(PT_status32, offsetof(struct pt_regs, status32));
49 DEFINE(PT_orig_r8, offsetof(struct pt_regs, orig_r8)); 49 DEFINE(PT_orig_r8, offsetof(struct pt_regs, orig_r8_word));
50 DEFINE(PT_sp, offsetof(struct pt_regs, sp)); 50 DEFINE(PT_sp, offsetof(struct pt_regs, sp));
51 DEFINE(PT_r0, offsetof(struct pt_regs, r0)); 51 DEFINE(PT_r0, offsetof(struct pt_regs, r0));
52 DEFINE(PT_r1, offsetof(struct pt_regs, r1)); 52 DEFINE(PT_r1, offsetof(struct pt_regs, r1));
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index d625b77c14bd..ce8670da8306 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -350,8 +350,8 @@ ARC_EXIT EV_Extension
350 350
351trap_with_param: 351trap_with_param:
352 352
353 ;make sure orig_r8 is a positive value 353 ; stop_pc info by gdb needs this info
354 st NR_syscalls + 2, [sp, PT_orig_r8] 354 st orig_r8_IS_BRKPT, [sp, PT_orig_r8]
355 355
356 mov r0, r12 356 mov r0, r12
357 lr r1, [efa] 357 lr r1, [efa]