diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2014-05-14 10:05:15 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-06-19 08:39:40 -0400 |
commit | 6ffb9c8c5f59a50779109e8b0a2e1bdd4b9be5c5 (patch) | |
tree | a6c124d9250e63241544227095df7b1c3a26ef56 | |
parent | 5a343b9fe22995c43b1209b0b63ea0fa2824cbae (diff) |
ARC: Make way for pt_regs != user_regs_struct
These have been register compatible so far. However ARCv2 mandates
different pt_regs layout (due to h/w auto save). To keep pt_regs same
for both, we start by removing the assumption - used mainly for block
copies between the 2 structs in signal handling and ptrace
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/kernel/ptrace.c | 90 | ||||
-rw-r--r-- | arch/arc/kernel/signal.c | 56 |
2 files changed, 137 insertions, 9 deletions
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index 13b3ffb27a38..4dd9e3a8c2da 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c | |||
@@ -47,10 +47,47 @@ static int genregs_get(struct task_struct *target, | |||
47 | offsetof(struct user_regs_struct, LOC) + 4); | 47 | offsetof(struct user_regs_struct, LOC) + 4); |
48 | 48 | ||
49 | REG_O_ZERO(pad); | 49 | REG_O_ZERO(pad); |
50 | REG_O_CHUNK(scratch, callee, ptregs); | 50 | REG_O_ONE(scratch.bta, &ptregs->bta); |
51 | REG_O_ONE(scratch.lp_start, &ptregs->lp_start); | ||
52 | REG_O_ONE(scratch.lp_end, &ptregs->lp_end); | ||
53 | REG_O_ONE(scratch.lp_count, &ptregs->lp_count); | ||
54 | REG_O_ONE(scratch.status32, &ptregs->status32); | ||
55 | REG_O_ONE(scratch.ret, &ptregs->ret); | ||
56 | REG_O_ONE(scratch.blink, &ptregs->blink); | ||
57 | REG_O_ONE(scratch.fp, &ptregs->fp); | ||
58 | REG_O_ONE(scratch.gp, &ptregs->r26); | ||
59 | REG_O_ONE(scratch.r12, &ptregs->r12); | ||
60 | REG_O_ONE(scratch.r11, &ptregs->r11); | ||
61 | REG_O_ONE(scratch.r10, &ptregs->r10); | ||
62 | REG_O_ONE(scratch.r9, &ptregs->r9); | ||
63 | REG_O_ONE(scratch.r8, &ptregs->r8); | ||
64 | REG_O_ONE(scratch.r7, &ptregs->r7); | ||
65 | REG_O_ONE(scratch.r6, &ptregs->r6); | ||
66 | REG_O_ONE(scratch.r5, &ptregs->r5); | ||
67 | REG_O_ONE(scratch.r4, &ptregs->r4); | ||
68 | REG_O_ONE(scratch.r3, &ptregs->r3); | ||
69 | REG_O_ONE(scratch.r2, &ptregs->r2); | ||
70 | REG_O_ONE(scratch.r1, &ptregs->r1); | ||
71 | REG_O_ONE(scratch.r0, &ptregs->r0); | ||
72 | REG_O_ONE(scratch.sp, &ptregs->sp); | ||
73 | |||
51 | REG_O_ZERO(pad2); | 74 | REG_O_ZERO(pad2); |
52 | REG_O_CHUNK(callee, efa, cregs); | 75 | |
53 | REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address); | 76 | REG_O_ONE(callee.r25, &cregs->r25); |
77 | REG_O_ONE(callee.r24, &cregs->r24); | ||
78 | REG_O_ONE(callee.r23, &cregs->r23); | ||
79 | REG_O_ONE(callee.r22, &cregs->r22); | ||
80 | REG_O_ONE(callee.r21, &cregs->r21); | ||
81 | REG_O_ONE(callee.r20, &cregs->r20); | ||
82 | REG_O_ONE(callee.r19, &cregs->r19); | ||
83 | REG_O_ONE(callee.r18, &cregs->r18); | ||
84 | REG_O_ONE(callee.r17, &cregs->r17); | ||
85 | REG_O_ONE(callee.r16, &cregs->r16); | ||
86 | REG_O_ONE(callee.r15, &cregs->r15); | ||
87 | REG_O_ONE(callee.r14, &cregs->r14); | ||
88 | REG_O_ONE(callee.r13, &cregs->r13); | ||
89 | |||
90 | REG_O_ONE(efa, &target->thread.fault_address); | ||
54 | 91 | ||
55 | if (!ret) { | 92 | if (!ret) { |
56 | if (in_brkpt_trap(ptregs)) { | 93 | if (in_brkpt_trap(ptregs)) { |
@@ -97,12 +134,51 @@ static int genregs_set(struct task_struct *target, | |||
97 | offsetof(struct user_regs_struct, LOC) + 4); | 134 | offsetof(struct user_regs_struct, LOC) + 4); |
98 | 135 | ||
99 | REG_IGNORE_ONE(pad); | 136 | REG_IGNORE_ONE(pad); |
100 | /* TBD: disallow updates to STATUS32 etc*/ | 137 | |
101 | REG_IN_CHUNK(scratch, pad2, ptregs); /* pt_regs[bta..sp] */ | 138 | REG_IN_ONE(scratch.bta, &ptregs->bta); |
139 | REG_IN_ONE(scratch.lp_start, &ptregs->lp_start); | ||
140 | REG_IN_ONE(scratch.lp_end, &ptregs->lp_end); | ||
141 | REG_IN_ONE(scratch.lp_count, &ptregs->lp_count); | ||
142 | |||
143 | REG_IGNORE_ONE(scratch.status32); | ||
144 | |||
145 | REG_IN_ONE(scratch.ret, &ptregs->ret); | ||
146 | REG_IN_ONE(scratch.blink, &ptregs->blink); | ||
147 | REG_IN_ONE(scratch.fp, &ptregs->fp); | ||
148 | REG_IN_ONE(scratch.gp, &ptregs->r26); | ||
149 | REG_IN_ONE(scratch.r12, &ptregs->r12); | ||
150 | REG_IN_ONE(scratch.r11, &ptregs->r11); | ||
151 | REG_IN_ONE(scratch.r10, &ptregs->r10); | ||
152 | REG_IN_ONE(scratch.r9, &ptregs->r9); | ||
153 | REG_IN_ONE(scratch.r8, &ptregs->r8); | ||
154 | REG_IN_ONE(scratch.r7, &ptregs->r7); | ||
155 | REG_IN_ONE(scratch.r6, &ptregs->r6); | ||
156 | REG_IN_ONE(scratch.r5, &ptregs->r5); | ||
157 | REG_IN_ONE(scratch.r4, &ptregs->r4); | ||
158 | REG_IN_ONE(scratch.r3, &ptregs->r3); | ||
159 | REG_IN_ONE(scratch.r2, &ptregs->r2); | ||
160 | REG_IN_ONE(scratch.r1, &ptregs->r1); | ||
161 | REG_IN_ONE(scratch.r0, &ptregs->r0); | ||
162 | REG_IN_ONE(scratch.sp, &ptregs->sp); | ||
163 | |||
102 | REG_IGNORE_ONE(pad2); | 164 | REG_IGNORE_ONE(pad2); |
103 | REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */ | 165 | |
166 | REG_IN_ONE(callee.r25, &cregs->r25); | ||
167 | REG_IN_ONE(callee.r24, &cregs->r24); | ||
168 | REG_IN_ONE(callee.r23, &cregs->r23); | ||
169 | REG_IN_ONE(callee.r22, &cregs->r22); | ||
170 | REG_IN_ONE(callee.r21, &cregs->r21); | ||
171 | REG_IN_ONE(callee.r20, &cregs->r20); | ||
172 | REG_IN_ONE(callee.r19, &cregs->r19); | ||
173 | REG_IN_ONE(callee.r18, &cregs->r18); | ||
174 | REG_IN_ONE(callee.r17, &cregs->r17); | ||
175 | REG_IN_ONE(callee.r16, &cregs->r16); | ||
176 | REG_IN_ONE(callee.r15, &cregs->r15); | ||
177 | REG_IN_ONE(callee.r14, &cregs->r14); | ||
178 | REG_IN_ONE(callee.r13, &cregs->r13); | ||
179 | |||
104 | REG_IGNORE_ONE(efa); /* efa update invalid */ | 180 | REG_IGNORE_ONE(efa); /* efa update invalid */ |
105 | REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */ | 181 | REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */ |
106 | 182 | ||
107 | return ret; | 183 | return ret; |
108 | } | 184 | } |
diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index 2251fb4bbfd7..b15d2fe9c461 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c | |||
@@ -67,7 +67,33 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs, | |||
67 | sigset_t *set) | 67 | sigset_t *set) |
68 | { | 68 | { |
69 | int err; | 69 | int err; |
70 | err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), regs, | 70 | struct user_regs_struct uregs; |
71 | |||
72 | uregs.scratch.bta = regs->bta; | ||
73 | uregs.scratch.lp_start = regs->lp_start; | ||
74 | uregs.scratch.lp_end = regs->lp_end; | ||
75 | uregs.scratch.lp_count = regs->lp_count; | ||
76 | uregs.scratch.status32 = regs->status32; | ||
77 | uregs.scratch.ret = regs->ret; | ||
78 | uregs.scratch.blink = regs->blink; | ||
79 | uregs.scratch.fp = regs->fp; | ||
80 | uregs.scratch.gp = regs->r26; | ||
81 | uregs.scratch.r12 = regs->r12; | ||
82 | uregs.scratch.r11 = regs->r11; | ||
83 | uregs.scratch.r10 = regs->r10; | ||
84 | uregs.scratch.r9 = regs->r9; | ||
85 | uregs.scratch.r8 = regs->r8; | ||
86 | uregs.scratch.r7 = regs->r7; | ||
87 | uregs.scratch.r6 = regs->r6; | ||
88 | uregs.scratch.r5 = regs->r5; | ||
89 | uregs.scratch.r4 = regs->r4; | ||
90 | uregs.scratch.r3 = regs->r3; | ||
91 | uregs.scratch.r2 = regs->r2; | ||
92 | uregs.scratch.r1 = regs->r1; | ||
93 | uregs.scratch.r0 = regs->r0; | ||
94 | uregs.scratch.sp = regs->sp; | ||
95 | |||
96 | err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch, | ||
71 | sizeof(sf->uc.uc_mcontext.regs.scratch)); | 97 | sizeof(sf->uc.uc_mcontext.regs.scratch)); |
72 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t)); | 98 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t)); |
73 | 99 | ||
@@ -78,14 +104,40 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) | |||
78 | { | 104 | { |
79 | sigset_t set; | 105 | sigset_t set; |
80 | int err; | 106 | int err; |
107 | struct user_regs_struct uregs; | ||
81 | 108 | ||
82 | err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); | 109 | err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); |
83 | if (!err) | 110 | if (!err) |
84 | set_current_blocked(&set); | 111 | set_current_blocked(&set); |
85 | 112 | ||
86 | err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs.scratch), | 113 | err |= __copy_from_user(&uregs.scratch, |
114 | &(sf->uc.uc_mcontext.regs.scratch), | ||
87 | sizeof(sf->uc.uc_mcontext.regs.scratch)); | 115 | sizeof(sf->uc.uc_mcontext.regs.scratch)); |
88 | 116 | ||
117 | regs->bta = uregs.scratch.bta; | ||
118 | regs->lp_start = uregs.scratch.lp_start; | ||
119 | regs->lp_end = uregs.scratch.lp_end; | ||
120 | regs->lp_count = uregs.scratch.lp_count; | ||
121 | regs->status32 = uregs.scratch.status32; | ||
122 | regs->ret = uregs.scratch.ret; | ||
123 | regs->blink = uregs.scratch.blink; | ||
124 | regs->fp = uregs.scratch.fp; | ||
125 | regs->r26 = uregs.scratch.gp; | ||
126 | regs->r12 = uregs.scratch.r12; | ||
127 | regs->r11 = uregs.scratch.r11; | ||
128 | regs->r10 = uregs.scratch.r10; | ||
129 | regs->r9 = uregs.scratch.r9; | ||
130 | regs->r8 = uregs.scratch.r8; | ||
131 | regs->r7 = uregs.scratch.r7; | ||
132 | regs->r6 = uregs.scratch.r6; | ||
133 | regs->r5 = uregs.scratch.r5; | ||
134 | regs->r4 = uregs.scratch.r4; | ||
135 | regs->r3 = uregs.scratch.r3; | ||
136 | regs->r2 = uregs.scratch.r2; | ||
137 | regs->r1 = uregs.scratch.r1; | ||
138 | regs->r0 = uregs.scratch.r0; | ||
139 | regs->sp = uregs.scratch.sp; | ||
140 | |||
89 | return err; | 141 | return err; |
90 | } | 142 | } |
91 | 143 | ||