diff --git a/[refs] b/[refs] index 42a952549d16..20d20182832e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 98aa686494f92e881869f76bfb734cbb1f53cb13 +refs/heads/master: a95c729b7484d2bbb9ab6beef4865641e73deb99 diff --git a/trunk/arch/arm/common/uengine.c b/trunk/arch/arm/common/uengine.c index 117cab30bd36..95c8508c29b7 100644 --- a/trunk/arch/arm/common/uengine.c +++ b/trunk/arch/arm/common/uengine.c @@ -374,8 +374,8 @@ static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c) u8 *ucode; int i; - gpr_a = kzalloc(128 * sizeof(u32), GFP_KERNEL); - gpr_b = kzalloc(128 * sizeof(u32), GFP_KERNEL); + gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL); + gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL); ucode = kmalloc(513 * 5, GFP_KERNEL); if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) { kfree(ucode); @@ -388,6 +388,8 @@ static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c) if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS) per_ctx_regs = 32; + memset(gpr_a, 0, sizeof(gpr_a)); + memset(gpr_b, 0, sizeof(gpr_b)); for (i = 0; i < 256; i++) { struct ixp2000_reg_value *r = c->initial_reg_values + i; u32 *bank; diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 29dec080a604..d645897652c2 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -339,6 +339,16 @@ __pabt_svc: str r1, [sp] @ save the "real" r0 copied @ from the exception stack +#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ make sure our user space atomic helper is aborted + cmp r2, #TASK_SIZE + bichs r3, r3, #PSR_Z_BIT +#endif +#endif + @ @ We are now ready to fill in the remaining blanks on the stack: @ @@ -362,25 +372,9 @@ __pabt_svc: zero_fp .endm - .macro kuser_cmpxchg_check -#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) -#ifndef CONFIG_MMU -#warning "NPTL on non MMU needs fixing" -#else - @ Make sure our user space atomic helper is restarted - @ if it was interrupted in a critical region. Here we - @ perform a quick test inline since it should be false - @ 99.9999% of the time. The rest is done out of line. - cmp r2, #TASK_SIZE - blhs kuser_cmpxchg_fixup -#endif -#endif - .endm - .align 5 __dabt_usr: usr_entry - kuser_cmpxchg_check @ @ Call the processor-specific abort handler: @@ -410,7 +404,6 @@ __dabt_usr: .align 5 __irq_usr: usr_entry - kuser_cmpxchg_check #ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_off @@ -453,9 +446,9 @@ __und_usr: @ @ r0 - instruction @ +1: ldrt r0, [r4] adr r9, ret_from_exception adr lr, __und_usr_unknown -1: ldrt r0, [r4] @ @ fallthrough to call_fpe @ @@ -676,7 +669,7 @@ __kuser_helper_start: * * Clobbered: * - * none + * the Z flag might be lost * * Definition and user space usage example: * @@ -737,6 +730,9 @@ __kuser_memory_barrier: @ 0xffff0fa0 * * - This routine already includes memory barriers as needed. * + * - A failure might be transient, i.e. it is possible, although unlikely, + * that "failure" be returned even if *ptr == oldval. + * * For example, a user space atomic_add implementation could look like this: * * #define atomic_add(ptr, val) \ @@ -773,62 +769,46 @@ __kuser_cmpxchg: @ 0xffff0fc0 #elif __LINUX_ARM_ARCH__ < 6 -#ifdef CONFIG_MMU - /* - * The only thing that can break atomicity in this cmpxchg - * implementation is either an IRQ or a data abort exception - * causing another process/thread to be scheduled in the middle - * of the critical sequence. To prevent this, code is added to - * the IRQ and data abort exception handlers to set the pc back - * to the beginning of the critical section if it is found to be - * within that critical section (see kuser_cmpxchg_fixup). + * Theory of operation: + * + * We set the Z flag before loading oldval. If ever an exception + * occurs we can not be sure the loaded value will still be the same + * when the exception returns, therefore the user exception handler + * will clear the Z flag whenever the interrupted user code was + * actually from the kernel address space (see the usr_entry macro). + * + * The post-increment on the str is used to prevent a race with an + * exception happening just after the str instruction which would + * clear the Z flag although the exchange was done. */ -1: ldr r3, [r2] @ load current val - subs r3, r3, r0 @ compare with oldval -2: streq r1, [r2] @ store newval if eq - rsbs r0, r3, #0 @ set return val and C flag - usr_ret lr - - .text -kuser_cmpxchg_fixup: - @ Called from kuser_cmpxchg_check macro. - @ r2 = address of interrupted insn (must be preserved). - @ sp = saved regs. r7 and r8 are clobbered. - @ 1b = first critical insn, 2b = last critical insn. - @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b. - mov r7, #0xffff0fff - sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg))) - subs r8, r2, r7 - rsbcss r8, r8, #(2b - 1b) - strcs r7, [sp, #S_PC] - mov pc, lr - .previous - +#ifdef CONFIG_MMU + teq ip, ip @ set Z flag + ldr ip, [r2] @ load current val + add r3, r2, #1 @ prepare store ptr + teqeq ip, r0 @ compare with oldval if still allowed + streq r1, [r3, #-1]! @ store newval if still allowed + subs r0, r2, r3 @ if r2 == r3 the str occured #else #warning "NPTL on non MMU needs fixing" mov r0, #-1 adds r0, r0, #0 - usr_ret lr #endif + usr_ret lr #else #ifdef CONFIG_SMP mcr p15, 0, r0, c7, c10, 5 @ dmb #endif -1: ldrex r3, [r2] + ldrex r3, [r2] subs r3, r3, r0 strexeq r3, r1, [r2] - teqeq r3, #1 - beq 1b rsbs r0, r3, #0 - /* beware -- each __kuser slot must be 8 instructions max */ #ifdef CONFIG_SMP - b __kuser_memory_barrier -#else - usr_ret lr + mcr p15, 0, r0, c7, c10, 5 @ dmb #endif + usr_ret lr #endif @@ -849,7 +829,7 @@ kuser_cmpxchg_fixup: * * Clobbered: * - * none + * the Z flag might be lost * * Definition and user space usage example: * diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index c34db4e868fa..4764bd9ccee8 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -327,7 +327,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) if ((instr & hook->instr_mask) == hook->instr_val && (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { if (hook->fn(regs, instr) == 0) { - spin_unlock_irqrestore(&undef_lock, flags); + spin_unlock_irq(&undef_lock); return; } } @@ -509,7 +509,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) * existence. Don't ever use this from user code. */ case 0xfff0: - for (;;) { + { extern void do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs); unsigned long val; @@ -545,6 +545,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) up_read(&mm->mmap_sem); /* simulate a write access fault */ do_DataAbort(addr, 15 + (1 << 11), regs); + return -1; } #endif diff --git a/trunk/arch/arm/mach-at91/clock.c b/trunk/arch/arm/mach-at91/clock.c index 848efb2a4ebf..57c3b647ce83 100644 --- a/trunk/arch/arm/mach-at91/clock.c +++ b/trunk/arch/arm/mach-at91/clock.c @@ -351,7 +351,7 @@ static void init_programmable_clock(struct clk *clk) pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); parent = at91_css_to_clk(pckr & AT91_PMC_CSS); clk->parent = parent; - clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); + clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); } #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ @@ -587,8 +587,11 @@ int __init at91_clock_init(unsigned long main_clock) mckr = at91_sys_read(AT91_PMC_MCKR); mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); freq = mck.parent->rate_hz; - freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ - mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ + freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ + if (cpu_is_at91rm9200()) + mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ + else + mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ /* Register the PMC's standard clocks */ for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) diff --git a/trunk/arch/arm/mach-imx/irq.c b/trunk/arch/arm/mach-imx/irq.c index a7465db84893..0791b56caecc 100644 --- a/trunk/arch/arm/mach-imx/irq.c +++ b/trunk/arch/arm/mach-imx/irq.c @@ -43,46 +43,12 @@ * */ -#define INTCNTL_OFF 0x00 -#define NIMASK_OFF 0x04 -#define INTENNUM_OFF 0x08 -#define INTDISNUM_OFF 0x0C -#define INTENABLEH_OFF 0x10 -#define INTENABLEL_OFF 0x14 -#define INTTYPEH_OFF 0x18 -#define INTTYPEL_OFF 0x1C -#define NIPRIORITY_OFF(x) (0x20+4*(7-(x))) -#define NIVECSR_OFF 0x40 -#define FIVECSR_OFF 0x44 -#define INTSRCH_OFF 0x48 -#define INTSRCL_OFF 0x4C -#define INTFRCH_OFF 0x50 -#define INTFRCL_OFF 0x54 -#define NIPNDH_OFF 0x58 -#define NIPNDL_OFF 0x5C -#define FIPNDH_OFF 0x60 -#define FIPNDL_OFF 0x64 +#define INTENNUM_OFF 0x8 +#define INTDISNUM_OFF 0xC #define VA_AITC_BASE IO_ADDRESS(IMX_AITC_BASE) -#define IMX_AITC_INTCNTL (VA_AITC_BASE + INTCNTL_OFF) -#define IMX_AITC_NIMASK (VA_AITC_BASE + NIMASK_OFF) -#define IMX_AITC_INTENNUM (VA_AITC_BASE + INTENNUM_OFF) #define IMX_AITC_INTDISNUM (VA_AITC_BASE + INTDISNUM_OFF) -#define IMX_AITC_INTENABLEH (VA_AITC_BASE + INTENABLEH_OFF) -#define IMX_AITC_INTENABLEL (VA_AITC_BASE + INTENABLEL_OFF) -#define IMX_AITC_INTTYPEH (VA_AITC_BASE + INTTYPEH_OFF) -#define IMX_AITC_INTTYPEL (VA_AITC_BASE + INTTYPEL_OFF) -#define IMX_AITC_NIPRIORITY(x) (VA_AITC_BASE + NIPRIORITY_OFF(x)) -#define IMX_AITC_NIVECSR (VA_AITC_BASE + NIVECSR_OFF) -#define IMX_AITC_FIVECSR (VA_AITC_BASE + FIVECSR_OFF) -#define IMX_AITC_INTSRCH (VA_AITC_BASE + INTSRCH_OFF) -#define IMX_AITC_INTSRCL (VA_AITC_BASE + INTSRCL_OFF) -#define IMX_AITC_INTFRCH (VA_AITC_BASE + INTFRCH_OFF) -#define IMX_AITC_INTFRCL (VA_AITC_BASE + INTFRCL_OFF) -#define IMX_AITC_NIPNDH (VA_AITC_BASE + NIPNDH_OFF) -#define IMX_AITC_NIPNDL (VA_AITC_BASE + NIPNDL_OFF) -#define IMX_AITC_FIPNDH (VA_AITC_BASE + FIPNDH_OFF) -#define IMX_AITC_FIPNDL (VA_AITC_BASE + FIPNDL_OFF) +#define IMX_AITC_INTENNUM (VA_AITC_BASE + INTENNUM_OFF) #if 0 #define DEBUG_IRQ(fmt...) printk(fmt) @@ -256,12 +222,7 @@ imx_init_irq(void) DEBUG_IRQ("Initializing imx interrupts\n"); - /* Disable all interrupts initially. */ - /* Do not rely on the bootloader. */ - __raw_writel(0, IMX_AITC_INTENABLEH); - __raw_writel(0, IMX_AITC_INTENABLEL); - - /* Mask all GPIO interrupts as well */ + /* Mask all interrupts initially */ IMR(0) = 0; IMR(1) = 0; IMR(2) = 0; @@ -284,6 +245,6 @@ imx_init_irq(void) set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler); set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler); - /* Release masking of interrupts according to priority */ - __raw_writel(-1, IMX_AITC_NIMASK); + /* Disable all interrupts initially. */ + /* In IMX this is done in the bootloader. */ } diff --git a/trunk/include/asm-arm/arch-ixp23xx/irqs.h b/trunk/include/asm-arm/arch-ixp23xx/irqs.h index 27c580898958..e69639585721 100644 --- a/trunk/include/asm-arm/arch-ixp23xx/irqs.h +++ b/trunk/include/asm-arm/arch-ixp23xx/irqs.h @@ -153,7 +153,7 @@ */ #define NR_IXP23XX_MACH_IRQS 32 -#define NR_IRQS (NR_IXP23XX_IRQS + NR_IXP23XX_MACH_IRQS) +#define NR_IRQS NR_IXP23XX_IRQS + NR_IXP23XX_MACH_IRQS #define IXP23XX_MACH_IRQ(irq) (NR_IXP23XX_IRQ + (irq)) diff --git a/trunk/include/asm-arm/arch-omap/board-innovator.h b/trunk/include/asm-arm/arch-omap/board-innovator.h index 56d2c98e143c..b3cf33441f6e 100644 --- a/trunk/include/asm-arm/arch-omap/board-innovator.h +++ b/trunk/include/asm-arm/arch-omap/board-innovator.h @@ -37,7 +37,7 @@ #define OMAP1510P1_EMIFF_PRI_VALUE 0x00 #define NR_FPGA_IRQS 24 -#define NR_IRQS (IH_BOARD_BASE + NR_FPGA_IRQS) +#define NR_IRQS IH_BOARD_BASE + NR_FPGA_IRQS #ifndef __ASSEMBLY__ void fpga_write(unsigned char val, int reg);