aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-27 05:23:46 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-27 05:23:46 -0400
commit17888225c2f392bfdbac6c7f0713cbd9a4d02b05 (patch)
treecf11f005d3a973be9fd06eec243ded4b776c1502 /arch
parent3c789a19054034847afe80af2f23ebb0eebfbad6 (diff)
Fix missing audit_syscall_exit() on ppc64 sigsuspend exit path
When we leave sigsuspend() directly into a signal handler, we don't want to go via the normal syscall exit path -- it'll corrupt r4 and r5 which are supposed to be giving information to the signal handler, and it'll give us one more single-step SIGTRAP than we need if single-stepping is in operation. However, we _should_ be calling audit_syscall_exit(), which would normally get invoked in that patch. It's not wonderfully pretty, but I suspect the best answer is just to call it directly... Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/ppc64/kernel/asm-offsets.c1
-rw-r--r--arch/ppc64/kernel/entry.S16
2 files changed, 13 insertions, 4 deletions
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index abb9e5b5da03..6f910fa2746f 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -68,6 +68,7 @@ int main(void)
68 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); 68 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
69#endif /* CONFIG_ALTIVEC */ 69#endif /* CONFIG_ALTIVEC */
70 DEFINE(MM, offsetof(struct task_struct, mm)); 70 DEFINE(MM, offsetof(struct task_struct, mm));
71 DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
71 72
72 DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size)); 73 DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
73 DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size)); 74 DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
index b61572eb2a71..ae5d563ad93a 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/ppc64/kernel/entry.S
@@ -276,12 +276,20 @@ _GLOBAL(ppc64_rt_sigsuspend)
276_GLOBAL(ppc32_rt_sigsuspend) 276_GLOBAL(ppc32_rt_sigsuspend)
277 bl .save_nvgprs 277 bl .save_nvgprs
278 bl .sys32_rt_sigsuspend 278 bl .sys32_rt_sigsuspend
279 /* If sigsuspend() returns zero, we are going into a signal handler */
28070: cmpdi 0,r3,0 27970: cmpdi 0,r3,0
281 beq .ret_from_except 280 /* If it returned an error, we need to return via syscall_exit to set
282 /* If it returned -EINTR, we need to return via syscall_exit to set
283 the SO bit in cr0 and potentially stop for ptrace. */ 281 the SO bit in cr0 and potentially stop for ptrace. */
284 b syscall_exit 282 bne syscall_exit
283 /* If sigsuspend() returns zero, we are going into a signal handler. We
284 may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
285 ld r3,PACACURRENT(r13)
286 ld r4,AUDITCONTEXT(r3)
287 cmpdi 0,r4,0
288 beq .ret_from_except /* No audit_context: Leave immediately. */
289 li r4, 2 /* AUDITSC_FAILURE */
290 li r5,-4 /* It's always -EINTR */
291 bl .audit_syscall_exit
292 b .ret_from_except
285 293
286_GLOBAL(ppc_fork) 294_GLOBAL(ppc_fork)
287 bl .save_nvgprs 295 bl .save_nvgprs