Skip to content

Commit 74fca9d

Browse files
arch/tile: Change struct sigcontext to be more useful
Rather than just using pt_regs, it now contains the actual saved state explicitly, similar to pt_regs. By doing it this way, we provide a cleaner API for userspace (or equivalently, we avoid the need for libc to provide its own definition of sigcontext). While we're at it, move PT_FLAGS_xxx to where they are not visible from userspace. And always pass siginfo and mcontext to signal handlers, even if they claim they don't need it, since sometimes they actually try to use it anyway in practice. Signed-off-by: Chris Metcalf <[email protected]>
1 parent e6e6c46 commit 74fca9d

File tree

5 files changed

+36
-27
lines changed

5 files changed

+36
-27
lines changed

arch/tile/include/asm/ptrace.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,7 @@ typedef uint_reg_t pt_reg_t;
5151

5252
/*
5353
* This struct defines the way the registers are stored on the stack during a
54-
* system call/exception. It should be a multiple of 8 bytes to preserve
55-
* normal stack alignment rules.
56-
*
57-
* Must track <sys/ucontext.h> and <sys/procfs.h>
54+
* system call or exception. "struct sigcontext" has the same shape.
5855
*/
5956
struct pt_regs {
6057
/* Saved main processor registers; 56..63 are special. */
@@ -80,11 +77,6 @@ struct pt_regs {
8077

8178
#endif /* __ASSEMBLY__ */
8279

83-
/* Flag bits in pt_regs.flags */
84-
#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */
85-
#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */
86-
#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */
87-
8880
#define PTRACE_GETREGS 12
8981
#define PTRACE_SETREGS 13
9082
#define PTRACE_GETFPREGS 14
@@ -101,6 +93,11 @@ struct pt_regs {
10193

10294
#ifdef __KERNEL__
10395

96+
/* Flag bits in pt_regs.flags */
97+
#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */
98+
#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */
99+
#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */
100+
104101
#ifndef __ASSEMBLY__
105102

106103
#define instruction_pointer(regs) ((regs)->pc)

arch/tile/include/asm/sigcontext.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,21 @@
1515
#ifndef _ASM_TILE_SIGCONTEXT_H
1616
#define _ASM_TILE_SIGCONTEXT_H
1717

18-
/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */
19-
#include <asm/ptrace.h>
20-
21-
/* Must track <sys/ucontext.h> */
18+
#include <arch/abi.h>
2219

20+
/*
21+
* struct sigcontext has the same shape as struct pt_regs,
22+
* but is simplified since we know the fault is from userspace.
23+
*/
2324
struct sigcontext {
24-
struct pt_regs regs;
25+
uint_reg_t gregs[53]; /* General-purpose registers. */
26+
uint_reg_t tp; /* Aliases gregs[TREG_TP]. */
27+
uint_reg_t sp; /* Aliases gregs[TREG_SP]. */
28+
uint_reg_t lr; /* Aliases gregs[TREG_LR]. */
29+
uint_reg_t pc; /* Program counter. */
30+
uint_reg_t ics; /* In Interrupt Critical Section? */
31+
uint_reg_t faultnum; /* Fault number. */
32+
uint_reg_t pad[5];
2533
};
2634

2735
#endif /* _ASM_TILE_SIGCONTEXT_H */

arch/tile/include/asm/signal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <asm-generic/signal.h>
2525

2626
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
27+
struct pt_regs;
2728
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
2829
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
2930
void do_signal(struct pt_regs *regs);

arch/tile/kernel/signal.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,19 @@ int restore_sigcontext(struct pt_regs *regs,
6161
/* Always make any pending restarted system calls return -EINTR */
6262
current_thread_info()->restart_block.fn = do_no_restart_syscall;
6363

64+
/*
65+
* Enforce that sigcontext is like pt_regs, and doesn't mess
66+
* up our stack alignment rules.
67+
*/
68+
BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs));
69+
BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0);
70+
6471
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
65-
err |= __get_user(((long *)regs)[i],
66-
&((long __user *)(&sc->regs))[i]);
72+
err |= __get_user(regs->regs[i], &sc->gregs[i]);
6773

6874
regs->faultnum = INT_SWINT_1_SIGRETURN;
6975

70-
err |= __get_user(*pr0, &sc->regs.regs[0]);
76+
err |= __get_user(*pr0, &sc->gregs[0]);
7177
return err;
7278
}
7379

@@ -112,8 +118,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
112118
int i, err = 0;
113119

114120
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
115-
err |= __put_user(((long *)regs)[i],
116-
&((long __user *)(&sc->regs))[i]);
121+
err |= __put_user(regs->regs[i], &sc->gregs[i]);
117122

118123
return err;
119124
}
@@ -203,19 +208,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
203208
* Set up registers for signal handler.
204209
* Registers that we don't modify keep the value they had from
205210
* user-space at the time we took the signal.
211+
* We always pass siginfo and mcontext, regardless of SA_SIGINFO,
212+
* since some things rely on this (e.g. glibc's debug/segfault.c).
206213
*/
207214
regs->pc = (unsigned long) ka->sa.sa_handler;
208215
regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
209216
regs->sp = (unsigned long) frame;
210217
regs->lr = restorer;
211218
regs->regs[0] = (unsigned long) usig;
212-
213-
if (ka->sa.sa_flags & SA_SIGINFO) {
214-
/* Need extra arguments, so mark to restore caller-saves. */
215-
regs->regs[1] = (unsigned long) &frame->info;
216-
regs->regs[2] = (unsigned long) &frame->uc;
217-
regs->flags |= PT_FLAGS_CALLER_SAVES;
218-
}
219+
regs->regs[1] = (unsigned long) &frame->info;
220+
regs->regs[2] = (unsigned long) &frame->uc;
221+
regs->flags |= PT_FLAGS_CALLER_SAVES;
219222

220223
/*
221224
* Notify any tracer that was single-stepping it.

arch/tile/kernel/stack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
175175
pr_err(" <received signal %d>\n",
176176
frame->info.si_signo);
177177
}
178-
return &frame->uc.uc_mcontext.regs;
178+
return (struct pt_regs *)&frame->uc.uc_mcontext;
179179
}
180180
return NULL;
181181
}

0 commit comments

Comments
 (0)