From: Corey Minyard <minyard@acm.org>
To: linuxppc-dev@lists.linuxppc.org
Cc: paulus@samba.org
Subject: Re: Change to allow signal handlers to set SE and BE bits.
Date: Tue, 09 Sep 2003 14:19:46 -0500 [thread overview]
Message-ID: <3F5E27D2.3090808@acm.org> (raw)
In-Reply-To: <3F58AA89.80803@acm.org>
[-- Attachment #1: Type: text/plain, Size: 2208 bytes --]
Paul came up with a much better method for this. I have added a syscall
that does a "debug" return from the signal handler. It's much cleaner.
I ahve a patch for this, and I've done a number of things besides just
this. I seemed bad to me to add yet another kludge to the beginning of
DoSyscall for handling yet another signal return value. So I turned all
the signal return syscalls into normal syscalls. This should speed up
normal syscall handling by removing four instructions from the syscall
entry. Is this ok?
I added some new syscalls for each sigreturn option, but there were
already some more that would obviously not work for this. Should I
convert the others over to work correctly, or should I leave these like
they are?
I made the interface to the debug sigreturn extensible, it takes an
array of two-member structures, where the first member is a debug type
and the second is a debug value. This should allow a lot of flexibility
for adding new things (probably a lot more than is required).
I also brought the syscall table in asm/unistd.h up to date.
I've got some code for setting dabr from userland and causing traps. I
could work it into this if someone is interested. It involves some
complicated code at exception entry.
-Corey
Corey Minyard wrote:
> Here's an example patch (that I have tested) that shows the use of the
> top 16 bits of the trap field as communication between the signal
> handler and the kernel.
>
> -Corey
>
> Corey Minyard wrote:
>
>>
>> Actually, using the SE bit may not be the best way to handle this to
>> cover all the PPC variants.
>>
>> Would it be better to have a special bit field someplace that is used to
>> communicate between the signal handler and the kernel? Some
>> possibilities are:
>>
>> * The top 16 bits of the trap field
>> * The currently unused mq field (except on APUS?)
>> * A new field in the signal frame
>>
>> I'm thinking that reserving the top 16 bits of the trap field may be the
>> best. It would always come in as zero (so existing software won't be
>> broken) and it will be available for all processors and will not be used
>> for anything else by the processor.
>>
>> Any thoughts?
>>
>> -Corey
>
[-- Attachment #2: dbg_sig_ppc.diff --]
[-- Type: text/plain, Size: 7375 bytes --]
--- arch/ppc/kernel/signal.c.old 2003-08-28 15:30:37.000000000 -0500
+++ arch/ppc/kernel/signal.c 2003-09-09 14:13:37.000000000 -0500
@@ -383,7 +383,7 @@
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- if (save_user_regs(regs, frame, 0x6666, 0))
+ if (save_user_regs(regs, frame, __NR_kern_rt_sigreturn, 0))
goto badframe;
if (put_user(regs->gpr[1], (unsigned long *)newsp))
@@ -461,15 +461,13 @@
return 0;
}
-int sys_rt_sigreturn(struct pt_regs *regs)
+int rt_sigreturn(struct ucontext *uc, struct pt_regs *regs)
{
- struct rt_sigframe *rt_sf;
stack_t st;
- rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
- if (verify_area(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
+ if (verify_area(VERIFY_READ, uc, sizeof(struct ucontext)))
goto bad;
- if (do_setcontext(&rt_sf->uc, regs, 0))
+ if (do_setcontext(uc, regs, 0))
goto bad;
/*
@@ -479,7 +477,7 @@
* always done it up until now so it is probably better not to
* change it. -- paulus
*/
- if (__copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
+ if (__copy_from_user(&st, &uc->uc_stack, sizeof(st)))
goto bad;
do_sigaltstack(&st, NULL, regs->gpr[1]);
@@ -489,6 +487,61 @@
do_exit(SIGSEGV);
}
+int sys_rt_sigreturn(struct pt_regs *regs)
+{
+ struct rt_sigframe *rt_sf;
+
+ rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
+ return rt_sigreturn(&rt_sf->uc, regs);
+}
+
+int sys_dbg_sigreturn(struct ucontext *uc, int ndbg, struct sig_dbg_op *dbg,
+ struct pt_regs *regs)
+{
+ struct sig_dbg_op op;
+ int i;
+
+ for (i=0; i<ndbg; i++) {
+ if (__copy_from_user(&op, dbg, sizeof(op)))
+ return -EFAULT;
+ switch (op.dbg_type) {
+ case SIG_DBG_SINGLE_STEPPING:
+#if defined(CONFIG_4xx)
+ if (op.dbg_value) {
+ regs->msr |= MSR_DE;
+ current->thread.dbcr0 |= (DBCR0_IDM | DBCR0_IC);
+ } else {
+ regs->msr &= ~MSR_DE;
+ current->thread.dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+ regs->msr &= ~MSR_SE;
+ }
+#else
+ if (op.dbg_value)
+ regs->msr |= MSR_SE;
+ else
+ regs->msr &= ~MSR_SE;
+#endif
+ break;
+
+ case SIG_DBG_BRANCH_TRACING:
+#if defined(CONFIG_4xx)
+ return -EINVAL;
+#else
+ if (op.dbg_value)
+ regs->msr |= MSR_BE;
+ else
+ regs->msr &= ~MSR_BE;
+#endif
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return rt_sigreturn(uc, regs);
+}
+
/*
* OK, we're invoking a handler
*/
@@ -525,7 +578,7 @@
|| __put_user(sig, &sc->signal))
goto badframe;
- if (save_user_regs(regs, &frame->mctx, 0x7777, 0))
+ if (save_user_regs(regs, &frame->mctx, __NR_kern_sigreturn, 0))
goto badframe;
if (put_user(regs->gpr[1], (unsigned long *)newsp))
--- arch/ppc/kernel/traps.c.old 2003-08-28 15:42:26.000000000 -0500
+++ arch/ppc/kernel/traps.c 2003-09-05 09:15:47.000000000 -0500
@@ -396,7 +396,7 @@
void
SingleStepException(struct pt_regs *regs)
{
- regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
+ regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */
if (debugger_sstep(regs))
return;
_exception(SIGTRAP, regs, TRAP_TRACE, 0);
--- arch/ppc/kernel/entry.S.old 2003-08-31 04:39:10.000000000 -0500
+++ arch/ppc/kernel/entry.S 2003-09-09 09:39:53.000000000 -0500
@@ -80,10 +80,6 @@
lwz r8,GPR8(r1)
1:
#endif /* SHOW_SYSCALLS */
- cmpi 0,r0,0x7777 /* Special case for 'sys_sigreturn' */
- beq- 10f
- cmpi 0,r0,0x6666 /* Special case for 'sys_rt_sigreturn' */
- beq- 16f
lwz r10,TASK_PTRACE(r2)
andi. r10,r10,PT_TRACESYS
bne- 50f
@@ -100,7 +96,7 @@
blrl /* Call handler */
.globl ret_from_syscall_1
ret_from_syscall_1:
-20: stw r3,RESULT(r1) /* Save result */
+ stw r3,RESULT(r1) /* Save result */
#ifdef SHOW_SYSCALLS
#ifdef SHOW_SYSCALLS_TASK
cmp 0,r2,r31
@@ -127,18 +123,6 @@
b ret_from_except
66: li r3,ENOSYS
b 22b
-/* sys_sigreturn */
-10: addi r3,r1,STACK_FRAME_OVERHEAD
- bl sys_sigreturn
- cmpi 0,r3,0 /* Check for restarted system call */
- bge ret_from_except
- b 20b
-/* sys_rt_sigreturn */
-16: addi r3,r1,STACK_FRAME_OVERHEAD
- bl sys_rt_sigreturn
- cmpi 0,r3,0 /* Check for restarted system call */
- bge ret_from_except
- b 20b
/* Traced system call support */
50: bl syscall_trace
lwz r0,GPR0(r1) /* Restore original registers */
--- arch/ppc/kernel/misc.S.old 2003-08-31 04:39:09.000000000 -0500
+++ arch/ppc/kernel/misc.S 2003-09-09 10:14:43.000000000 -0500
@@ -1034,6 +1034,37 @@
_GLOBAL(__main)
blr
+_sys_sigreturn:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ mflr r30
+ bl sys_sigreturn
+ cmpi 0,r3,0 /* Check for restarted system call */
+ bge ret_from_except
+ mtlr r30
+ blr
+
+_sys_rt_sigreturn:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ mflr r30
+ bl sys_rt_sigreturn
+ cmpi 0,r3,0 /* Check for restarted system call */
+ bge ret_from_except
+ mtlr r30
+ blr
+
+/*
+ * This handles the special case of the debug sigreturn call, which needs
+ * the registers in order to do its job.
+ */
+_sys_dbg_sigreturn:
+ addi r6,r1,STACK_FRAME_OVERHEAD
+ mflr r30
+ bl sys_dbg_sigreturn
+ cmpi 0,r3,0 /* Check for restarted system call */
+ bge ret_from_except
+ mtlr r30
+ blr
+
#define SYSCALL(name) \
_GLOBAL(name) \
li r0,__NR_##name; \
@@ -1314,6 +1345,9 @@
.long sys_ni_syscall /* reserved for sys_clock_getres */
.long sys_ni_syscall /* reserved for sys_clock_nanosleep */
.long sys_swapcontext
+ .long _sys_sigreturn /* 250 */
+ .long _sys_rt_sigreturn
+ .long _sys_dbg_sigreturn
.rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
--- include/asm-ppc/signal.h.old 2003-09-09 11:29:59.000000000 -0500
+++ include/asm-ppc/signal.h 2003-09-09 13:29:49.000000000 -0500
@@ -152,4 +152,23 @@
#include <asm/sigcontext.h>
#endif /* __KERNEL__ */
+/*
+ * These are parameters to dbg_sigreturn syscall. They enable or
+ * disable certain debugging things that can be done from signal
+ * handlers. The dbg_sigreturn syscall *must* be called from a
+ * SA_SIGINFO signal so the ucontext can be passed to it. It takes an
+ * array of struct sig_dbg_op, which has the debug operations to
+ * perform before returning from the signal.
+ */
+struct sig_dbg_op {
+ int dbg_type;
+ unsigned long dbg_value;
+};
+
+/* Enable or disable single-stepping. The value sets the state. */
+#define SIG_DBG_SINGLE_STEPPING 1
+
+/* Enable or disable branch tracing. The value sets the state. */
+#define SIG_DBG_BRANCH_TRACING 2
+
#endif
--- include/asm-ppc/unistd.h.old 2003-08-31 04:41:10.000000000 -0500
+++ include/asm-ppc/unistd.h 2003-09-09 13:20:11.000000000 -0500
@@ -237,7 +237,28 @@
#define __NR_io_getevents 229
#define __NR_io_submit 230
#define __NR_io_cancel 231
+#define __NR_set_tid_address 232
+#define __NR_fadvise64 233
+#define __NR_exit_group 234
+#define __NR_lookup_dcookie 235
+#define __NR_epoll_create 236
+#define __NR_epoll_ctl 237
+#define __NR_epoll_wait 238
+#define __NR_remap_file_pages 239
+#define __NR_timer_create 240
+#define __NR_timer_settime 241
+#define __NR_timer_gettime 242
+#define __NR_timer_getoverrun 243
+#define __NR_timer_delete 244
+#define __NR_clock_settime 245
+#define __NR_clock_gettime 246
+#define __NR_clock_getres 247
+#define __NR_clock_nanosleep 248
#endif
+#define __NR_swapcontext 249
+#define __NR_kern_sigreturn 250
+#define __NR_kern_rt_sigreturn 251
+#define __NR_dbg_sigreturn 252
#define __NR(n) #n
next prev parent reply other threads:[~2003-09-09 19:19 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-08-29 20:00 Change to allow signal handlers to set SE and BE bits Corey Minyard
2003-08-29 20:18 ` Matt Porter
2003-09-04 14:16 ` Corey Minyard
2003-09-05 15:23 ` Corey Minyard
2003-09-09 19:19 ` Corey Minyard [this message]
2003-09-09 19:39 ` Benjamin Herrenschmidt
2003-09-09 21:34 ` Corey Minyard
2003-09-10 1:37 ` Paul Mackerras
2003-09-10 2:47 ` Corey Minyard
2003-08-30 0:29 ` Paul Mackerras
2003-09-01 20:46 ` Corey Minyard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3F5E27D2.3090808@acm.org \
--to=minyard@acm.org \
--cc=linuxppc-dev@lists.linuxppc.org \
--cc=paulus@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.