diff options
Diffstat (limited to 'arch/arm/kernel')
| -rw-r--r-- | arch/arm/kernel/bios32.c | 1 | ||||
| -rw-r--r-- | arch/arm/kernel/insn.c | 1 | ||||
| -rw-r--r-- | arch/arm/kernel/irq.c | 6 | ||||
| -rw-r--r-- | arch/arm/kernel/kprobes.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/ptrace.c | 28 | ||||
| -rw-r--r-- | arch/arm/kernel/setup.c | 16 | ||||
| -rw-r--r-- | arch/arm/kernel/signal.c | 55 | ||||
| -rw-r--r-- | arch/arm/kernel/smp.c | 33 | ||||
| -rw-r--r-- | arch/arm/kernel/sys_arm.c | 2 | 
9 files changed, 57 insertions, 87 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 632df9a66f8..ede5f7741c4 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -299,7 +299,6 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev)   */  void pcibios_fixup_bus(struct pci_bus *bus)  { -	struct pci_sys_data *root = bus->sysdata;  	struct pci_dev *dev;  	u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK; diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c index ab312e51654..b760340b701 100644 --- a/arch/arm/kernel/insn.c +++ b/arch/arm/kernel/insn.c @@ -1,3 +1,4 @@ +#include <linux/bug.h>  #include <linux/kernel.h>  #include <asm/opcodes.h> diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 71ccdbfed66..8349d4e97e2 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -155,10 +155,10 @@ static bool migrate_one_irq(struct irq_desc *desc)  	}  	c = irq_data_get_irq_chip(d); -	if (c->irq_set_affinity) -		c->irq_set_affinity(d, affinity, true); -	else +	if (!c->irq_set_affinity)  		pr_debug("IRQ%u: unable to set affinity\n", d->irq); +	else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret) +		cpumask_copy(d->affinity, affinity);  	return ret;  } diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index ab1869dac97..4dd41fc9e23 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -152,7 +152,7 @@ int __kprobes __arch_disarm_kprobe(void *p)  void __kprobes arch_disarm_kprobe(struct kprobe *p)  { -	stop_machine(__arch_disarm_kprobe, p, &cpu_online_map); +	stop_machine(__arch_disarm_kprobe, p, cpu_online_mask);  }  void __kprobes arch_remove_kprobe(struct kprobe *p) diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 45956c9d0ef..9650c143afc 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -256,7 +256,7 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off,  {  	unsigned long tmp; -	if (off & 3 || off >= sizeof(struct user)) +	if (off & 3)  		return -EIO;  	tmp = 0; @@ -268,6 +268,8 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off,  		tmp = tsk->mm->end_code;  	else if (off < sizeof(struct pt_regs))  		tmp = get_user_reg(tsk, off >> 2); +	else if (off >= sizeof(struct user)) +		return -EIO;  	return put_user(tmp, ret);  } @@ -904,27 +906,14 @@ long arch_ptrace(struct task_struct *child, long request,  	return ret;  } -#ifdef __ARMEB__ -#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB -#else -#define AUDIT_ARCH_NR AUDIT_ARCH_ARM -#endif -  asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)  {  	unsigned long ip; -	/* -	 * Save IP.  IP is used to denote syscall entry/exit: -	 *  IP = 0 -> entry, = 1 -> exit -	 */ -	ip = regs->ARM_ip; -	regs->ARM_ip = why; - -	if (!ip) +	if (why)  		audit_syscall_exit(regs);  	else -		audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0, +		audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0,  				    regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);  	if (!test_thread_flag(TIF_SYSCALL_TRACE)) @@ -934,6 +923,13 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)  	current_thread_info()->syscall = scno; +	/* +	 * IP is used to denote syscall entry/exit: +	 * IP = 0 -> entry, =1 -> exit +	 */ +	ip = regs->ARM_ip; +	regs->ARM_ip = why; +  	/* the 0x80 provides a way for the tracing parent to distinguish  	   between a syscall stop and SIGTRAP delivery */  	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b91411371ae..ebfac782593 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -523,7 +523,21 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size)  	 */  	size -= start & ~PAGE_MASK;  	bank->start = PAGE_ALIGN(start); -	bank->size  = size & PAGE_MASK; + +#ifndef CONFIG_LPAE +	if (bank->start + size < bank->start) { +		printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " +			"32-bit physical address space\n", (long long)start); +		/* +		 * To ensure bank->start + bank->size is representable in +		 * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. +		 * This means we lose a page after masking. +		 */ +		size = ULONG_MAX - bank->start; +	} +#endif + +	bank->size = size & PAGE_MASK;  	/*  	 * Check whether this memory region has non-zero size or diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 7cb532fc8aa..d68d1b69468 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -180,44 +180,23 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)  static int preserve_vfp_context(struct vfp_sigframe __user *frame)  { -	struct thread_info *thread = current_thread_info(); -	struct vfp_hard_struct *h = &thread->vfpstate.hard;  	const unsigned long magic = VFP_MAGIC;  	const unsigned long size = VFP_STORAGE_SIZE;  	int err = 0; -	vfp_sync_hwstate(thread);  	__put_user_error(magic, &frame->magic, err);  	__put_user_error(size, &frame->size, err); -	/* -	 * Copy the floating point registers. There can be unused -	 * registers see asm/hwcap.h for details. -	 */ -	err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, -			      sizeof(h->fpregs)); -	/* -	 * Copy the status and control register. -	 */ -	__put_user_error(h->fpscr, &frame->ufp.fpscr, err); - -	/* -	 * Copy the exception registers. -	 */ -	__put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); -	__put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); -	__put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); +	if (err) +		return -EFAULT; -	return err ? -EFAULT : 0; +	return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);  }  static int restore_vfp_context(struct vfp_sigframe __user *frame)  { -	struct thread_info *thread = current_thread_info(); -	struct vfp_hard_struct *h = &thread->vfpstate.hard;  	unsigned long magic;  	unsigned long size; -	unsigned long fpexc;  	int err = 0;  	__get_user_error(magic, &frame->magic, err); @@ -228,33 +207,7 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)  	if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)  		return -EINVAL; -	vfp_flush_hwstate(thread); - -	/* -	 * Copy the floating point registers. There can be unused -	 * registers see asm/hwcap.h for details. -	 */ -	err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, -				sizeof(h->fpregs)); -	/* -	 * Copy the status and control register. -	 */ -	__get_user_error(h->fpscr, &frame->ufp.fpscr, err); - -	/* -	 * Sanitise and restore the exception registers. -	 */ -	__get_user_error(fpexc, &frame->ufp_exc.fpexc, err); -	/* Ensure the VFP is enabled. */ -	fpexc |= FPEXC_EN; -	/* Ensure FPINST2 is invalid and the exception flag is cleared. */ -	fpexc &= ~(FPEXC_EX | FPEXC_FP2V); -	h->fpexc = fpexc; - -	__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); -	__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); - -	return err ? -EFAULT : 0; +	return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);  }  #endif diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 2cee7d1eb95..8f464465977 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -251,8 +251,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)  	struct mm_struct *mm = &init_mm;  	unsigned int cpu = smp_processor_id(); -	printk("CPU%u: Booted secondary processor\n", cpu); -  	/*  	 * All kernel threads share the same mm context; grab a  	 * reference and switch to it. @@ -264,6 +262,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void)  	enter_lazy_tlb(mm, current);  	local_flush_tlb_all(); +	printk("CPU%u: Booted secondary processor\n", cpu); +  	cpu_init();  	preempt_disable();  	trace_hardirqs_off(); @@ -349,7 +349,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)  		 * re-initialize the map in platform_smp_prepare_cpus() if  		 * present != possible (e.g. physical hotplug).  		 */ -		init_cpu_present(&cpu_possible_map); +		init_cpu_present(cpu_possible_mask);  		/*  		 * Initialise the SCU if there are more than one CPU @@ -510,10 +510,6 @@ static void ipi_cpu_stop(unsigned int cpu)  	local_fiq_disable();  	local_irq_disable(); -#ifdef CONFIG_HOTPLUG_CPU -	platform_cpu_kill(cpu); -#endif -  	while (1)  		cpu_relax();  } @@ -576,16 +572,25 @@ void smp_send_reschedule(int cpu)  	smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);  } +#ifdef CONFIG_HOTPLUG_CPU +static void smp_kill_cpus(cpumask_t *mask) +{ +	unsigned int cpu; +	for_each_cpu(cpu, mask) +		platform_cpu_kill(cpu); +} +#else +static void smp_kill_cpus(cpumask_t *mask) { } +#endif +  void smp_send_stop(void)  {  	unsigned long timeout; +	struct cpumask mask; -	if (num_online_cpus() > 1) { -		cpumask_t mask = cpu_online_map; -		cpu_clear(smp_processor_id(), mask); - -		smp_cross_call(&mask, IPI_CPU_STOP); -	} +	cpumask_copy(&mask, cpu_online_mask); +	cpumask_clear_cpu(smp_processor_id(), &mask); +	smp_cross_call(&mask, IPI_CPU_STOP);  	/* Wait up to one second for other CPUs to stop */  	timeout = USEC_PER_SEC; @@ -594,6 +599,8 @@ void smp_send_stop(void)  	if (num_online_cpus() > 1)  		pr_warning("SMP: failed to stop secondary CPUs\n"); + +	smp_kill_cpus(&mask);  }  /* diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index d2b177905cd..76cbb055dd0 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -115,7 +115,7 @@ int kernel_execve(const char *filename,  		  "Ir" (THREAD_START_SP - sizeof(regs)),  		  "r" (®s),  		  "Ir" (sizeof(regs)) -		: "r0", "r1", "r2", "r3", "ip", "lr", "memory"); +		: "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");   out:  	return ret;  |