aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/single_step.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/kernel/single_step.c')
-rw-r--r--arch/tile/kernel/single_step.c75
1 files changed, 41 insertions, 34 deletions
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 266aae123632..5ec4b9c651f2 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -23,6 +23,7 @@
23#include <linux/uaccess.h> 23#include <linux/uaccess.h>
24#include <linux/mman.h> 24#include <linux/mman.h>
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/err.h>
26#include <asm/cacheflush.h> 27#include <asm/cacheflush.h>
27#include <asm/opcode-tile.h> 28#include <asm/opcode-tile.h>
28#include <asm/opcode_constants.h> 29#include <asm/opcode_constants.h>
@@ -39,8 +40,8 @@ static int __init setup_unaligned_printk(char *str)
39 if (strict_strtol(str, 0, &val) != 0) 40 if (strict_strtol(str, 0, &val) != 0)
40 return 0; 41 return 0;
41 unaligned_printk = val; 42 unaligned_printk = val;
42 printk("Printk for each unaligned data accesses is %s\n", 43 pr_info("Printk for each unaligned data accesses is %s\n",
43 unaligned_printk ? "enabled" : "disabled"); 44 unaligned_printk ? "enabled" : "disabled");
44 return 1; 45 return 1;
45} 46}
46__setup("unaligned_printk=", setup_unaligned_printk); 47__setup("unaligned_printk=", setup_unaligned_printk);
@@ -113,7 +114,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
113 enum mem_op mem_op, 114 enum mem_op mem_op,
114 int size, int sign_ext) 115 int size, int sign_ext)
115{ 116{
116 unsigned char *addr; 117 unsigned char __user *addr;
117 int val_reg, addr_reg, err, val; 118 int val_reg, addr_reg, err, val;
118 119
119 /* Get address and value registers */ 120 /* Get address and value registers */
@@ -148,7 +149,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
148 return bundle; 149 return bundle;
149 150
150 /* If it's aligned, don't handle it specially */ 151 /* If it's aligned, don't handle it specially */
151 addr = (void *)regs->regs[addr_reg]; 152 addr = (void __user *)regs->regs[addr_reg];
152 if (((unsigned long)addr % size) == 0) 153 if (((unsigned long)addr % size) == 0)
153 return bundle; 154 return bundle;
154 155
@@ -183,7 +184,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
183 siginfo_t info = { 184 siginfo_t info = {
184 .si_signo = SIGSEGV, 185 .si_signo = SIGSEGV,
185 .si_code = SEGV_MAPERR, 186 .si_code = SEGV_MAPERR,
186 .si_addr = (void __user *)addr 187 .si_addr = addr
187 }; 188 };
188 force_sig_info(info.si_signo, &info, current); 189 force_sig_info(info.si_signo, &info, current);
189 return (tile_bundle_bits) 0; 190 return (tile_bundle_bits) 0;
@@ -193,30 +194,33 @@ static tile_bundle_bits rewrite_load_store_unaligned(
193 siginfo_t info = { 194 siginfo_t info = {
194 .si_signo = SIGBUS, 195 .si_signo = SIGBUS,
195 .si_code = BUS_ADRALN, 196 .si_code = BUS_ADRALN,
196 .si_addr = (void __user *)addr 197 .si_addr = addr
197 }; 198 };
198 force_sig_info(info.si_signo, &info, current); 199 force_sig_info(info.si_signo, &info, current);
199 return (tile_bundle_bits) 0; 200 return (tile_bundle_bits) 0;
200 } 201 }
201 202
202 if (unaligned_printk || unaligned_fixup_count == 0) { 203 if (unaligned_printk || unaligned_fixup_count == 0) {
203 printk("Process %d/%s: PC %#lx: Fixup of" 204 pr_info("Process %d/%s: PC %#lx: Fixup of"
204 " unaligned %s at %#lx.\n", 205 " unaligned %s at %#lx.\n",
205 current->pid, current->comm, regs->pc, 206 current->pid, current->comm, regs->pc,
206 (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) ? 207 (mem_op == MEMOP_LOAD ||
207 "load" : "store", 208 mem_op == MEMOP_LOAD_POSTINCR) ?
208 (unsigned long)addr); 209 "load" : "store",
210 (unsigned long)addr);
209 if (!unaligned_printk) { 211 if (!unaligned_printk) {
210 printk("\n" 212#define P pr_info
211"Unaligned fixups in the kernel will slow your application considerably.\n" 213P("\n");
212"You can find them by writing \"1\" to /proc/sys/tile/unaligned_fixup/printk,\n" 214P("Unaligned fixups in the kernel will slow your application considerably.\n");
213"which requests the kernel show all unaligned fixups, or writing a \"0\"\n" 215P("To find them, write a \"1\" to /proc/sys/tile/unaligned_fixup/printk,\n");
214"to /proc/sys/tile/unaligned_fixup/enabled, in which case each unaligned\n" 216P("which requests the kernel show all unaligned fixups, or write a \"0\"\n");
215"access will become a SIGBUS you can debug. No further warnings will be\n" 217P("to /proc/sys/tile/unaligned_fixup/enabled, in which case each unaligned\n");
216"shown so as to avoid additional slowdown, but you can track the number\n" 218P("access will become a SIGBUS you can debug. No further warnings will be\n");
217"of fixups performed via /proc/sys/tile/unaligned_fixup/count.\n" 219P("shown so as to avoid additional slowdown, but you can track the number\n");
218"Use the tile-addr2line command (see \"info addr2line\") to decode PCs.\n" 220P("of fixups performed via /proc/sys/tile/unaligned_fixup/count.\n");
219 "\n"); 221P("Use the tile-addr2line command (see \"info addr2line\") to decode PCs.\n");
222P("\n");
223#undef P
220 } 224 }
221 } 225 }
222 ++unaligned_fixup_count; 226 ++unaligned_fixup_count;
@@ -276,7 +280,7 @@ void single_step_once(struct pt_regs *regs)
276 struct thread_info *info = (void *)current_thread_info(); 280 struct thread_info *info = (void *)current_thread_info();
277 struct single_step_state *state = info->step_state; 281 struct single_step_state *state = info->step_state;
278 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP); 282 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
279 tile_bundle_bits *buffer, *pc; 283 tile_bundle_bits __user *buffer, *pc;
280 tile_bundle_bits bundle; 284 tile_bundle_bits bundle;
281 int temp_reg; 285 int temp_reg;
282 int target_reg = TREG_LR; 286 int target_reg = TREG_LR;
@@ -306,21 +310,21 @@ void single_step_once(struct pt_regs *regs)
306 /* allocate a page of writable, executable memory */ 310 /* allocate a page of writable, executable memory */
307 state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL); 311 state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);
308 if (state == NULL) { 312 if (state == NULL) {
309 printk("Out of kernel memory trying to single-step\n"); 313 pr_err("Out of kernel memory trying to single-step\n");
310 return; 314 return;
311 } 315 }
312 316
313 /* allocate a cache line of writable, executable memory */ 317 /* allocate a cache line of writable, executable memory */
314 down_write(&current->mm->mmap_sem); 318 down_write(&current->mm->mmap_sem);
315 buffer = (void *) do_mmap(0, 0, 64, 319 buffer = (void __user *) do_mmap(NULL, 0, 64,
316 PROT_EXEC | PROT_READ | PROT_WRITE, 320 PROT_EXEC | PROT_READ | PROT_WRITE,
317 MAP_PRIVATE | MAP_ANONYMOUS, 321 MAP_PRIVATE | MAP_ANONYMOUS,
318 0); 322 0);
319 up_write(&current->mm->mmap_sem); 323 up_write(&current->mm->mmap_sem);
320 324
321 if ((int)buffer < 0 && (int)buffer > -PAGE_SIZE) { 325 if (IS_ERR((void __force *)buffer)) {
322 kfree(state); 326 kfree(state);
323 printk("Out of kernel pages trying to single-step\n"); 327 pr_err("Out of kernel pages trying to single-step\n");
324 return; 328 return;
325 } 329 }
326 330
@@ -349,11 +353,14 @@ void single_step_once(struct pt_regs *regs)
349 if (regs->faultnum == INT_SWINT_1) 353 if (regs->faultnum == INT_SWINT_1)
350 regs->pc -= 8; 354 regs->pc -= 8;
351 355
352 pc = (tile_bundle_bits *)(regs->pc); 356 pc = (tile_bundle_bits __user *)(regs->pc);
353 bundle = pc[0]; 357 if (get_user(bundle, pc) != 0) {
358 pr_err("Couldn't read instruction at %p trying to step\n", pc);
359 return;
360 }
354 361
355 /* We'll follow the instruction with 2 ill op bundles */ 362 /* We'll follow the instruction with 2 ill op bundles */
356 state->orig_pc = (unsigned long) pc; 363 state->orig_pc = (unsigned long)pc;
357 state->next_pc = (unsigned long)(pc + 1); 364 state->next_pc = (unsigned long)(pc + 1);
358 state->branch_next_pc = 0; 365 state->branch_next_pc = 0;
359 state->update = 0; 366 state->update = 0;
@@ -633,7 +640,7 @@ void single_step_once(struct pt_regs *regs)
633 } 640 }
634 641
635 if (err) { 642 if (err) {
636 printk("Fault when writing to single-step buffer\n"); 643 pr_err("Fault when writing to single-step buffer\n");
637 return; 644 return;
638 } 645 }
639 646
@@ -641,12 +648,12 @@ void single_step_once(struct pt_regs *regs)
641 * Flush the buffer. 648 * Flush the buffer.
642 * We do a local flush only, since this is a thread-specific buffer. 649 * We do a local flush only, since this is a thread-specific buffer.
643 */ 650 */
644 __flush_icache_range((unsigned long) state->buffer, 651 __flush_icache_range((unsigned long)state->buffer,
645 (unsigned long) buffer); 652 (unsigned long)buffer);
646 653
647 /* Indicate enabled */ 654 /* Indicate enabled */
648 state->is_enabled = is_single_step; 655 state->is_enabled = is_single_step;
649 regs->pc = (unsigned long) state->buffer; 656 regs->pc = (unsigned long)state->buffer;
650 657
651 /* Fault immediately if we are coming back from a syscall. */ 658 /* Fault immediately if we are coming back from a syscall. */
652 if (regs->faultnum == INT_SWINT_1) 659 if (regs->faultnum == INT_SWINT_1)