diff options
Diffstat (limited to 'arch/arm/kernel')
| -rw-r--r-- | arch/arm/kernel/entry-armv.S | 1 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-common.S | 8 | ||||
| -rw-r--r-- | arch/arm/kernel/fiq.c | 9 | ||||
| -rw-r--r-- | arch/arm/kernel/irq.c | 10 | ||||
| -rw-r--r-- | arch/arm/kernel/kprobes-test-arm.c | 4 | ||||
| -rw-r--r-- | arch/arm/kernel/kprobes-thumb.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/perf_event.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/signal.c | 78 | ||||
| -rw-r--r-- | arch/arm/kernel/smp.c | 8 | ||||
| -rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 2 | 
10 files changed, 35 insertions, 89 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 437f0c42651..0d1851ca6eb 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -495,6 +495,7 @@ ENDPROC(__und_usr)   * The out of line fixup for the ldrt above.   */  	.pushsection .fixup, "ax" +	.align	2  4:	mov	pc, r9  	.popsection  	.pushsection __ex_table,"a" diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 7bd2d3cb895..4afed88d250 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -53,9 +53,13 @@ fast_work_pending:  work_pending:  	tst	r1, #_TIF_NEED_RESCHED  	bne	work_resched -	tst	r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME -	beq	no_work_pending +	/* +	 * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here +	 */ +	ldr	r2, [sp, #S_PSR]  	mov	r0, sp				@ 'regs' +	tst	r2, #15				@ are we returning to user mode? +	bne	no_work_pending			@ no?  just leave, then...  	mov	r2, why				@ 'syscall'  	tst	r1, #_TIF_SIGPENDING		@ delivering a signal?  	movne	why, #0				@ prevent further restarts diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index c32f8456aa0..2adda11f712 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -122,14 +122,16 @@ void release_fiq(struct fiq_handler *f)  	while (current_fiq->fiq_op(current_fiq->dev_id, 0));  } +static int fiq_start; +  void enable_fiq(int fiq)  { -	enable_irq(fiq + FIQ_START); +	enable_irq(fiq + fiq_start);  }  void disable_fiq(int fiq)  { -	disable_irq(fiq + FIQ_START); +	disable_irq(fiq + fiq_start);  }  EXPORT_SYMBOL(set_fiq_handler); @@ -140,7 +142,8 @@ EXPORT_SYMBOL(release_fiq);  EXPORT_SYMBOL(enable_fiq);  EXPORT_SYMBOL(disable_fiq); -void __init init_FIQ(void) +void __init init_FIQ(int start)  {  	no_fiq_insn = *(unsigned long *)0xffff001c; +	fiq_start = start;  } diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 8349d4e97e2..16cedb42c0c 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -40,13 +40,6 @@  #include <asm/mach/irq.h>  #include <asm/mach/time.h> -/* - * No architecture-specific irq_finish function defined in arm/arch/irqs.h. - */ -#ifndef irq_finish -#define irq_finish(irq) do { } while (0) -#endif -  unsigned long irq_err_count;  int arch_show_interrupts(struct seq_file *p, int prec) @@ -85,9 +78,6 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)  		generic_handle_irq(irq);  	} -	/* AT91 specific workaround */ -	irq_finish(irq); -  	irq_exit();  	set_irq_regs(old_regs);  } diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/kernel/kprobes-test-arm.c index ba32b393b3f..38c1a3b103a 100644 --- a/arch/arm/kernel/kprobes-test-arm.c +++ b/arch/arm/kernel/kprobes-test-arm.c @@ -187,8 +187,8 @@ void kprobe_arm_test_cases(void)  	TEST_BF_R ("mov	pc, r",0,2f,"")  	TEST_BF_RR("mov	pc, r",0,2f,", asl r",1,0,"")  	TEST_BB(   "sub	pc, pc, #1b-2b+8") -#if __LINUX_ARM_ARCH__ >= 6 -	TEST_BB(   "sub	pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before ARMv6 */ +#if __LINUX_ARM_ARCH__ == 6 && !defined(CONFIG_CPU_V7) +	TEST_BB(   "sub	pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before and after ARMv6 */  #endif  	TEST_BB_R( "sub	pc, pc, r",14, 1f-2f+8,"")  	TEST_BB_R( "rsb	pc, r",14,1f-2f+8,", pc") diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 8f96ec778e8..6123daf397a 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c @@ -660,7 +660,7 @@ static const union decode_item t32_table_1111_100x[] = {  	/* LDRSB (literal)	1111 1001 x001 1111 xxxx xxxx xxxx xxxx */  	/* LDRH (literal)	1111 1000 x011 1111 xxxx xxxx xxxx xxxx */  	/* LDRSH (literal)	1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ -	DECODE_EMULATEX	(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, +	DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal,  						 REGS(PC, NOSPPCX, 0, 0, 0)),  	/* STRB (immediate)	1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 186c8cb982c..a02eada3aa5 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -503,7 +503,7 @@ __hw_perf_event_init(struct perf_event *event)  	     event_requires_mode_exclusion(&event->attr)) {  		pr_debug("ARM performance counters do not support "  			 "mode exclusion\n"); -		return -EPERM; +		return -EOPNOTSUPP;  	}  	/* diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 4e5fdd9bd9e..536c5d6b340 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -22,8 +22,6 @@  #include "signal.h" -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -  /*   * For ARM syscalls, we encode the syscall number into the instruction.   */ @@ -82,10 +80,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,  		old_sigset_t mask;  		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||  		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) || -		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) +		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || +		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) || +		    __get_user(mask, &act->sa_mask))  			return -EFAULT; -		__get_user(new_ka.sa.sa_flags, &act->sa_flags); -		__get_user(mask, &act->sa_mask);  		siginitset(&new_ka.sa.sa_mask, mask);  	} @@ -94,10 +92,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,  	if (!ret && oact) {  		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||  		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || -		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) +		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || +		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || +		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))  			return -EFAULT; -		__put_user(old_ka.sa.sa_flags, &oact->sa_flags); -		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);  	}  	return ret; @@ -223,10 +221,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)  	int err;  	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); -	if (err == 0) { -		sigdelsetmask(&set, ~_BLOCKABLE); +	if (err == 0)  		set_current_blocked(&set); -	}  	__get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);  	__get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); @@ -541,13 +537,13 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,  /*   * OK, we're invoking a handler   */	 -static int +static void  handle_signal(unsigned long sig, struct k_sigaction *ka, -	      siginfo_t *info, sigset_t *oldset, -	      struct pt_regs * regs) +	      siginfo_t *info, struct pt_regs *regs)  {  	struct thread_info *thread = current_thread_info();  	struct task_struct *tsk = current; +	sigset_t *oldset = sigmask_to_save();  	int usig = sig;  	int ret; @@ -572,17 +568,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,  	if (ret != 0) {  		force_sigsegv(sig, tsk); -		return ret; +		return;  	} - -	/* -	 * Block the signal if we were successful. -	 */ -	block_sigmask(ka, sig); - -	tracehook_signal_handler(sig, info, ka, regs, 0); - -	return 0; +	signal_delivered(sig, info, ka, regs, 0);  }  /* @@ -602,15 +590,6 @@ static void do_signal(struct pt_regs *regs, int syscall)  	int signr;  	/* -	 * We want the common case to go fast, which -	 * is why we may in certain cases get here from -	 * kernel mode. Just return without doing anything -	 * if so. -	 */ -	if (!user_mode(regs)) -		return; - -	/*  	 * If we were from a system call, check for system call restarting...  	 */  	if (syscall) { @@ -635,17 +614,12 @@ static void do_signal(struct pt_regs *regs, int syscall)  		}  	} -	if (try_to_freeze()) -		goto no_signal; -  	/*  	 * Get the signal to deliver.  When running under ptrace, at this  	 * point the debugger may change all our registers ...  	 */  	signr = get_signal_to_deliver(&info, &ka, regs, NULL);  	if (signr > 0) { -		sigset_t *oldset; -  		/*  		 * Depending on the signal settings we may need to revert the  		 * decision to restart the system call.  But skip this if a @@ -660,24 +634,10 @@ static void do_signal(struct pt_regs *regs, int syscall)  			}  		} -		if (test_thread_flag(TIF_RESTORE_SIGMASK)) -			oldset = ¤t->saved_sigmask; -		else -			oldset = ¤t->blocked; -		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { -			/* -			 * A signal was successfully delivered; the saved -			 * sigmask will have been stored in the signal frame, -			 * and will be restored by sigreturn, so we can simply -			 * clear the TIF_RESTORE_SIGMASK flag. -			 */ -			if (test_thread_flag(TIF_RESTORE_SIGMASK)) -				clear_thread_flag(TIF_RESTORE_SIGMASK); -		} +		handle_signal(signr, &ka, &info, regs);  		return;  	} - no_signal:  	if (syscall) {  		/*  		 * Handle restarting a different system call.  As above, @@ -708,15 +668,9 @@ static void do_signal(struct pt_regs *regs, int syscall)  #endif  			}  		} - -		/* If there's no signal to deliver, we just put the saved sigmask -		 * back. -		 */ -		if (test_thread_flag(TIF_RESTORE_SIGMASK)) { -			clear_thread_flag(TIF_RESTORE_SIGMASK); -			sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); -		}  	} + +	restore_saved_sigmask();  }  asmlinkage void @@ -728,7 +682,5 @@ do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)  	if (thread_flags & _TIF_NOTIFY_RESUME) {  		clear_thread_flag(TIF_NOTIFY_RESUME);  		tracehook_notify_resume(regs); -		if (current->replacement_session_keyring) -			key_replace_session_keyring();  	}  } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index b735521a4a5..2c7217d971d 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -109,7 +109,6 @@ static void percpu_timer_stop(void);  int __cpu_disable(void)  {  	unsigned int cpu = smp_processor_id(); -	struct task_struct *p;  	int ret;  	ret = platform_cpu_disable(cpu); @@ -139,12 +138,7 @@ int __cpu_disable(void)  	flush_cache_all();  	local_flush_tlb_all(); -	read_lock(&tasklist_lock); -	for_each_process(p) { -		if (p->mm) -			cpumask_clear_cpu(cpu, mm_cpumask(p->mm)); -	} -	read_unlock(&tasklist_lock); +	clear_tasks_mm_cpumask(cpu);  	return 0;  } diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 43a31fb0631..36ff15bbfdd 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -183,7 +183,9 @@ SECTIONS  	}  #endif +#ifdef CONFIG_SMP  	PERCPU_SECTION(L1_CACHE_BYTES) +#endif  #ifdef CONFIG_XIP_KERNEL  	__data_loc = ALIGN(4);		/* location in binary */  |