diff options
Diffstat (limited to 'arch/tile/kernel/single_step.c')
| -rw-r--r-- | arch/tile/kernel/single_step.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c index bc1eb586e24d..89529c9f0605 100644 --- a/arch/tile/kernel/single_step.c +++ b/arch/tile/kernel/single_step.c | |||
| @@ -153,6 +153,25 @@ static tile_bundle_bits rewrite_load_store_unaligned( | |||
| 153 | if (((unsigned long)addr % size) == 0) | 153 | if (((unsigned long)addr % size) == 0) |
| 154 | return bundle; | 154 | return bundle; |
| 155 | 155 | ||
| 156 | /* | ||
| 157 | * Return SIGBUS with the unaligned address, if requested. | ||
| 158 | * Note that we return SIGBUS even for completely invalid addresses | ||
| 159 | * as long as they are in fact unaligned; this matches what the | ||
| 160 | * tilepro hardware would be doing, if it could provide us with the | ||
| 161 | * actual bad address in an SPR, which it doesn't. | ||
| 162 | */ | ||
| 163 | if (unaligned_fixup == 0) { | ||
| 164 | siginfo_t info = { | ||
| 165 | .si_signo = SIGBUS, | ||
| 166 | .si_code = BUS_ADRALN, | ||
| 167 | .si_addr = addr | ||
| 168 | }; | ||
| 169 | trace_unhandled_signal("unaligned trap", regs, | ||
| 170 | (unsigned long)addr, SIGBUS); | ||
| 171 | force_sig_info(info.si_signo, &info, current); | ||
| 172 | return (tilepro_bundle_bits) 0; | ||
| 173 | } | ||
| 174 | |||
| 156 | #ifndef __LITTLE_ENDIAN | 175 | #ifndef __LITTLE_ENDIAN |
| 157 | # error We assume little-endian representation with copy_xx_user size 2 here | 176 | # error We assume little-endian representation with copy_xx_user size 2 here |
| 158 | #endif | 177 | #endif |
| @@ -192,18 +211,6 @@ static tile_bundle_bits rewrite_load_store_unaligned( | |||
| 192 | return (tile_bundle_bits) 0; | 211 | return (tile_bundle_bits) 0; |
| 193 | } | 212 | } |
| 194 | 213 | ||
| 195 | if (unaligned_fixup == 0) { | ||
| 196 | siginfo_t info = { | ||
| 197 | .si_signo = SIGBUS, | ||
| 198 | .si_code = BUS_ADRALN, | ||
| 199 | .si_addr = addr | ||
| 200 | }; | ||
| 201 | trace_unhandled_signal("unaligned trap", regs, | ||
| 202 | (unsigned long)addr, SIGBUS); | ||
| 203 | force_sig_info(info.si_signo, &info, current); | ||
| 204 | return (tile_bundle_bits) 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | if (unaligned_printk || unaligned_fixup_count == 0) { | 214 | if (unaligned_printk || unaligned_fixup_count == 0) { |
| 208 | pr_info("Process %d/%s: PC %#lx: Fixup of" | 215 | pr_info("Process %d/%s: PC %#lx: Fixup of" |
| 209 | " unaligned %s at %#lx.\n", | 216 | " unaligned %s at %#lx.\n", |
| @@ -339,12 +346,10 @@ void single_step_once(struct pt_regs *regs) | |||
| 339 | } | 346 | } |
| 340 | 347 | ||
| 341 | /* allocate a cache line of writable, executable memory */ | 348 | /* allocate a cache line of writable, executable memory */ |
| 342 | down_write(¤t->mm->mmap_sem); | 349 | buffer = (void __user *) vm_mmap(NULL, 0, 64, |
| 343 | buffer = (void __user *) do_mmap(NULL, 0, 64, | ||
| 344 | PROT_EXEC | PROT_READ | PROT_WRITE, | 350 | PROT_EXEC | PROT_READ | PROT_WRITE, |
| 345 | MAP_PRIVATE | MAP_ANONYMOUS, | 351 | MAP_PRIVATE | MAP_ANONYMOUS, |
| 346 | 0); | 352 | 0); |
| 347 | up_write(¤t->mm->mmap_sem); | ||
| 348 | 353 | ||
| 349 | if (IS_ERR((void __force *)buffer)) { | 354 | if (IS_ERR((void __force *)buffer)) { |
| 350 | kfree(state); | 355 | kfree(state); |
