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 bc1eb586e24..89529c9f060 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(  	if (((unsigned long)addr % size) == 0)  		return bundle; +	/* +	 * Return SIGBUS with the unaligned address, if requested. +	 * Note that we return SIGBUS even for completely invalid addresses +	 * as long as they are in fact unaligned; this matches what the +	 * tilepro hardware would be doing, if it could provide us with the +	 * actual bad address in an SPR, which it doesn't. +	 */ +	if (unaligned_fixup == 0) { +		siginfo_t info = { +			.si_signo = SIGBUS, +			.si_code = BUS_ADRALN, +			.si_addr = addr +		}; +		trace_unhandled_signal("unaligned trap", regs, +				       (unsigned long)addr, SIGBUS); +		force_sig_info(info.si_signo, &info, current); +		return (tilepro_bundle_bits) 0; +	} +  #ifndef __LITTLE_ENDIAN  # error We assume little-endian representation with copy_xx_user size 2 here  #endif @@ -192,18 +211,6 @@ static tile_bundle_bits rewrite_load_store_unaligned(  		return (tile_bundle_bits) 0;  	} -	if (unaligned_fixup == 0) { -		siginfo_t info = { -			.si_signo = SIGBUS, -			.si_code = BUS_ADRALN, -			.si_addr = addr -		}; -		trace_unhandled_signal("unaligned trap", regs, -				       (unsigned long)addr, SIGBUS); -		force_sig_info(info.si_signo, &info, current); -		return (tile_bundle_bits) 0; -	} -  	if (unaligned_printk || unaligned_fixup_count == 0) {  		pr_info("Process %d/%s: PC %#lx: Fixup of"  			" unaligned %s at %#lx.\n", @@ -339,12 +346,10 @@ void single_step_once(struct pt_regs *regs)  		}  		/* allocate a cache line of writable, executable memory */ -		down_write(¤t->mm->mmap_sem); -		buffer = (void __user *) do_mmap(NULL, 0, 64, +		buffer = (void __user *) vm_mmap(NULL, 0, 64,  					  PROT_EXEC | PROT_READ | PROT_WRITE,  					  MAP_PRIVATE | MAP_ANONYMOUS,  					  0); -		up_write(¤t->mm->mmap_sem);  		if (IS_ERR((void __force *)buffer)) {  			kfree(state);  |