aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel/signal.c')
-rw-r--r--arch/microblaze/kernel/signal.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 1c80e4fc40ce..d8d3bb396cd6 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -44,7 +44,6 @@
44 44
45asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall); 45asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
46 46
47
48asmlinkage long 47asmlinkage long
49sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 48sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
50 struct pt_regs *regs) 49 struct pt_regs *regs)
@@ -176,6 +175,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
176 struct rt_sigframe __user *frame; 175 struct rt_sigframe __user *frame;
177 int err = 0; 176 int err = 0;
178 int signal; 177 int signal;
178 unsigned long address = 0;
179#ifdef CONFIG_MMU
180 pmd_t *pmdp;
181 pte_t *ptep;
182#endif
179 183
180 frame = get_sigframe(ka, regs, sizeof(*frame)); 184 frame = get_sigframe(ka, regs, sizeof(*frame));
181 185
@@ -216,8 +220,29 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
216 Negative 8 offset because return is rtsd r15, 8 */ 220 Negative 8 offset because return is rtsd r15, 8 */
217 regs->r15 = ((unsigned long)frame->tramp)-8; 221 regs->r15 = ((unsigned long)frame->tramp)-8;
218 222
219 __invalidate_cache_sigtramp((unsigned long)frame->tramp); 223 address = ((unsigned long)frame->tramp);
220 224#ifdef CONFIG_MMU
225 pmdp = pmd_offset(pud_offset(
226 pgd_offset(current->mm, address),
227 address), address);
228
229 preempt_disable();
230 ptep = pte_offset_map(pmdp, address);
231 if (pte_present(*ptep)) {
232 address = (unsigned long) page_address(pte_page(*ptep));
233 /* MS: I need add offset in page */
234 address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
235 /* MS address is virtual */
236 address = virt_to_phys(address);
237 invalidate_icache_range(address, address + 8);
238 flush_dcache_range(address, address + 8);
239 }
240 pte_unmap(ptep);
241 preempt_enable();
242#else
243 flush_icache_range(address, address + 8);
244 flush_dcache_range(address, address + 8);
245#endif
221 if (err) 246 if (err)
222 goto give_sigsegv; 247 goto give_sigsegv;
223 248
@@ -233,6 +258,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
233 258
234 set_fs(USER_DS); 259 set_fs(USER_DS);
235 260
261 /* the tracer may want to single-step inside the handler */
262 if (test_thread_flag(TIF_SINGLESTEP))
263 ptrace_notify(SIGTRAP);
264
236#ifdef DEBUG_SIG 265#ifdef DEBUG_SIG
237 printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n", 266 printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
238 current->comm, current->pid, frame, regs->pc); 267 current->comm, current->pid, frame, regs->pc);