diff options
Diffstat (limited to 'arch')
176 files changed, 1661 insertions, 1005 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 4877a8c8ee16..fe48fc7a3eba 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -32,8 +32,9 @@ config HAVE_OPROFILE config KPROBES bool "Kprobes" - depends on KALLSYMS && MODULES + depends on MODULES depends on HAVE_KPROBES + select KALLSYMS help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes @@ -45,7 +46,6 @@ config OPTPROBES def_bool y depends on KPROBES && HAVE_OPTPROBES depends on !PREEMPT - select KALLSYMS_ALL config HAVE_EFFICIENT_UNALIGNED_ACCESS bool diff --git a/arch/alpha/include/asm/cacheflush.h b/arch/alpha/include/asm/cacheflush.h index 01d71e1c8a9e..012f1243b1c1 100644 --- a/arch/alpha/include/asm/cacheflush.h +++ b/arch/alpha/include/asm/cacheflush.h @@ -43,6 +43,8 @@ extern void smp_imb(void); /* ??? Ought to use this in arch/alpha/kernel/signal.c too. */ #ifndef CONFIG_SMP +#include <linux/sched.h> + extern void __load_new_mm_context(struct mm_struct *); static inline void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index 804e5311c841..058937bf5a77 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -449,10 +449,13 @@ #define __NR_pwritev 491 #define __NR_rt_tgsigqueueinfo 492 #define __NR_perf_event_open 493 +#define __NR_fanotify_init 494 +#define __NR_fanotify_mark 495 +#define __NR_prlimit64 496 #ifdef __KERNEL__ -#define NR_SYSCALLS 494 +#define NR_SYSCALLS 497 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR @@ -463,6 +466,7 @@ #define __ARCH_WANT_SYS_OLD_GETRLIMIT #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_RT_SIGSUSPEND /* "Conditional" syscalls. What we want is diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index b45d913a51c3..6d159cee5f2f 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -73,8 +73,6 @@ ldq $20, HAE_REG($19); \ stq $21, HAE_CACHE($19); \ stq $21, 0($20); \ - ldq $0, 0($sp); \ - ldq $1, 8($sp); \ 99:; \ ldq $19, 72($sp); \ ldq $20, 80($sp); \ @@ -316,19 +314,24 @@ ret_from_sys_call: cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ ldq $0, SP_OFF($sp) and $0, 8, $0 - beq $0, restore_all -ret_from_reschedule: + beq $0, ret_to_kernel +ret_to_user: /* Make sure need_resched and sigpending don't change between sampling and the rti. */ lda $16, 7 call_pal PAL_swpipl ldl $5, TI_FLAGS($8) and $5, _TIF_WORK_MASK, $2 - bne $5, work_pending + bne $2, work_pending restore_all: RESTORE_ALL call_pal PAL_rti +ret_to_kernel: + lda $16, 7 + call_pal PAL_swpipl + br restore_all + .align 3 $syscall_error: /* @@ -363,7 +366,7 @@ $ret_success: * $8: current. * $19: The old syscall number, or zero if this is not a return * from a syscall that errored and is possibly restartable. - * $20: Error indication. + * $20: The old a3 value */ .align 4 @@ -392,12 +395,18 @@ $work_resched: $work_notifysig: mov $sp, $16 - br $1, do_switch_stack + bsr $1, do_switch_stack mov $sp, $17 mov $5, $18 + mov $19, $9 /* save old syscall number */ + mov $20, $10 /* save old a3 */ + and $5, _TIF_SIGPENDING, $2 + cmovne $2, 0, $9 /* we don't want double syscall restarts */ jsr $26, do_notify_resume + mov $9, $19 + mov $10, $20 bsr $1, undo_switch_stack - br restore_all + br ret_to_user .end work_pending /* @@ -430,6 +439,7 @@ strace: beq $1, 1f ldq $27, 0($2) 1: jsr $26, ($27), sys_gettimeofday +ret_from_straced: ldgp $gp, 0($26) /* check return.. */ @@ -650,7 +660,7 @@ kernel_thread: /* We don't actually care for a3 success widgetry in the kernel. Not for positive errno values. */ stq $0, 0($sp) /* $0 */ - br restore_all + br ret_to_kernel .end kernel_thread /* @@ -757,11 +767,15 @@ sys_vfork: .ent sys_sigreturn sys_sigreturn: .prologue 0 + lda $9, ret_from_straced + cmpult $26, $9, $9 mov $sp, $17 lda $18, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp) jsr $26, do_sigreturn - br $1, undo_switch_stack + bne $9, 1f + jsr $26, syscall_trace +1: br $1, undo_switch_stack br ret_from_sys_call .end sys_sigreturn @@ -770,47 +784,19 @@ sys_sigreturn: .ent sys_rt_sigreturn sys_rt_sigreturn: .prologue 0 + lda $9, ret_from_straced + cmpult $26, $9, $9 mov $sp, $17 lda $18, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp) jsr $26, do_rt_sigreturn - br $1, undo_switch_stack + bne $9, 1f + jsr $26, syscall_trace +1: br $1, undo_switch_stack br ret_from_sys_call .end sys_rt_sigreturn .align 4 - .globl sys_sigsuspend - .ent sys_sigsuspend -sys_sigsuspend: - .prologue 0 - mov $sp, $17 - br $1, do_switch_stack - mov $sp, $18 - subq $sp, 16, $sp - stq $26, 0($sp) - jsr $26, do_sigsuspend - ldq $26, 0($sp) - lda $sp, SWITCH_STACK_SIZE+16($sp) - ret -.end sys_sigsuspend - - .align 4 - .globl sys_rt_sigsuspend - .ent sys_rt_sigsuspend -sys_rt_sigsuspend: - .prologue 0 - mov $sp, $18 - br $1, do_switch_stack - mov $sp, $19 - subq $sp, 16, $sp - stq $26, 0($sp) - jsr $26, do_rt_sigsuspend - ldq $26, 0($sp) - lda $sp, SWITCH_STACK_SIZE+16($sp) - ret -.end sys_rt_sigsuspend - - .align 4 .globl sys_sethae .ent sys_sethae sys_sethae: @@ -929,15 +915,6 @@ sys_execve: .end sys_execve .align 4 - .globl osf_sigprocmask - .ent osf_sigprocmask -osf_sigprocmask: - .prologue 0 - mov $sp, $18 - jmp $31, sys_osf_sigprocmask -.end osf_sigprocmask - - .align 4 .globl alpha_ni_syscall .ent alpha_ni_syscall alpha_ni_syscall: diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c index 8ca6345bf131..253cf1a87481 100644 --- a/arch/alpha/kernel/err_ev6.c +++ b/arch/alpha/kernel/err_ev6.c @@ -90,11 +90,13 @@ static int ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, u64 c_stat, u64 c_sts, int print) { - char *sourcename[] = { "UNKNOWN", "UNKNOWN", "UNKNOWN", - "MEMORY", "BCACHE", "DCACHE", - "BCACHE PROBE", "BCACHE PROBE" }; - char *streamname[] = { "D", "I" }; - char *bitsname[] = { "SINGLE", "DOUBLE" }; + static const char * const sourcename[] = { + "UNKNOWN", "UNKNOWN", "UNKNOWN", + "MEMORY", "BCACHE", "DCACHE", + "BCACHE PROBE", "BCACHE PROBE" + }; + static const char * const streamname[] = { "D", "I" }; + static const char * const bitsname[] = { "SINGLE", "DOUBLE" }; int status = MCHK_DISPOSITION_REPORT; int source = -1, stream = -1, bits = -1; diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index 5c905aaaeccd..648ae88aeb8a 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c @@ -589,22 +589,23 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) static void marvel_print_pox_trans_sum(u64 trans_sum) { - char *pcix_cmd[] = { "Interrupt Acknowledge", - "Special Cycle", - "I/O Read", - "I/O Write", - "Reserved", - "Reserved / Device ID Message", - "Memory Read", - "Memory Write", - "Reserved / Alias to Memory Read Block", - "Reserved / Alias to Memory Write Block", - "Configuration Read", - "Configuration Write", - "Memory Read Multiple / Split Completion", - "Dual Address Cycle", - "Memory Read Line / Memory Read Block", - "Memory Write and Invalidate / Memory Write Block" + static const char * const pcix_cmd[] = { + "Interrupt Acknowledge", + "Special Cycle", + "I/O Read", + "I/O Write", + "Reserved", + "Reserved / Device ID Message", + "Memory Read", + "Memory Write", + "Reserved / Alias to Memory Read Block", + "Reserved / Alias to Memory Write Block", + "Configuration Read", + "Configuration Write", + "Memory Read Multiple / Split Completion", + "Dual Address Cycle", + "Memory Read Line / Memory Read Block", + "Memory Write and Invalidate / Memory Write Block" }; #define IO7__POX_TRANSUM__PCI_ADDR__S (0) diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c index f7ed97ce0dfd..c3b3781a03de 100644 --- a/arch/alpha/kernel/err_titan.c +++ b/arch/alpha/kernel/err_titan.c @@ -75,8 +75,12 @@ titan_parse_p_serror(int which, u64 serror, int print) int status = MCHK_DISPOSITION_REPORT; #ifdef CONFIG_VERBOSE_MCHECK - char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"}; - char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"}; + static const char * const serror_src[] = { + "GPCI", "APCI", "AGP HP", "AGP LP" + }; + static const char * const serror_cmd[] = { + "DMA Read", "DMA RMW", "SGTE Read", "Reserved" + }; #endif /* CONFIG_VERBOSE_MCHECK */ #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) @@ -140,14 +144,15 @@ titan_parse_p_perror(int which, int port, u64 perror, int print) int status = MCHK_DISPOSITION_REPORT; #ifdef CONFIG_VERBOSE_MCHECK - char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle", - "I/O Read", "I/O Write", - "Reserved", "Reserved", - "Memory Read", "Memory Write", - "Reserved", "Reserved", - "Configuration Read", "Configuration Write", - "Memory Read Multiple", "Dual Address Cycle", - "Memory Read Line","Memory Write and Invalidate" + static const char * const perror_cmd[] = { + "Interrupt Acknowledge", "Special Cycle", + "I/O Read", "I/O Write", + "Reserved", "Reserved", + "Memory Read", "Memory Write", + "Reserved", "Reserved", + "Configuration Read", "Configuration Write", + "Memory Read Multiple", "Dual Address Cycle", + "Memory Read Line", "Memory Write and Invalidate" }; #endif /* CONFIG_VERBOSE_MCHECK */ @@ -273,11 +278,11 @@ titan_parse_p_agperror(int which, u64 agperror, int print) int cmd, len; unsigned long addr; - char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)", - "Write (low-priority)", - "Write (high-priority)", - "Reserved", "Reserved", - "Flush", "Fence" + static const char * const agperror_cmd[] = { + "Read (low-priority)", "Read (high-priority)", + "Write (low-priority)", "Write (high-priority)", + "Reserved", "Reserved", + "Flush", "Fence" }; #endif /* CONFIG_VERBOSE_MCHECK */ diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 5d1e6d6ce684..547e8b84b2f7 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -15,7 +15,6 @@ #include <linux/kernel.h> #include <linux/mm.h> #include <linux/smp.h> -#include <linux/smp_lock.h> #include <linux/stddef.h> #include <linux/syscalls.h> #include <linux/unistd.h> @@ -69,7 +68,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start, { struct mm_struct *mm; - lock_kernel(); mm = current->mm; mm->end_code = bss_start + bss_len; mm->start_brk = bss_start + bss_len; @@ -78,7 +76,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start, printk("set_program_attributes(%lx %lx %lx %lx)\n", text_start, text_len, bss_start, bss_len); #endif - unlock_kernel(); return 0; } @@ -517,7 +514,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code, long error; int __user *min_buf_size_ptr; - lock_kernel(); switch (code) { case PL_SET: if (get_user(error, &args->set.nbytes)) @@ -547,7 +543,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code, error = -EOPNOTSUPP; break; }; - unlock_kernel(); return error; } @@ -594,7 +589,7 @@ SYSCALL_DEFINE2(osf_sigstack, struct sigstack __user *, uss, SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) { - char *sysinfo_table[] = { + const char *sysinfo_table[] = { utsname()->sysname, utsname()->nodename, utsname()->release, @@ -606,7 +601,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) "dummy", /* secure RPC domain */ }; unsigned long offset; - char *res; + const char *res; long len, err = -EINVAL; offset = command-1; diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 738fc824e2ea..b899e95f79fd 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -66,7 +66,7 @@ static int pci_mmap_resource(struct kobject *kobj, { struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj)); - struct resource *res = (struct resource *)attr->private; + struct resource *res = attr->private; enum pci_mmap_state mmap_type; struct pci_bus_region bar; int i; diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 842dba308eab..3ec35066f1dc 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -356,7 +356,7 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) dest[27] = pt->r27; dest[28] = pt->r28; dest[29] = pt->gp; - dest[30] = rdusp(); + dest[30] = ti == current_thread_info() ? rdusp() : ti->pcb.usp; dest[31] = pt->pc; /* Once upon a time this was the PS value. Which is stupid diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 0932dbb1ef8e..6f7feb5db271 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -41,46 +41,20 @@ static void do_signal(struct pt_regs *, struct switch_stack *, /* * The OSF/1 sigprocmask calling sequence is different from the * C sigprocmask() sequence.. - * - * how: - * 1 - SIG_BLOCK - * 2 - SIG_UNBLOCK - * 3 - SIG_SETMASK - * - * We change the range to -1 .. 1 in order to let gcc easily - * use the conditional move instructions. - * - * Note that we don't need to acquire the kernel lock for SMP - * operation, as all of this is local to this thread. */ -SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask, - struct pt_regs *, regs) +SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask) { - unsigned long oldmask = -EINVAL; - - if ((unsigned long)how-1 <= 2) { - long sign = how-2; /* -1 .. 1 */ - unsigned long block, unblock; - - newmask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - oldmask = current->blocked.sig[0]; - - unblock = oldmask & ~newmask; - block = oldmask | newmask; - if (!sign) - block = unblock; - if (sign <= 0) - newmask = block; - if (_NSIG_WORDS > 1 && sign > 0) - sigemptyset(¤t->blocked); - current->blocked.sig[0] = newmask; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - regs->r0 = 0; /* special no error return */ + sigset_t oldmask; + sigset_t mask; + unsigned long res; + + siginitset(&mask, newmask & _BLOCKABLE); + res = sigprocmask(how, &mask, &oldmask); + if (!res) { + force_successful_syscall_return(); + res = oldmask.sig[0]; } - return oldmask; + return res; } SYSCALL_DEFINE3(osf_sigaction, int, sig, @@ -94,9 +68,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, 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_flags, &act->sa_flags)) + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) return -EFAULT; - __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); new_ka.ka_restorer = NULL; } @@ -106,9 +80,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, 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_flags, &oact->sa_flags)) + __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_mask.sig[0], &oact->sa_mask); } return ret; @@ -144,8 +118,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage int -do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) +SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) { mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); @@ -154,41 +127,6 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - /* Indicate EINTR on return from any possible signal handler, - which will not come back through here, but via sigreturn. */ - regs->r0 = EINTR; - regs->r19 = 1; - - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; -} - -asmlinkage int -do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, - struct pt_regs *regs, struct switch_stack *sw) -{ - sigset_t set; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - if (copy_from_user(&set, uset, sizeof(set))) - return -EFAULT; - - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - /* Indicate EINTR on return from any possible signal handler, - which will not come back through here, but via sigreturn. */ - regs->r0 = EINTR; - regs->r19 = 1; - current->state = TASK_INTERRUPTIBLE; schedule(); set_thread_flag(TIF_RESTORE_SIGMASK); @@ -239,6 +177,8 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long usp; long i, err = __get_user(regs->pc, &sc->sc_pc); + current_thread_info()->restart_block.fn = do_no_restart_syscall; + sw->r26 = (unsigned long) ret_from_sys_call; err |= __get_user(regs->r0, sc->sc_regs+0); @@ -591,7 +531,6 @@ syscall_restart(unsigned long r0, unsigned long r19, regs->pc -= 4; break; case ERESTART_RESTARTBLOCK: - current_thread_info()->restart_block.fn = do_no_restart_syscall; regs->r0 = EINTR; break; } diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index 4afc1a1e2e5a..f0df3fbd8402 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c @@ -87,7 +87,7 @@ static int srm_env_proc_show(struct seq_file *m, void *v) srm_env_t *entry; char *page; - entry = (srm_env_t *)m->private; + entry = m->private; page = (char *)__get_free_page(GFP_USER); if (!page) return -ENOMEM; diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 09acb786e72b..a6a1de9db16f 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -58,7 +58,7 @@ sys_call_table: .quad sys_open /* 45 */ .quad alpha_ni_syscall .quad sys_getxgid - .quad osf_sigprocmask + .quad sys_osf_sigprocmask .quad alpha_ni_syscall .quad alpha_ni_syscall /* 50 */ .quad sys_acct @@ -512,6 +512,9 @@ sys_call_table: .quad sys_pwritev .quad sys_rt_tgsigqueueinfo .quad sys_perf_event_open + .quad sys_fanotify_init + .quad sys_fanotify_mark /* 495 */ + .quad sys_prlimit64 .size sys_call_table, . - sys_call_table .type sys_call_table, @object diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index eacceb26d9c8..396af1799ea4 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -191,16 +191,16 @@ irqreturn_t timer_interrupt(int irq, void *dev) write_sequnlock(&xtime_lock); -#ifndef CONFIG_SMP - while (nticks--) - update_process_times(user_mode(get_irq_regs())); -#endif - if (test_perf_event_pending()) { clear_perf_event_pending(); perf_event_do_pending(); } +#ifndef CONFIG_SMP + while (nticks--) + update_process_times(user_mode(get_irq_regs())); +#endif + return IRQ_HANDLED; } diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index b14f015008ad..0414e021a91c 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -13,7 +13,6 @@ #include <linux/sched.h> #include <linux/tty.h> #include <linux/delay.h> -#include <linux/smp_lock.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kallsyms.h> @@ -623,7 +622,6 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, return; } - lock_kernel(); printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", pc, va, opcode, reg); do_exit(SIGSEGV); @@ -646,7 +644,6 @@ got_exception: * Yikes! No one to forward the exception to. * Since the registers are in a weird format, dump them ourselves. */ - lock_kernel(); printk("%s(%d): unhandled unaligned exception\n", current->comm, task_pid_nr(current)); diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 16bc8eb4901c..88c97bc7a6f5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -271,7 +271,6 @@ config ARCH_AT91 bool "Atmel AT91" select ARCH_REQUIRE_GPIOLIB select HAVE_CLK - select ARCH_USES_GETTIMEOFFSET help This enables support for systems based on the Atmel AT91RM9200, AT91SAM9 and AT91CAP9 processors. @@ -1051,6 +1050,32 @@ config ARM_ERRATA_460075 ACTLR register. Note that setting specific bits in the ACTLR register may not be available in non-secure mode. +config ARM_ERRATA_742230 + bool "ARM errata: DMB operation may be faulty" + depends on CPU_V7 && SMP + help + This option enables the workaround for the 742230 Cortex-A9 + (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction + between two write operations may not ensure the correct visibility + ordering of the two writes. This workaround sets a specific bit in + the diagnostic register of the Cortex-A9 which causes the DMB + instruction to behave as a DSB, ensuring the correct behaviour of + the two writes. + +config ARM_ERRATA_742231 + bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption" + depends on CPU_V7 && SMP + help + This option enables the workaround for the 742231 Cortex-A9 + (r2p0..r2p2) erratum. Under certain conditions, specific to the + Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode, + accessing some data located in the same cache line, may get corrupted + data due to bad handling of the address hazard when the line gets + replaced from one of the CPUs at the same time as another CPU is + accessing it. This workaround sets specific bits in the diagnostic + register of the Cortex-A9 which reduces the linefill issuing + capabilities of the processor. + config PL310_ERRATA_588369 bool "Clean & Invalidate maintenance operations do not invalidate clean lines" depends on CACHE_L2X0 && ARCH_OMAP4 @@ -1576,97 +1601,6 @@ config AUTO_ZRELADDR 0xf8000000. This assumes the zImage being placed in the first 128MB from start of memory. -config ZRELADDR - hex "Physical address of the decompressed kernel image" - depends on !AUTO_ZRELADDR - default 0x00008000 if ARCH_BCMRING ||\ - ARCH_CNS3XXX ||\ - ARCH_DOVE ||\ - ARCH_EBSA110 ||\ - ARCH_FOOTBRIDGE ||\ - ARCH_INTEGRATOR ||\ - ARCH_IOP13XX ||\ - ARCH_IOP33X ||\ - ARCH_IXP2000 ||\ - ARCH_IXP23XX ||\ - ARCH_IXP4XX ||\ - ARCH_KIRKWOOD ||\ - ARCH_KS8695 ||\ - ARCH_LOKI ||\ - ARCH_MMP ||\ - ARCH_MV78XX0 ||\ - ARCH_NOMADIK ||\ - ARCH_NUC93X ||\ - ARCH_NS9XXX ||\ - ARCH_ORION5X ||\ - ARCH_SPEAR3XX ||\ - ARCH_SPEAR6XX ||\ - ARCH_TEGRA ||\ - ARCH_U8500 ||\ - ARCH_VERSATILE ||\ - ARCH_W90X900 - default 0x08008000 if ARCH_MX1 ||\ - ARCH_SHARK - default 0x10008000 if ARCH_MSM ||\ - ARCH_OMAP1 ||\ - ARCH_RPC - default 0x20008000 if ARCH_S5P6440 ||\ - ARCH_S5P6442 ||\ - ARCH_S5PC100 ||\ - ARCH_S5PV210 - default 0x30008000 if ARCH_S3C2410 ||\ - ARCH_S3C2400 ||\ - ARCH_S3C2412 ||\ - ARCH_S3C2416 ||\ - ARCH_S3C2440 ||\ - ARCH_S3C2443 - default 0x40008000 if ARCH_STMP378X ||\ - ARCH_STMP37XX ||\ - ARCH_SH7372 ||\ - ARCH_SH7377 ||\ - ARCH_S5PV310 - default 0x50008000 if ARCH_S3C64XX ||\ - ARCH_SH7367 - default 0x60008000 if ARCH_VEXPRESS - default 0x80008000 if ARCH_MX25 ||\ - ARCH_MX3 ||\ - ARCH_NETX ||\ - ARCH_OMAP2PLUS ||\ - ARCH_PNX4008 - default 0x90008000 if ARCH_MX5 ||\ - ARCH_MX91231 - default 0xa0008000 if ARCH_IOP32X ||\ - ARCH_PXA ||\ - MACH_MX27 - default 0xc0008000 if ARCH_LH7A40X ||\ - MACH_MX21 - default 0xf0008000 if ARCH_AAEC2000 ||\ - ARCH_L7200 - default 0xc0028000 if ARCH_CLPS711X - default 0x70008000 if ARCH_AT91 && (ARCH_AT91CAP9 || ARCH_AT91SAM9G45) - default 0x20008000 if ARCH_AT91 && !(ARCH_AT91CAP9 || ARCH_AT91SAM9G45) - default 0xc0008000 if ARCH_DAVINCI && ARCH_DAVINCI_DA8XX - default 0x80008000 if ARCH_DAVINCI && !ARCH_DAVINCI_DA8XX - default 0x00008000 if ARCH_EP93XX && EP93XX_SDCE3_SYNC_PHYS_OFFSET - default 0xc0008000 if ARCH_EP93XX && EP93XX_SDCE0_PHYS_OFFSET - default 0xd0008000 if ARCH_EP93XX && EP93XX_SDCE1_PHYS_OFFSET - default 0xe0008000 if ARCH_EP93XX && EP93XX_SDCE2_PHYS_OFFSET - default 0xf0008000 if ARCH_EP93XX && EP93XX_SDCE3_ASYNC_PHYS_OFFSET - default 0x00008000 if ARCH_GEMINI && GEMINI_MEM_SWAP - default 0x10008000 if ARCH_GEMINI && !GEMINI_MEM_SWAP - default 0x70008000 if ARCH_REALVIEW && REALVIEW_HIGH_PHYS_OFFSET - default 0x00008000 if ARCH_REALVIEW && !REALVIEW_HIGH_PHYS_OFFSET - default 0xc0208000 if ARCH_SA1100 && SA1111 - default 0xc0008000 if ARCH_SA1100 && !SA1111 - default 0x30108000 if ARCH_S3C2410 && PM_H1940 - default 0x28E08000 if ARCH_U300 && MACH_U300_SINGLE_RAM - default 0x48008000 if ARCH_U300 && !MACH_U300_SINGLE_RAM - help - ZRELADDR is the physical address where the decompressed kernel - image will be placed. ZRELADDR has to be specified when the - assumption of AUTO_ZRELADDR is not valid, or when ZBOOT_ROM is - selected. - endmenu menu "CPU Power Management" diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f705213caa88..4a590f4113e2 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -14,16 +14,18 @@ MKIMAGE := $(srctree)/scripts/mkuboot.sh ifneq ($(MACHINE),) --include $(srctree)/$(MACHINE)/Makefile.boot +include $(srctree)/$(MACHINE)/Makefile.boot endif # Note: the following conditions must always be true: +# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) # PARAMS_PHYS must be within 4MB of ZRELADDR # INITRD_PHYS must be in RAM +ZRELADDR := $(zreladdr-y) PARAMS_PHYS := $(params_phys-y) INITRD_PHYS := $(initrd_phys-y) -export INITRD_PHYS PARAMS_PHYS +export ZRELADDR INITRD_PHYS PARAMS_PHYS targets := Image zImage xipImage bootpImage uImage @@ -65,7 +67,7 @@ quiet_cmd_uimage = UIMAGE $@ ifeq ($(CONFIG_ZBOOT_ROM),y) $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) else -$(obj)/uImage: LOADADDR=$(CONFIG_ZRELADDR) +$(obj)/uImage: LOADADDR=$(ZRELADDR) endif ifeq ($(CONFIG_THUMB2_KERNEL),y) diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 68775e33476c..65a7c1c588a9 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -79,6 +79,10 @@ endif EXTRA_CFLAGS := -fpic -fno-builtin EXTRA_AFLAGS := -Wa,-march=all +# Supply ZRELADDR to the decompressor via a linker symbol. +ifneq ($(CONFIG_AUTO_ZRELADDR),y) +LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR) +endif ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) LDFLAGS_vmlinux += --be8 endif @@ -112,5 +116,5 @@ CFLAGS_font.o := -Dstatic= $(obj)/font.c: $(FONTC) $(call cmd,shipped) -$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config +$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG) @sed "$(SEDFLAGS)" < $< > $@ diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 6af9907c3b5c..6825c34646d4 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -177,7 +177,7 @@ not_angel: and r4, pc, #0xf8000000 add r4, r4, #TEXT_OFFSET #else - ldr r4, =CONFIG_ZRELADDR + ldr r4, =zreladdr #endif subs r0, r0, r1 @ calculate the delta offset diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 6c0913562455..1bec96e85196 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -263,6 +263,22 @@ static int it8152_pci_platform_notify_remove(struct device *dev) return 0; } +int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) +{ + dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", + __func__, dma_addr, size); + return (dev->bus == &pci_bus_type) && + ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); +} + +int dma_set_coherent_mask(struct device *dev, u64 mask) +{ + if (mask >= PHYS_OFFSET + SZ_64M - 1) + return 0; + + return -EIO; +} + int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) { it8152_io.start = IT8152_IO_BASE + 0x12000; diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index c226fe10553e..c568da7dcae4 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -288,15 +288,7 @@ extern void dmabounce_unregister_dev(struct device *); * DMA access and 1 if the buffer needs to be bounced. * */ -#ifdef CONFIG_SA1111 extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); -#else -static inline int dma_needs_bounce(struct device *dev, dma_addr_t addr, - size_t size) -{ - return 0; -} -#endif /* * The DMA API, implemented by dmabounce.c. See below for descriptions. diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 48837e6d8887..b5799a3b7117 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h @@ -17,7 +17,7 @@ * counter interrupts are regular interrupts and not an NMI. This * means that when we receive the interrupt we can call * perf_event_do_pending() that handles all of the work with - * interrupts enabled. + * interrupts disabled. */ static inline void set_perf_event_pending(void) diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index ab68cf1ef80f..e90b167ea848 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -317,6 +317,10 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE #define pgprot_dmacoherent(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) +#define __HAVE_PHYS_MEM_ACCESS_PROT +struct file; +extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); #else #define pgprot_dmacoherent(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index d02cfb683487..c891eb76c0e3 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -393,6 +393,9 @@ #define __NR_perf_event_open (__NR_SYSCALL_BASE+364) #define __NR_recvmmsg (__NR_SYSCALL_BASE+365) #define __NR_accept4 (__NR_SYSCALL_BASE+366) +#define __NR_fanotify_init (__NR_SYSCALL_BASE+367) +#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368) +#define __NR_prlimit64 (__NR_SYSCALL_BASE+369) /* * The following SWIs are ARM private. diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index afeb71fa72cb..5c26eccef998 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -376,6 +376,9 @@ CALL(sys_perf_event_open) /* 365 */ CALL(sys_recvmmsg) CALL(sys_accept4) + CALL(sys_fanotify_init) + CALL(sys_fanotify_mark) + CALL(sys_prlimit64) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index f05a35a59694..7885722bdf4e 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -48,6 +48,8 @@ work_pending: beq no_work_pending mov r0, sp @ 'regs' mov r2, why @ 'syscall' + tst r1, #_TIF_SIGPENDING @ delivering a signal? + movne why, #0 @ prevent further restarts bl do_notify_resume b ret_slow_syscall @ Check work again @@ -418,11 +420,13 @@ ENDPROC(sys_clone_wrapper) sys_sigreturn_wrapper: add r0, sp, #S_OFF + mov why, #0 @ prevent syscall restart handling b sys_sigreturn ENDPROC(sys_sigreturn_wrapper) sys_rt_sigreturn_wrapper: add r0, sp, #S_OFF + mov why, #0 @ prevent syscall restart handling b sys_rt_sigreturn ENDPROC(sys_rt_sigreturn_wrapper) diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 417c392ddf1c..ecbb0288e5dd 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -319,8 +319,8 @@ validate_event(struct cpu_hw_events *cpuc, { struct hw_perf_event fake_event = event->hw; - if (event->pmu && event->pmu != &pmu) - return 0; + if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) + return 1; return armpmu->get_event_idx(cpuc, &fake_event) >= 0; } @@ -1041,8 +1041,8 @@ armv6pmu_handle_irq(int irq_num, /* * Handle the pending perf events. * - * Note: this call *must* be run with interrupts enabled. For - * platforms that can have the PMU interrupts raised as a PMI, this + * Note: this call *must* be run with interrupts disabled. For + * platforms that can have the PMU interrupts raised as an NMI, this * will not work. */ perf_event_do_pending(); @@ -2017,8 +2017,8 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) /* * Handle the pending perf events. * - * Note: this call *must* be run with interrupts enabled. For - * platforms that can have the PMU interrupts raised as a PMI, this + * Note: this call *must* be run with interrupts disabled. For + * platforms that can have the PMU interrupts raised as an NMI, this * will not work. */ perf_event_do_pending(); diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 753c0d31a3d3..c67b47f1c0fd 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -121,8 +121,8 @@ static struct clk ssc1_clk = { .pmc_mask = 1 << AT91SAM9G45_ID_SSC1, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk tcb_clk = { - .name = "tcb_clk", +static struct clk tcb0_clk = { + .name = "tcb0_clk", .pmc_mask = 1 << AT91SAM9G45_ID_TCB, .type = CLK_TYPE_PERIPHERAL, }; @@ -192,6 +192,14 @@ static struct clk ohci_clk = { .parent = &uhphs_clk, }; +/* One additional fake clock for second TC block */ +static struct clk tcb1_clk = { + .name = "tcb1_clk", + .pmc_mask = 0, + .type = CLK_TYPE_PERIPHERAL, + .parent = &tcb0_clk, +}; + static struct clk *periph_clocks[] __initdata = { &pioA_clk, &pioB_clk, @@ -208,7 +216,7 @@ static struct clk *periph_clocks[] __initdata = { &spi1_clk, &ssc0_clk, &ssc1_clk, - &tcb_clk, + &tcb0_clk, &pwm_clk, &tsc_clk, &dma_clk, @@ -221,6 +229,7 @@ static struct clk *periph_clocks[] __initdata = { &mmc1_clk, // irq0 &ohci_clk, + &tcb1_clk, }; /* diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 809114d5a5a6..1276babf84d5 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -46,7 +46,7 @@ static struct resource hdmac_resources[] = { .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, .flags = IORESOURCE_MEM, }, - [2] = { + [1] = { .start = AT91SAM9G45_ID_DMA, .end = AT91SAM9G45_ID_DMA, .flags = IORESOURCE_IRQ, @@ -426,7 +426,7 @@ static struct i2c_gpio_platform_data pdata_i2c0 = { .sda_is_open_drain = 1, .scl_pin = AT91_PIN_PA21, .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ + .udelay = 5, /* ~100 kHz */ }; static struct platform_device at91sam9g45_twi0_device = { @@ -440,7 +440,7 @@ static struct i2c_gpio_platform_data pdata_i2c1 = { .sda_is_open_drain = 1, .scl_pin = AT91_PIN_PB11, .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ + .udelay = 5, /* ~100 kHz */ }; static struct platform_device at91sam9g45_twi1_device = { @@ -835,9 +835,9 @@ static struct platform_device at91sam9g45_tcb1_device = { static void __init at91_add_device_tc(void) { /* this chip has one clock and irq for all six TC channels */ - at91_clock_associate("tcb_clk", &at91sam9g45_tcb0_device.dev, "t0_clk"); + at91_clock_associate("tcb0_clk", &at91sam9g45_tcb0_device.dev, "t0_clk"); platform_device_register(&at91sam9g45_tcb0_device); - at91_clock_associate("tcb_clk", &at91sam9g45_tcb1_device.dev, "t0_clk"); + at91_clock_associate("tcb1_clk", &at91sam9g45_tcb1_device.dev, "t0_clk"); platform_device_register(&at91sam9g45_tcb1_device); } #else diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index c4c8865d52d7..65eb0943194f 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -93,11 +93,12 @@ static struct resource dm9000_resource[] = { .start = AT91_PIN_PC11, .end = AT91_PIN_PC11, .flags = IORESOURCE_IRQ + | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, } }; static struct dm9000_plat_data dm9000_platdata = { - .flags = DM9000_PLATF_16BITONLY, + .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM, }; static struct platform_device dm9000_device = { @@ -168,17 +169,6 @@ static struct at91_udc_data __initdata ek_udc_data = { /* - * MCI (SD/MMC) - */ -static struct at91_mmc_data __initdata ek_mmc_data = { - .wire4 = 1, -// .det_pin = ... not connected -// .wp_pin = ... not connected -// .vcc_pin = ... not connected -}; - - -/* * NAND flash */ static struct mtd_partition __initdata ek_nand_partition[] = { @@ -246,6 +236,10 @@ static void __init ek_add_device_nand(void) at91_add_device_nand(&ek_nand_data); } +/* + * SPI related devices + */ +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) /* * ADS7846 Touchscreen @@ -356,6 +350,19 @@ static struct spi_board_info ek_spi_devices[] = { #endif }; +#else /* CONFIG_SPI_ATMEL_* */ +/* spi0 and mmc/sd share the same PIO pins: cannot be used at the same time */ + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .wire4 = 1, +}; + +#endif /* CONFIG_SPI_ATMEL_* */ + /* * LCD Controller diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 7f7da439341f..7525cee3983f 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -501,7 +501,8 @@ postcore_initcall(at91_clk_debugfs_init); int __init clk_register(struct clk *clk) { if (clk_is_peripheral(clk)) { - clk->parent = &mck; + if (!clk->parent) + clk->parent = &mck; clk->mode = pmc_periph_mode; list_add_tail(&clk->node, &clocks); } diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 3d996b659ff4..9be261beae7d 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -769,8 +769,7 @@ static struct map_desc dm355_io_desc[] = { .virtual = SRAM_VIRT, .pfn = __phys_to_pfn(0x00010000), .length = SZ_32K, - /* MT_MEMORY_NONCACHED requires supersection alignment */ - .type = MT_DEVICE, + .type = MT_MEMORY_NONCACHED, }, }; diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 6b6f4c643709..7781e35daec3 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -969,8 +969,7 @@ static struct map_desc dm365_io_desc[] = { .virtual = SRAM_VIRT, .pfn = __phys_to_pfn(0x00010000), .length = SZ_32K, - /* MT_MEMORY_NONCACHED requires supersection alignment */ - .type = MT_DEVICE, + .type = MT_MEMORY_NONCACHED, }, }; diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 40fec315c99a..5e5b0a7831fb 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -653,8 +653,7 @@ static struct map_desc dm644x_io_desc[] = { .virtual = SRAM_VIRT, .pfn = __phys_to_pfn(0x00008000), .length = SZ_16K, - /* MT_MEMORY_NONCACHED requires supersection alignment */ - .type = MT_DEVICE, + .type = MT_MEMORY_NONCACHED, }, }; diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index e4a3df1872ac..26e8a9c7f50b 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -737,8 +737,7 @@ static struct map_desc dm646x_io_desc[] = { .virtual = SRAM_VIRT, .pfn = __phys_to_pfn(0x00010000), .length = SZ_32K, - /* MT_MEMORY_NONCACHED requires supersection alignment */ - .type = MT_DEVICE, + .type = MT_MEMORY_NONCACHED, }, }; diff --git a/arch/arm/mach-dove/include/mach/io.h b/arch/arm/mach-dove/include/mach/io.h index 3b3e4721ce2e..eb4936ff90ad 100644 --- a/arch/arm/mach-dove/include/mach/io.h +++ b/arch/arm/mach-dove/include/mach/io.h @@ -13,8 +13,8 @@ #define IO_SPACE_LIMIT 0xffffffff -#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\ - DOVE_PCIE0_IO_VIRT_BASE)) -#define __mem_pci(a) (a) +#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \ + DOVE_PCIE0_IO_VIRT_BASE)) +#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 8bf3cec98cfa..4566bd1c8660 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -560,4 +560,4 @@ static int __init ep93xx_clock_init(void) clkdev_add_table(clocks, ARRAY_SIZE(clocks)); return 0; } -arch_initcall(ep93xx_clock_init); +postcore_initcall(ep93xx_clock_init); diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 61cd4d64b985..24498a932ba6 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -503,6 +503,14 @@ struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys) return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); } +int dma_set_coherent_mask(struct device *dev, u64 mask) +{ + if (mask >= SZ_64M - 1) + return 0; + + return -EIO; +} + EXPORT_SYMBOL(ixp4xx_pci_read); EXPORT_SYMBOL(ixp4xx_pci_write); diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h index f91ca6d4fbe8..8138371c406e 100644 --- a/arch/arm/mach-ixp4xx/include/mach/hardware.h +++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h @@ -26,6 +26,8 @@ #define PCIBIOS_MAX_MEM 0x4BFFFFFF #endif +#define ARCH_HAS_DMA_SET_COHERENT_MASK + #define pcibios_assign_all_busses() 1 /* Register locations and bits */ diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 93fc2ec95e76..6e924b398919 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -38,7 +38,7 @@ #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 #define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 -#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000 +#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000 #define KIRKWOOD_PCIE1_IO_SIZE SZ_1M #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 55e7f00836b7..513ad3102d7c 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -117,7 +117,7 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp) * IORESOURCE_IO */ pp->res[0].name = "PCIe 0 I/O Space"; - pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE; + pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE; pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; pp->res[0].flags = IORESOURCE_IO; @@ -139,7 +139,7 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp) * IORESOURCE_IO */ pp->res[0].name = "PCIe 1 I/O Space"; - pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE; + pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE; pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1; pp->res[0].flags = IORESOURCE_IO; diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h index 4f5b0e0ce6cf..1a8a25edb1b4 100644 --- a/arch/arm/mach-mmp/include/mach/system.h +++ b/arch/arm/mach-mmp/include/mach/system.h @@ -9,6 +9,8 @@ #ifndef __ASM_MACH_SYSTEM_H #define __ASM_MACH_SYSTEM_H +#include <mach/cputype.h> + static inline void arch_idle(void) { cpu_do_idle(); @@ -16,6 +18,9 @@ static inline void arch_idle(void) static inline void arch_reset(char mode, const char *cmd) { - cpu_reset(0); + if (cpu_is_pxa168()) + cpu_reset(0xffff0000); + else + cpu_reset(0); } #endif /* __ASM_MACH_SYSTEM_H */ diff --git a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c index 91931dcb0689..4aaadc753d3e 100644 --- a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c @@ -215,7 +215,7 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = { * Add platform devices present on this baseboard and init * them from CPU side as far as required to use them later on */ -void __init eukrea_mbimxsd_baseboard_init(void) +void __init eukrea_mbimxsd25_baseboard_init(void) { if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, ARRAY_SIZE(eukrea_mbimxsd_pads))) diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c index a5f0174290b4..e064bb3d6919 100644 --- a/arch/arm/mach-mx25/mach-cpuimx25.c +++ b/arch/arm/mach-mx25/mach-cpuimx25.c @@ -147,8 +147,8 @@ static void __init eukrea_cpuimx25_init(void) if (!otg_mode_host) mxc_register_device(&otg_udc_device, &otg_device_pdata); -#ifdef CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD - eukrea_mbimxsd_baseboard_init(); +#ifdef CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD + eukrea_mbimxsd25_baseboard_init(); #endif } diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c index d3af0fdf8475..7a62e744a8b0 100644 --- a/arch/arm/mach-mx3/clock-imx35.c +++ b/arch/arm/mach-mx3/clock-imx35.c @@ -155,7 +155,7 @@ static unsigned long get_rate_arm(void) aad = &clk_consumer[(pdr0 >> 16) & 0xf]; if (aad->sel) - fref = fref * 2 / 3; + fref = fref * 3 / 4; return fref / aad->arm; } @@ -164,7 +164,7 @@ static unsigned long get_rate_ahb(struct clk *clk) { unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); struct arm_ahb_div *aad; - unsigned long fref = get_rate_mpll(); + unsigned long fref = get_rate_arm(); aad = &clk_consumer[(pdr0 >> 16) & 0xf]; @@ -176,16 +176,11 @@ static unsigned long get_rate_ipg(struct clk *clk) return get_rate_ahb(NULL) >> 1; } -static unsigned long get_3_3_div(unsigned long in) -{ - return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1); -} - static unsigned long get_rate_uart(struct clk *clk) { unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); - unsigned long div = get_3_3_div(pdr4 >> 10); + unsigned long div = ((pdr4 >> 10) & 0x3f) + 1; if (pdr3 & (1 << 14)) return get_rate_arm() / div; @@ -216,7 +211,7 @@ static unsigned long get_rate_sdhc(struct clk *clk) break; } - return rate / get_3_3_div(div); + return rate / (div + 1); } static unsigned long get_rate_mshc(struct clk *clk) @@ -270,7 +265,7 @@ static unsigned long get_rate_csi(struct clk *clk) else rate = get_rate_ppll(); - return rate / get_3_3_div((pdr2 >> 16) & 0x3f); + return rate / (((pdr2 >> 16) & 0x3f) + 1); } static unsigned long get_rate_otg(struct clk *clk) @@ -283,25 +278,51 @@ static unsigned long get_rate_otg(struct clk *clk) else rate = get_rate_ppll(); - return rate / get_3_3_div((pdr4 >> 22) & 0x3f); + return rate / (((pdr4 >> 22) & 0x3f) + 1); } static unsigned long get_rate_ipg_per(struct clk *clk) { unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); - unsigned long div1, div2; + unsigned long div; if (pdr0 & (1 << 26)) { - div1 = (pdr4 >> 19) & 0x7; - div2 = (pdr4 >> 16) & 0x7; - return get_rate_arm() / ((div1 + 1) * (div2 + 1)); + div = (pdr4 >> 16) & 0x3f; + return get_rate_arm() / (div + 1); } else { - div1 = (pdr0 >> 12) & 0x7; - return get_rate_ahb(NULL) / div1; + div = (pdr0 >> 12) & 0x7; + return get_rate_ahb(NULL) / (div + 1); } } +static unsigned long get_rate_hsp(struct clk *clk) +{ + unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03; + unsigned long fref = get_rate_mpll(); + + if (fref > 400 * 1000 * 1000) { + switch (hsp_podf) { + case 0: + return fref >> 2; + case 1: + return fref >> 3; + case 2: + return fref / 3; + } + } else { + switch (hsp_podf) { + case 0: + case 2: + return fref / 3; + case 1: + return fref / 6; + } + } + + return 0; +} + static int clk_cgr_enable(struct clk *clk) { u32 reg; @@ -359,7 +380,7 @@ DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL); DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL); DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL); DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL); -DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_ahb, NULL); +DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_hsp, NULL); DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL); DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL); DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL); @@ -485,10 +506,10 @@ static struct clk_lookup lookups[] = { int __init mx35_clocks_init() { - unsigned int ll = 0; + unsigned int cgr2 = 3 << 26, cgr3 = 0; #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) - ll = (3 << 16); + cgr2 |= 3 << 16; #endif clkdev_add_table(lookups, ARRAY_SIZE(lookups)); @@ -499,8 +520,20 @@ int __init mx35_clocks_init() __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), CCM_BASE + CCM_CGR1); - __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); - __raw_writel(0, CCM_BASE + CCM_CGR3); + + /* + * Check if we came up in internal boot mode. If yes, we need some + * extra clocks turned on, otherwise the MX35 boot ROM code will + * hang after a watchdog reset. + */ + if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) { + /* Additionally turn on UART1, SCC, and IIM clocks */ + cgr2 |= 3 << 16 | 3 << 4; + cgr3 |= 3 << 2; + } + + __raw_writel(cgr2, CCM_BASE + CCM_CGR2); + __raw_writel(cgr3, CCM_BASE + CCM_CGR3); mxc_timer_init(&gpt_clk, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c index 1dc5004df866..f8f15e3ac7a0 100644 --- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c @@ -216,7 +216,7 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = { * Add platform devices present on this baseboard and init * them from CPU side as far as required to use them later on */ -void __init eukrea_mbimxsd_baseboard_init(void) +void __init eukrea_mbimxsd35_baseboard_init(void) { if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, ARRAY_SIZE(eukrea_mbimxsd_pads))) diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c index 9770a6a973be..2a4f8b781ba4 100644 --- a/arch/arm/mach-mx3/mach-cpuimx35.c +++ b/arch/arm/mach-mx3/mach-cpuimx35.c @@ -201,8 +201,8 @@ static void __init mxc_board_init(void) if (!otg_mode_host) mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata); -#ifdef CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD - eukrea_mbimxsd_baseboard_init(); +#ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD + eukrea_mbimxsd35_baseboard_init(); #endif } diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 6af69def357f..57c10a9926cc 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -56,7 +56,7 @@ static void _clk_ccgr_disable(struct clk *clk) { u32 reg; reg = __raw_readl(clk->enable_reg); - reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift); + reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); __raw_writel(reg, clk->enable_reg); } diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 268a9bc6be8a..58093d9e07be 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c @@ -312,8 +312,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, freqs.cpu = policy->cpu; if (freq_debug) - pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, " - "(SDRAM %d Mhz)\n", + pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", freqs.new / 1000, (pxa_freq_settings[idx].div2) ? (new_freq_mem / 2000) : (new_freq_mem / 1000)); @@ -398,7 +397,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, return 0; } -static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) +static int pxa_cpufreq_init(struct cpufreq_policy *policy) { int i; unsigned int freq; diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 27fa329d9a8b..0a0d0fe99220 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c @@ -204,7 +204,7 @@ static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, return 0; } -static __init int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) +static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) { int ret = -EINVAL; diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 7f64d24cd564..814f1458a06a 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h @@ -264,23 +264,35 @@ * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x * == 0x3 for pxa300/pxa310/pxa320 */ +#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) #define __cpu_is_pxa2xx(id) \ ({ \ unsigned int _id = (id) >> 13 & 0x7; \ _id <= 0x2; \ }) +#else +#define __cpu_is_pxa2xx(id) (0) +#endif +#ifdef CONFIG_PXA3xx #define __cpu_is_pxa3xx(id) \ ({ \ unsigned int _id = (id) >> 13 & 0x7; \ _id == 0x3; \ }) +#else +#define __cpu_is_pxa3xx(id) (0) +#endif +#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) #define __cpu_is_pxa93x(id) \ ({ \ unsigned int _id = (id) >> 4 & 0xfff; \ _id == 0x683 || _id == 0x693; \ }) +#else +#define __cpu_is_pxa93x(id) (0) +#endif #define cpu_is_pxa2xx() \ ({ \ @@ -309,7 +321,7 @@ extern unsigned long get_clock_tick_rate(void); #define PCIBIOS_MIN_IO 0 #define PCIBIOS_MIN_MEM 0 #define pcibios_assign_all_busses() 1 +#define ARCH_HAS_DMA_SET_COHERENT_MASK #endif - #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index 262691fb97d8..fdca3be47d9b 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h @@ -6,6 +6,8 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H +#include <mach/hardware.h> + #define IO_SPACE_LIMIT 0xffffffff /* diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h index 7139e0dc26d1..4e1287070d21 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h @@ -71,10 +71,10 @@ #define GPIO46_CI_DD_7 MFP_CFG_DRV(GPIO46, AF0, DS04X) #define GPIO47_CI_DD_8 MFP_CFG_DRV(GPIO47, AF1, DS04X) #define GPIO48_CI_DD_9 MFP_CFG_DRV(GPIO48, AF1, DS04X) -#define GPIO52_CI_HSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X) -#define GPIO51_CI_VSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X) #define GPIO49_CI_MCLK MFP_CFG_DRV(GPIO49, AF0, DS04X) #define GPIO50_CI_PCLK MFP_CFG_DRV(GPIO50, AF0, DS04X) +#define GPIO51_CI_HSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X) +#define GPIO52_CI_VSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X) /* KEYPAD */ #define GPIO3_KP_DKIN_6 MFP_CFG_LPM(GPIO3, AF2, FLOAT) diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 77ad6d34ab5b..405b92a29793 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c @@ -469,9 +469,13 @@ static struct i2c_board_info __initdata palm27x_pi2c_board_info[] = { }, }; +static struct i2c_pxa_platform_data palm27x_i2c_power_info = { + .use_pio = 1, +}; + void __init palm27x_pmic_init(void) { i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); - pxa27x_set_i2c_power_info(NULL); + pxa27x_set_i2c_power_info(&palm27x_i2c_power_info); } #endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index c9b747cedea8..37d6173bbb66 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -240,6 +240,7 @@ static void __init vpac270_onenand_init(void) {} #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static struct pxamci_platform_data vpac270_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_power = -1, .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, .detect_delay_ms = 200, diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c index a492b982aa06..405e62128917 100644 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ b/arch/arm/mach-s3c64xx/dev-spi.c @@ -18,10 +18,11 @@ #include <mach/map.h> #include <mach/gpio-bank-c.h> #include <mach/spi-clocks.h> +#include <mach/irqs.h> #include <plat/s3c64xx-spi.h> #include <plat/gpio-cfg.h> -#include <plat/irqs.h> +#include <plat/devs.h> static char *spi_src_clks[] = { [S3C64XX_SPI_SRCCLK_PCLK] = "pclk", diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index 5c07d013b23d..e130379ba0e8 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c @@ -30,73 +30,73 @@ #include <plat/devs.h> #include <plat/regs-serial.h> -#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK -#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB -#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE +#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) +#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) +#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = { [0] = { - .hwport = 0, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, }, [1] = { - .hwport = 1, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, }, [2] = { - .hwport = 2, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, }, [3] = { - .hwport = 3, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, + .hwport = 3, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, }, }; /* DM9000AEP 10/100 ethernet controller */ static struct resource real6410_dm9k_resource[] = { - [0] = { - .start = S3C64XX_PA_XM0CSN1, - .end = S3C64XX_PA_XM0CSN1 + 1, - .flags = IORESOURCE_MEM - }, - [1] = { - .start = S3C64XX_PA_XM0CSN1 + 4, - .end = S3C64XX_PA_XM0CSN1 + 5, - .flags = IORESOURCE_MEM - }, - [2] = { - .start = S3C_EINT(7), - .end = S3C_EINT(7), - .flags = IORESOURCE_IRQ, - } + [0] = { + .start = S3C64XX_PA_XM0CSN1, + .end = S3C64XX_PA_XM0CSN1 + 1, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = S3C64XX_PA_XM0CSN1 + 4, + .end = S3C64XX_PA_XM0CSN1 + 5, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = S3C_EINT(7), + .end = S3C_EINT(7), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL + } }; static struct dm9000_plat_data real6410_dm9k_pdata = { - .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), + .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), }; static struct platform_device real6410_device_eth = { - .name = "dm9000", - .id = -1, - .num_resources = ARRAY_SIZE(real6410_dm9k_resource), - .resource = real6410_dm9k_resource, - .dev = { - .platform_data = &real6410_dm9k_pdata, - }, + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(real6410_dm9k_resource), + .resource = real6410_dm9k_resource, + .dev = { + .platform_data = &real6410_dm9k_pdata, + }, }; static struct platform_device *real6410_devices[] __initdata = { @@ -129,12 +129,12 @@ static void __init real6410_machine_init(void) /* set timing for nCS1 suitable for ethernet chip */ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) | - (6 << S3C64XX_SROM_BCX__TACP__SHIFT) | - (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) | - (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) | - (13 << S3C64XX_SROM_BCX__TACC__SHIFT) | - (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | - (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); + (6 << S3C64XX_SROM_BCX__TACP__SHIFT) | + (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) | + (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) | + (13 << S3C64XX_SROM_BCX__TACC__SHIFT) | + (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | + (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); } diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index af91fefef2c6..cfecd70657cb 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -281,6 +281,24 @@ static struct clk init_clocks_disable[] = { .enable = s5pv210_clk_ip0_ctrl, .ctrlbit = (1<<29), }, { + .name = "fimc", + .id = 0, + .parent = &clk_hclk_dsys.clk, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 24), + }, { + .name = "fimc", + .id = 1, + .parent = &clk_hclk_dsys.clk, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "fimc", + .id = 2, + .parent = &clk_hclk_dsys.clk, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 26), + }, { .name = "otg", .id = -1, .parent = &clk_hclk_psys.clk, @@ -357,7 +375,7 @@ static struct clk init_clocks_disable[] = { .id = 1, .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, - .ctrlbit = (1<<8), + .ctrlbit = (1 << 10), }, { .name = "i2c", .id = 2, diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index b9f4d677cf55..77f456c91ad3 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -47,7 +47,7 @@ static struct map_desc s5pv210_iodesc[] __initdata = { { .virtual = (unsigned long)S5P_VA_SYSTIMER, .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER), - .length = SZ_1M, + .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = (unsigned long)VA_VIC2, diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 5e16b4c69222..ae416fe7daf2 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -3,7 +3,7 @@ # # Common objects -obj-y := timer.o console.o clock.o +obj-y := timer.o console.o clock.o pm_runtime.o # CPU objects obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 23d472f9525e..95935c83c306 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -25,6 +25,7 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/mfd/sh_mobile_sdhi.h> +#include <linux/mfd/tmio.h> #include <linux/mmc/host.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> @@ -39,6 +40,7 @@ #include <linux/sh_clk.h> #include <linux/gpio.h> #include <linux/input.h> +#include <linux/leds.h> #include <linux/input/sh_keysc.h> #include <linux/usb/r8a66597.h> @@ -307,6 +309,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, .tmio_ocr_mask = MMC_VDD_165_195, + .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, }; static struct resource sdhi1_resources[] = { @@ -558,7 +561,7 @@ static struct resource fsi_resources[] = { static struct platform_device fsi_device = { .name = "sh_fsi2", - .id = 0, + .id = -1, .num_resources = ARRAY_SIZE(fsi_resources), .resource = fsi_resources, .dev = { @@ -650,7 +653,44 @@ static struct platform_device hdmi_device = { }, }; +static struct gpio_led ap4evb_leds[] = { + { + .name = "led4", + .gpio = GPIO_PORT185, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "led2", + .gpio = GPIO_PORT186, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "led3", + .gpio = GPIO_PORT187, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "led1", + .gpio = GPIO_PORT188, + .default_state = LEDS_GPIO_DEFSTATE_ON, + } +}; + +static struct gpio_led_platform_data ap4evb_leds_pdata = { + .num_leds = ARRAY_SIZE(ap4evb_leds), + .leds = ap4evb_leds, +}; + +static struct platform_device leds_device = { + .name = "leds-gpio", + .id = 0, + .dev = { + .platform_data = &ap4evb_leds_pdata, + }, +}; + static struct platform_device *ap4evb_devices[] __initdata = { + &leds_device, &nor_flash_device, &smc911x_device, &sdhi0_device, @@ -840,20 +880,6 @@ static void __init ap4evb_init(void) gpio_request(GPIO_FN_CS5A, NULL); gpio_request(GPIO_FN_IRQ6_39, NULL); - /* enable LED 1 - 4 */ - gpio_request(GPIO_PORT185, NULL); - gpio_request(GPIO_PORT186, NULL); - gpio_request(GPIO_PORT187, NULL); - gpio_request(GPIO_PORT188, NULL); - gpio_direction_output(GPIO_PORT185, 1); - gpio_direction_output(GPIO_PORT186, 1); - gpio_direction_output(GPIO_PORT187, 1); - gpio_direction_output(GPIO_PORT188, 1); - gpio_export(GPIO_PORT185, 0); - gpio_export(GPIO_PORT186, 0); - gpio_export(GPIO_PORT187, 0); - gpio_export(GPIO_PORT188, 0); - /* enable Debug switch (S6) */ gpio_request(GPIO_PORT32, NULL); gpio_request(GPIO_PORT33, NULL); diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index fb4e9b1d788e..759468992ad2 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -286,7 +286,6 @@ static struct clk_ops pllc2_clk_ops = { struct clk pllc2_clk = { .ops = &pllc2_clk_ops, - .flags = CLK_ENABLE_ON_INIT, .parent = &extal1_div2_clk, .freq_table = pllc2_freq_table, .parent_table = pllc2_parent, @@ -395,7 +394,7 @@ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { enum { MSTP001, MSTP131, MSTP130, - MSTP129, MSTP128, + MSTP129, MSTP128, MSTP127, MSTP126, MSTP118, MSTP117, MSTP116, MSTP106, MSTP101, MSTP100, MSTP223, @@ -413,6 +412,8 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ + [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */ + [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */ [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ @@ -428,7 +429,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ - [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */ + [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ @@ -498,6 +499,8 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ + CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */ + CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c index b7c705a213a2..6b7c7c42bc8f 100644 --- a/arch/arm/mach-shmobile/clock.c +++ b/arch/arm/mach-shmobile/clock.c @@ -1,8 +1,10 @@ /* - * SH-Mobile Timer + * SH-Mobile Clock Framework * * Copyright (C) 2010 Magnus Damm * + * Used together with arch/arm/common/clkdev.c and drivers/sh/clk.c. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c new file mode 100644 index 000000000000..94912d3944d3 --- /dev/null +++ b/arch/arm/mach-shmobile/pm_runtime.c @@ -0,0 +1,169 @@ +/* + * arch/arm/mach-shmobile/pm_runtime.c + * + * Runtime PM support code for SuperH Mobile ARM + * + * Copyright (C) 2009-2010 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/pm_runtime.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/sh_clk.h> +#include <linux/bitmap.h> + +#ifdef CONFIG_PM_RUNTIME +#define BIT_ONCE 0 +#define BIT_ACTIVE 1 +#define BIT_CLK_ENABLED 2 + +struct pm_runtime_data { + unsigned long flags; + struct clk *clk; +}; + +static void __devres_release(struct device *dev, void *res) +{ + struct pm_runtime_data *prd = res; + + dev_dbg(dev, "__devres_release()\n"); + + if (test_bit(BIT_CLK_ENABLED, &prd->flags)) + clk_disable(prd->clk); + + if (test_bit(BIT_ACTIVE, &prd->flags)) + clk_put(prd->clk); +} + +static struct pm_runtime_data *__to_prd(struct device *dev) +{ + return devres_find(dev, __devres_release, NULL, NULL); +} + +static void platform_pm_runtime_init(struct device *dev, + struct pm_runtime_data *prd) +{ + if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) { + prd->clk = clk_get(dev, NULL); + if (!IS_ERR(prd->clk)) { + set_bit(BIT_ACTIVE, &prd->flags); + dev_info(dev, "clocks managed by runtime pm\n"); + } + } +} + +static void platform_pm_runtime_bug(struct device *dev, + struct pm_runtime_data *prd) +{ + if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) + dev_err(dev, "runtime pm suspend before resume\n"); +} + +int platform_pm_runtime_suspend(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + + dev_dbg(dev, "platform_pm_runtime_suspend()\n"); + + platform_pm_runtime_bug(dev, prd); + + if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { + clk_disable(prd->clk); + clear_bit(BIT_CLK_ENABLED, &prd->flags); + } + + return 0; +} + +int platform_pm_runtime_resume(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + + dev_dbg(dev, "platform_pm_runtime_resume()\n"); + + platform_pm_runtime_init(dev, prd); + + if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { + clk_enable(prd->clk); + set_bit(BIT_CLK_ENABLED, &prd->flags); + } + + return 0; +} + +int platform_pm_runtime_idle(struct device *dev) +{ + /* suspend synchronously to disable clocks immediately */ + return pm_runtime_suspend(dev); +} + +static int platform_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct pm_runtime_data *prd; + + dev_dbg(dev, "platform_bus_notify() %ld !\n", action); + + if (action == BUS_NOTIFY_BIND_DRIVER) { + prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL); + if (prd) + devres_add(dev, prd); + else + dev_err(dev, "unable to alloc memory for runtime pm\n"); + } + + return 0; +} + +#else /* CONFIG_PM_RUNTIME */ + +static int platform_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct clk *clk; + + dev_dbg(dev, "platform_bus_notify() %ld !\n", action); + + switch (action) { + case BUS_NOTIFY_BIND_DRIVER: + clk = clk_get(dev, NULL); + if (!IS_ERR(clk)) { + clk_enable(clk); + clk_put(clk); + dev_info(dev, "runtime pm disabled, clock forced on\n"); + } + break; + case BUS_NOTIFY_UNBOUND_DRIVER: + clk = clk_get(dev, NULL); + if (!IS_ERR(clk)) { + clk_disable(clk); + clk_put(clk); + dev_info(dev, "runtime pm disabled, clock forced off\n"); + } + break; + } + + return 0; +} + +#endif /* CONFIG_PM_RUNTIME */ + +static struct notifier_block platform_bus_notifier = { + .notifier_call = platform_bus_notify +}; + +static int __init sh_pm_runtime_init(void) +{ + bus_register_notifier(&platform_bus_type, &platform_bus_notifier); + return 0; +} +core_initcall(sh_pm_runtime_init); diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h index 7b1fc984abb6..d5a71abcbaea 100644 --- a/arch/arm/mach-u300/include/mach/gpio.h +++ b/arch/arm/mach-u300/include/mach/gpio.h @@ -273,6 +273,9 @@ extern void gpio_pullup(unsigned gpio, int value); extern int gpio_get_value(unsigned gpio); extern void gpio_set_value(unsigned gpio, int value); +#define gpio_get_value_cansleep gpio_get_value +#define gpio_set_value_cansleep gpio_set_value + /* wrappers to sleep-enable the previous two functions */ static inline unsigned gpio_to_irq(unsigned gpio) { diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 577df6cccb08..efb127022d42 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -227,7 +227,13 @@ static void ct_ca9x4_init(void) int i; #ifdef CONFIG_CACHE_L2X0 - l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff); + void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); + + /* set RAM latencies to 1 cycle for this core tile. */ + writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); + writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL); + + l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); #endif clkdev_add_table(lookups, ARRAY_SIZE(lookups)); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 33c3f570aaa0..a0a2928ae4dd 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -398,7 +398,7 @@ config CPU_V6 # ARMv6k config CPU_32v6K bool "Support ARM V6K processor extensions" if !SMP - depends on CPU_V6 + depends on CPU_V6 || CPU_V7 default y if SMP && !(ARCH_MX3 || ARCH_OMAP2) help Say Y here if your ARMv6 processor supports the 'K' extension. diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index d073b64ae87e..724ba3bce72c 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -885,8 +885,23 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (ai_usermode & UM_SIGNAL) force_sig(SIGBUS, current); - else - set_cr(cr_no_alignment); + else { + /* + * We're about to disable the alignment trap and return to + * user space. But if an interrupt occurs before actually + * reaching user space, then the IRQ vector entry code will + * notice that we were still in kernel space and therefore + * the alignment trap won't be re-enabled in that case as it + * is presumed to be always on from kernel space. + * Let's prevent that race by disabling interrupts here (they + * are disabled on the way back to user space anyway in + * entry-common.S) and disable the alignment trap only if + * there is no work pending for this thread. + */ + raw_local_irq_disable(); + if (!(current_thread_info()->flags & _TIF_WORK_MASK)) + set_cr(cr_no_alignment); + } return 0; } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c704eed63c5d..4bc43e535d3b 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -229,6 +229,8 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) } } while (size -= PAGE_SIZE); + dsb(); + return (void *)c->vm_start; } return NULL; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6e1c4f6a2b3f..6a3a2d0cd6db 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -15,6 +15,7 @@ #include <linux/nodemask.h> #include <linux/memblock.h> #include <linux/sort.h> +#include <linux/fs.h> #include <asm/cputype.h> #include <asm/sections.h> @@ -246,6 +247,9 @@ static struct mem_type mem_types[] = { .domain = DOMAIN_USER, }, [MT_MEMORY] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, }, @@ -254,6 +258,9 @@ static struct mem_type mem_types[] = { .domain = DOMAIN_KERNEL, }, [MT_MEMORY_NONCACHED] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, + .prot_l1 = PMD_TYPE_TABLE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, }, @@ -411,9 +418,12 @@ static void __init build_mem_type_table(void) * Enable CPU-specific coherency if supported. * (Only available on XSC3 at the moment.) */ - if (arch_is_coherent() && cpu_is_xsc3()) + if (arch_is_coherent() && cpu_is_xsc3()) { mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; - + mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; + mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; + } /* * ARMv6 and above have extended page tables. */ @@ -438,7 +448,9 @@ static void __init build_mem_type_table(void) mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; #endif } @@ -475,6 +487,8 @@ static void __init build_mem_type_table(void) mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; + mem_types[MT_MEMORY].prot_pte |= kern_pgprot; + mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask; mem_types[MT_ROM].prot_sect |= cp->pmd; switch (cp->pmd) { @@ -498,6 +512,19 @@ static void __init build_mem_type_table(void) } } +#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot) +{ + if (!pfn_valid(pfn)) + return pgprot_noncached(vma_prot); + else if (file->f_flags & O_SYNC) + return pgprot_writecombine(vma_prot); + return vma_prot; +} +EXPORT_SYMBOL(phys_mem_access_prot); +#endif + #define vectors_base() (vectors_high() ? 0xffff0000 : 0) static void __init *early_alloc(unsigned long sz) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 6a8506d99ee9..7563ff0141bd 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -186,13 +186,14 @@ cpu_v7_name: * It is assumed that: * - cache type register is implemented */ -__v7_setup: +__v7_ca9mp_setup: #ifdef CONFIG_SMP mrc p15, 0, r0, c1, c0, 1 tst r0, #(1 << 6) @ SMP/nAMP mode enabled? orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting #endif +__v7_setup: adr r12, __v7_setup_stack @ the local stack stmia r12, {r0-r5, r7, r9, r11, lr} bl v7_flush_dcache_all @@ -201,11 +202,16 @@ __v7_setup: mrc p15, 0, r0, c0, c0, 0 @ read main ID register and r10, r0, #0xff000000 @ ARM? teq r10, #0x41000000 - bne 2f + bne 3f and r5, r0, #0x00f00000 @ variant and r6, r0, #0x0000000f @ revision - orr r0, r6, r5, lsr #20-4 @ combine variant and revision + orr r6, r6, r5, lsr #20-4 @ combine variant and revision + ubfx r0, r0, #4, #12 @ primary part number + /* Cortex-A8 Errata */ + ldr r10, =0x00000c08 @ Cortex-A8 primary part number + teq r0, r10 + bne 2f #ifdef CONFIG_ARM_ERRATA_430973 teq r5, #0x00100000 @ only present in r1p* mrceq p15, 0, r10, c1, c0, 1 @ read aux control register @@ -213,21 +219,42 @@ __v7_setup: mcreq p15, 0, r10, c1, c0, 1 @ write aux control register #endif #ifdef CONFIG_ARM_ERRATA_458693 - teq r0, #0x20 @ only present in r2p0 + teq r6, #0x20 @ only present in r2p0 mrceq p15, 0, r10, c1, c0, 1 @ read aux control register orreq r10, r10, #(1 << 5) @ set L1NEON to 1 orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 mcreq p15, 0, r10, c1, c0, 1 @ write aux control register #endif #ifdef CONFIG_ARM_ERRATA_460075 - teq r0, #0x20 @ only present in r2p0 + teq r6, #0x20 @ only present in r2p0 mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register tsteq r10, #1 << 22 orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register #endif + b 3f + + /* Cortex-A9 Errata */ +2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number + teq r0, r10 + bne 3f +#ifdef CONFIG_ARM_ERRATA_742230 + cmp r6, #0x22 @ only present up to r2p2 + mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register + orrle r10, r10, #1 << 4 @ set bit #4 + mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register +#endif +#ifdef CONFIG_ARM_ERRATA_742231 + teq r6, #0x20 @ present in r2p0 + teqne r6, #0x21 @ present in r2p1 + teqne r6, #0x22 @ present in r2p2 + mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register + orreq r10, r10, #1 << 12 @ set bit #12 + orreq r10, r10, #1 << 22 @ set bit #22 + mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register +#endif -2: mov r10, #0 +3: mov r10, #0 #ifdef HARVARD_CACHE mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate #endif @@ -323,6 +350,29 @@ cpu_elf_name: .section ".proc.info.init", #alloc, #execinstr + .type __v7_ca9mp_proc_info, #object +__v7_ca9mp_proc_info: + .long 0x410fc090 @ Required ID value + .long 0xff0ffff0 @ Mask for ID + .long PMD_TYPE_SECT | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ | \ + PMD_FLAGS + .long PMD_TYPE_SECT | \ + PMD_SECT_XN | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __v7_ca9mp_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_v7_name + .long v7_processor_functions + .long v7wbi_tlb_fns + .long v6_user_fns + .long v7_cache_fns + .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info + /* * Match any ARMv7 processor core. */ diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 0527e65318f4..6785db4179b8 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -43,6 +43,7 @@ config ARCH_MXC91231 config ARCH_MX5 bool "MX5-based" select CPU_V7 + select ARM_L1_CACHE_SHIFT_6 help This enables support for systems based on the Freescale i.MX51 family diff --git a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h index 634e3f4c454d..656acb45d434 100644 --- a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h +++ b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h @@ -37,9 +37,9 @@ * mach-mx5/eukrea_mbimx51-baseboard.c for cpuimx51 */ -extern void eukrea_mbimx25_baseboard_init(void); +extern void eukrea_mbimxsd25_baseboard_init(void); extern void eukrea_mbimx27_baseboard_init(void); -extern void eukrea_mbimx35_baseboard_init(void); +extern void eukrea_mbimxsd35_baseboard_init(void); extern void eukrea_mbimx51_baseboard_init(void); #endif diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index b3da9aad4295..3703ab28257f 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c @@ -164,8 +164,9 @@ int tzic_enable_wake(int is_idle) return -EAGAIN; for (i = 0; i < 4; i++) { - v = is_idle ? __raw_readl(TZIC_ENSET0(i)) : wakeup_intr[i]; - __raw_writel(v, TZIC_WAKEUP0(i)); + v = is_idle ? __raw_readl(tzic_base + TZIC_ENSET0(i)) : + wakeup_intr[i]; + __raw_writel(v, tzic_base + TZIC_WAKEUP0(i)); } return 0; diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index ea3ca86c5283..aedf9c1d645e 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-nomadik/timer.c + * linux/arch/arm/plat-nomadik/timer.c * * Copyright (C) 2008 STMicroelectronics * Copyright (C) 2010 Alessandro Rubini @@ -75,7 +75,7 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode, cr = readl(mtu_base + MTU_CR(1)); writel(0, mtu_base + MTU_LR(1)); writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); - writel(0x2, mtu_base + MTU_IMSC); + writel(1 << 1, mtu_base + MTU_IMSC); break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: @@ -131,25 +131,23 @@ void __init nmdk_timer_init(void) { unsigned long rate; struct clk *clk0; - struct clk *clk1; - u32 cr; + u32 cr = MTU_CRn_32BITS; clk0 = clk_get_sys("mtu0", NULL); BUG_ON(IS_ERR(clk0)); - clk1 = clk_get_sys("mtu1", NULL); - BUG_ON(IS_ERR(clk1)); - clk_enable(clk0); - clk_enable(clk1); /* - * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: - * use a divide-by-16 counter if it's more than 16MHz + * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz + * for ux500. + * Use a divide-by-16 counter if the tick rate is more than 32MHz. + * At 32 MHz, the timer (with 32 bit counter) can be programmed + * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer + * with 16 gives too low timer resolution. */ - cr = MTU_CRn_32BITS;; rate = clk_get_rate(clk0); - if (rate > 16 << 20) { + if (rate > 32000000) { rate /= 16; cr |= MTU_CRn_PRESCALE_16; } else { @@ -170,15 +168,8 @@ void __init nmdk_timer_init(void) pr_err("timer: failed to initialize clock source %s\n", nmdk_clksrc.name); - /* Timer 1 is used for events, fix according to rate */ - cr = MTU_CRn_32BITS; - rate = clk_get_rate(clk1); - if (rate > 16 << 20) { - rate /= 16; - cr |= MTU_CRn_PRESCALE_16; - } else { - cr |= MTU_CRn_PRESCALE_1; - } + /* Timer 1 is used for events */ + clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index e39a417a368d..a92cb499313f 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -33,7 +33,7 @@ config OMAP_DEBUG_DEVICES config OMAP_DEBUG_LEDS bool depends on OMAP_DEBUG_DEVICES - default y if LEDS + default y if LEDS_CLASS config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e31496e35b0f..0c8612fd8312 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -156,7 +156,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) /* Writing zero to RSYNC_ERR clears the IRQ */ MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); } else { - complete(&mcbsp_rx->tx_irq_completion); + complete(&mcbsp_rx->rx_irq_completion); } return IRQ_HANDLED; diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 226b2e858d6c..10b3b4c63372 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -220,20 +220,7 @@ void __init omap_map_sram(void) if (omap_sram_size == 0) return; - if (cpu_is_omap24xx()) { - omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; - - base = OMAP2_SRAM_PA; - base = ROUND_DOWN(base, PAGE_SIZE); - omap_sram_io_desc[0].pfn = __phys_to_pfn(base); - } - if (cpu_is_omap34xx()) { - omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA; - base = OMAP3_SRAM_PA; - base = ROUND_DOWN(base, PAGE_SIZE); - omap_sram_io_desc[0].pfn = __phys_to_pfn(base); - /* * SRAM must be marked as non-cached on OMAP3 since the * CORE DPLL M2 divider change code (in SRAM) runs with the @@ -244,13 +231,11 @@ void __init omap_map_sram(void) omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; } - if (cpu_is_omap44xx()) { - omap_sram_io_desc[0].virtual = OMAP4_SRAM_VA; - base = OMAP4_SRAM_PA; - base = ROUND_DOWN(base, PAGE_SIZE); - omap_sram_io_desc[0].pfn = __phys_to_pfn(base); - } - omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */ + omap_sram_io_desc[0].virtual = omap_sram_base; + base = omap_sram_start; + base = ROUND_DOWN(base, PAGE_SIZE); + omap_sram_io_desc[0].pfn = __phys_to_pfn(base); + omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE); iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c index 0732c6c8d511..ef32686feef9 100644 --- a/arch/arm/plat-pxa/pwm.c +++ b/arch/arm/plat-pxa/pwm.c @@ -176,7 +176,7 @@ static inline void __add_pwm(struct pwm_device *pwm) static int __devinit pwm_probe(struct platform_device *pdev) { - struct platform_device_id *id = platform_get_device_id(pdev); + const struct platform_device_id *id = platform_get_device_id(pdev); struct pwm_device *pwm, *secondary = NULL; struct resource *r; int ret = 0; diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c index d3f1a9b5d2b5..608770fc1531 100644 --- a/arch/arm/plat-s5p/dev-fimc0.c +++ b/arch/arm/plat-s5p/dev-fimc0.c @@ -10,6 +10,7 @@ */ #include <linux/kernel.h> +#include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/ioport.h> @@ -18,7 +19,7 @@ static struct resource s5p_fimc0_resource[] = { [0] = { .start = S5P_PA_FIMC0, - .end = S5P_PA_FIMC0 + SZ_1M - 1, + .end = S5P_PA_FIMC0 + SZ_4K - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -28,9 +29,15 @@ static struct resource s5p_fimc0_resource[] = { }, }; +static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32); + struct platform_device s5p_device_fimc0 = { .name = "s5p-fimc", .id = 0, .num_resources = ARRAY_SIZE(s5p_fimc0_resource), .resource = s5p_fimc0_resource, + .dev = { + .dma_mask = &s5p_fimc0_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, }; diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c index 41bd6986d0ad..76e3a97a87d3 100644 --- a/arch/arm/plat-s5p/dev-fimc1.c +++ b/arch/arm/plat-s5p/dev-fimc1.c @@ -10,6 +10,7 @@ */ #include <linux/kernel.h> +#include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/ioport.h> @@ -18,7 +19,7 @@ static struct resource s5p_fimc1_resource[] = { [0] = { .start = S5P_PA_FIMC1, - .end = S5P_PA_FIMC1 + SZ_1M - 1, + .end = S5P_PA_FIMC1 + SZ_4K - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -28,9 +29,15 @@ static struct resource s5p_fimc1_resource[] = { }, }; +static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32); + struct platform_device s5p_device_fimc1 = { .name = "s5p-fimc", .id = 1, .num_resources = ARRAY_SIZE(s5p_fimc1_resource), .resource = s5p_fimc1_resource, + .dev = { + .dma_mask = &s5p_fimc1_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, }; diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c index dfddeda6d4a3..24d29816fa2c 100644 --- a/arch/arm/plat-s5p/dev-fimc2.c +++ b/arch/arm/plat-s5p/dev-fimc2.c @@ -10,6 +10,7 @@ */ #include <linux/kernel.h> +#include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/ioport.h> @@ -18,7 +19,7 @@ static struct resource s5p_fimc2_resource[] = { [0] = { .start = S5P_PA_FIMC2, - .end = S5P_PA_FIMC2 + SZ_1M - 1, + .end = S5P_PA_FIMC2 + SZ_4K - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -28,9 +29,15 @@ static struct resource s5p_fimc2_resource[] = { }, }; +static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32); + struct platform_device s5p_device_fimc2 = { .name = "s5p-fimc", .id = 2, .num_resources = ARRAY_SIZE(s5p_fimc2_resource), .resource = s5p_fimc2_resource, + .dev = { + .dma_mask = &s5p_fimc2_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, }; diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 57b68a50f45e..e3d41eaed1ff 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -273,13 +273,13 @@ s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) if (!chip) return -EINVAL; - off = chip->chip.base - pin; + off = pin - chip->chip.base; shift = off * 2; reg = chip->base + 0x0C; drvstr = __raw_readl(reg); - drvstr = 0xffff & (0x3 << shift); drvstr = drvstr >> shift; + drvstr &= 0x3; return (__force s5p_gpio_drvstr_t)drvstr; } @@ -296,11 +296,12 @@ int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) if (!chip) return -EINVAL; - off = chip->chip.base - pin; + off = pin - chip->chip.base; shift = off * 2; reg = chip->base + 0x0C; tmp = __raw_readl(reg); + tmp &= ~(0x3 << shift); tmp |= drvstr << shift; __raw_writel(tmp, reg); diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index db4112c6f2be..1c6b92947c5d 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -143,12 +143,12 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); /* Define values for the drvstr available for each gpio pin. * * These values control the value of the output signal driver strength, - * configurable on most pins on the S5C series. + * configurable on most pins on the S5P series. */ -#define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x00) -#define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x01) -#define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x10) -#define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x11) +#define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x0) +#define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x2) +#define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x1) +#define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x3) /** * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 48cbdcb6bbd4..55590a4d87c9 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon Jul 12 21:10:14 2010 +# Last update: Thu Sep 9 22:43:01 2010 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -2622,7 +2622,7 @@ kraken MACH_KRAKEN KRAKEN 2634 gw2388 MACH_GW2388 GW2388 2635 jadecpu MACH_JADECPU JADECPU 2636 carlisle MACH_CARLISLE CARLISLE 2637 -lux_sf9 MACH_LUX_SFT9 LUX_SFT9 2638 +lux_sf9 MACH_LUX_SF9 LUX_SF9 2638 nemid_tb MACH_NEMID_TB NEMID_TB 2639 terrier MACH_TERRIER TERRIER 2640 turbot MACH_TURBOT TURBOT 2641 @@ -2950,3 +2950,97 @@ davinci_dm365_dvr MACH_DAVINCI_DM365_DVR DAVINCI_DM365_DVR 2963 netviz MACH_NETVIZ NETVIZ 2964 flexibity MACH_FLEXIBITY FLEXIBITY 2965 wlan_computer MACH_WLAN_COMPUTER WLAN_COMPUTER 2966 +lpc24xx MACH_LPC24XX LPC24XX 2967 +spica MACH_SPICA SPICA 2968 +gpsdisplay MACH_GPSDISPLAY GPSDISPLAY 2969 +bipnet MACH_BIPNET BIPNET 2970 +overo_ctu_inertial MACH_OVERO_CTU_INERTIAL OVERO_CTU_INERTIAL 2971 +davinci_dm355_mmm MACH_DAVINCI_DM355_MMM DAVINCI_DM355_MMM 2972 +pc9260_v2 MACH_PC9260_V2 PC9260_V2 2973 +ptx7545 MACH_PTX7545 PTX7545 2974 +tm_efdc MACH_TM_EFDC TM_EFDC 2975 +omap3_waldo1 MACH_OMAP3_WALDO1 OMAP3_WALDO1 2977 +flyer MACH_FLYER FLYER 2978 +tornado3240 MACH_TORNADO3240 TORNADO3240 2979 +soli_01 MACH_SOLI_01 SOLI_01 2980 +omapl138_europalc MACH_OMAPL138_EUROPALC OMAPL138_EUROPALC 2981 +helios_v1 MACH_HELIOS_V1 HELIOS_V1 2982 +netspace_lite_v2 MACH_NETSPACE_LITE_V2 NETSPACE_LITE_V2 2983 +ssc MACH_SSC SSC 2984 +premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985 +wasabi MACH_WASABI WASABI 2986 +vivow MACH_VIVOW VIVOW 2987 +mx50_rdp MACH_MX50_RDP MX50_RDP 2988 +universal MACH_UNIVERSAL UNIVERSAL 2989 +real6410 MACH_REAL6410 REAL6410 2990 +spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 +ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 +omap3_bc10 MACH_OMAP3_BC10 OMAP3_BC10 2993 +thebe MACH_THEBE THEBE 2994 +rv082 MACH_RV082 RV082 2995 +armlguest MACH_ARMLGUEST ARMLGUEST 2996 +tjinc1000 MACH_TJINC1000 TJINC1000 2997 +dockstar MACH_DOCKSTAR DOCKSTAR 2998 +ax8008 MACH_AX8008 AX8008 2999 +gnet_sgce MACH_GNET_SGCE GNET_SGCE 3000 +pxwnas_500_1000 MACH_PXWNAS_500_1000 PXWNAS_500_1000 3001 +ea20 MACH_EA20 EA20 3002 +awm2 MACH_AWM2 AWM2 3003 +ti8148evm MACH_TI8148EVM TI8148EVM 3004 +tegra_seaboard MACH_TEGRA_SEABOARD TEGRA_SEABOARD 3005 +linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006 +tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007 +rubys MACH_RUBYS RUBYS 3008 +aquarius MACH_AQUARIUS AQUARIUS 3009 +mx53_ard MACH_MX53_ARD MX53_ARD 3010 +mx53_smd MACH_MX53_SMD MX53_SMD 3011 +lswxl MACH_LSWXL LSWXL 3012 +dove_avng_v3 MACH_DOVE_AVNG_V3 DOVE_AVNG_V3 3013 +sdi_ess_9263 MACH_SDI_ESS_9263 SDI_ESS_9263 3014 +jocpu550 MACH_JOCPU550 JOCPU550 3015 +msm8x60_rumi3 MACH_MSM8X60_RUMI3 MSM8X60_RUMI3 3016 +msm8x60_ffa MACH_MSM8X60_FFA MSM8X60_FFA 3017 +yanomami MACH_YANOMAMI YANOMAMI 3018 +gta04 MACH_GTA04 GTA04 3019 +cm_a510 MACH_CM_A510 CM_A510 3020 +omap3_rfs200 MACH_OMAP3_RFS200 OMAP3_RFS200 3021 +kx33xx MACH_KX33XX KX33XX 3022 +ptx7510 MACH_PTX7510 PTX7510 3023 +top9000 MACH_TOP9000 TOP9000 3024 +teenote MACH_TEENOTE TEENOTE 3025 +ts3 MACH_TS3 TS3 3026 +a0 MACH_A0 A0 3027 +fsm9xxx_surf MACH_FSM9XXX_SURF FSM9XXX_SURF 3028 +fsm9xxx_ffa MACH_FSM9XXX_FFA FSM9XXX_FFA 3029 +frrhwcdma60w MACH_FRRHWCDMA60W FRRHWCDMA60W 3030 +remus MACH_REMUS REMUS 3031 +at91cap7xdk MACH_AT91CAP7XDK AT91CAP7XDK 3032 +at91cap7stk MACH_AT91CAP7STK AT91CAP7STK 3033 +kt_sbc_sam9_1 MACH_KT_SBC_SAM9_1 KT_SBC_SAM9_1 3034 +oratisrouter MACH_ORATISROUTER ORATISROUTER 3035 +armada_xp_db MACH_ARMADA_XP_DB ARMADA_XP_DB 3036 +spdm MACH_SPDM SPDM 3037 +gtib MACH_GTIB GTIB 3038 +dgm3240 MACH_DGM3240 DGM3240 3039 +atlas_i_lpe MACH_ATLAS_I_LPE ATLAS_I_LPE 3040 +htcmega MACH_HTCMEGA HTCMEGA 3041 +tricorder MACH_TRICORDER TRICORDER 3042 +tx28 MACH_TX28 TX28 3043 +bstbrd MACH_BSTBRD BSTBRD 3044 +pwb3090 MACH_PWB3090 PWB3090 3045 +idea6410 MACH_IDEA6410 IDEA6410 3046 +qbc9263 MACH_QBC9263 QBC9263 3047 +borabora MACH_BORABORA BORABORA 3048 +valdez MACH_VALDEZ VALDEZ 3049 +ls9g20 MACH_LS9G20 LS9G20 3050 +mios_v1 MACH_MIOS_V1 MIOS_V1 3051 +s5pc110_crespo MACH_S5PC110_CRESPO S5PC110_CRESPO 3052 +controltek9g20 MACH_CONTROLTEK9G20 CONTROLTEK9G20 3053 +tin307 MACH_TIN307 TIN307 3054 +tin510 MACH_TIN510 TIN510 3055 +bluecheese MACH_BLUECHEESE BLUECHEESE 3057 +tem3x30 MACH_TEM3X30 TEM3X30 3058 +harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059 +msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 +spear900 MACH_SPEAR900 SPEAR900 3061 +pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 0974c0ecc594..bab01298b58e 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c @@ -121,6 +121,9 @@ static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8) struct user_context *user = current->thread.user; unsigned long tbr, psr; + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + tbr = user->i.tbr; psr = user->i.psr; if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context))) @@ -250,6 +253,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) struct sigframe __user *frame; int rsig; + set_fs(USER_DS); + frame = get_sigframe(ka, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) @@ -293,22 +298,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) (unsigned long) (frame->retcode + 2)); } - /* set up registers for signal handler */ - __frame->sp = (unsigned long) frame; - __frame->lr = (unsigned long) &frame->retcode; - __frame->gr8 = sig; - + /* Set up registers for the signal handler */ if (current->personality & FDPIC_FUNCPTRS) { struct fdpic_func_descriptor __user *funcptr = (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; - __get_user(__frame->pc, &funcptr->text); - __get_user(__frame->gr15, &funcptr->GOT); + struct fdpic_func_descriptor desc; + if (copy_from_user(&desc, funcptr, sizeof(desc))) + goto give_sigsegv; + __frame->pc = desc.text; + __frame->gr15 = desc.GOT; } else { __frame->pc = (unsigned long) ka->sa.sa_handler; __frame->gr15 = 0; } - set_fs(USER_DS); + __frame->sp = (unsigned long) frame; + __frame->lr = (unsigned long) &frame->retcode; + __frame->gr8 = sig; /* the tracer may want to single-step inside the handler */ if (test_thread_flag(TIF_SINGLESTEP)) @@ -323,7 +329,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) return 0; give_sigsegv: - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); return -EFAULT; } /* end setup_frame() */ @@ -338,6 +344,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, struct rt_sigframe __user *frame; int rsig; + set_fs(USER_DS); + frame = get_sigframe(ka, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) @@ -392,22 +400,23 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, } /* Set up registers for signal handler */ - __frame->sp = (unsigned long) frame; - __frame->lr = (unsigned long) &frame->retcode; - __frame->gr8 = sig; - __frame->gr9 = (unsigned long) &frame->info; - if (current->personality & FDPIC_FUNCPTRS) { struct fdpic_func_descriptor __user *funcptr = (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; - __get_user(__frame->pc, &funcptr->text); - __get_user(__frame->gr15, &funcptr->GOT); + struct fdpic_func_descriptor desc; + if (copy_from_user(&desc, funcptr, sizeof(desc))) + goto give_sigsegv; + __frame->pc = desc.text; + __frame->gr15 = desc.GOT; } else { __frame->pc = (unsigned long) ka->sa.sa_handler; __frame->gr15 = 0; } - set_fs(USER_DS); + __frame->sp = (unsigned long) frame; + __frame->lr = (unsigned long) &frame->retcode; + __frame->gr8 = sig; + __frame->gr9 = (unsigned long) &frame->info; /* the tracer may want to single-step inside the handler */ if (test_thread_flag(TIF_SINGLESTEP)) @@ -422,7 +431,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return 0; give_sigsegv: - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); return -EFAULT; } /* end setup_rt_frame() */ @@ -437,7 +446,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info, int ret; /* Are we from a system call? */ - if (in_syscall(__frame)) { + if (__frame->syscallno != -1) { /* If so, check system call restarting.. */ switch (__frame->gr8) { case -ERESTART_RESTARTBLOCK: @@ -456,6 +465,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info, __frame->gr8 = __frame->orig_gr8; __frame->pc -= 4; } + __frame->syscallno = -1; } /* Set up the stack frame */ @@ -538,10 +548,11 @@ no_signal: break; case -ERESTART_RESTARTBLOCK: - __frame->gr8 = __NR_restart_syscall; + __frame->gr7 = __NR_restart_syscall; __frame->pc -= 4; break; } + __frame->syscallno = -1; } /* if there's no signal to deliver, we just put the saved sigmask diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h index f90edc85b509..9301a2821615 100644 --- a/arch/ia64/include/asm/compat.h +++ b/arch/ia64/include/asm/compat.h @@ -199,7 +199,7 @@ ptr_to_compat(void __user *uptr) } static __inline__ void __user * -compat_alloc_user_space (long len) +arch_compat_alloc_user_space (long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len); diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 3567d54f8cee..331d42bda77a 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -420,22 +420,31 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set ;; RSM_PSR_I(p0, r18, r19) // mask interrupt delivery - mov ar.ccv=0 andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP + mov r8=EINVAL // default to EINVAL #ifdef CONFIG_SMP - mov r17=1 + // __ticket_spin_trylock(r31) + ld4 r17=[r31] ;; - cmpxchg4.acq r18=[r31],r17,ar.ccv // try to acquire the lock - mov r8=EINVAL // default to EINVAL + mov.m ar.ccv=r17 + extr.u r9=r17,17,15 + adds r19=1,r17 + extr.u r18=r17,0,15 + ;; + cmp.eq p6,p7=r9,r18 ;; +(p6) cmpxchg4.acq r9=[r31],r19,ar.ccv +(p6) dep.z r20=r19,1,15 // next serving ticket for unlock +(p7) br.cond.spnt.many .lock_contention + ;; + cmp4.eq p0,p7=r9,r17 + adds r31=2,r31 +(p7) br.cond.spnt.many .lock_contention ld8 r3=[r2] // re-read current->blocked now that we hold the lock - cmp4.ne p6,p0=r18,r0 -(p6) br.cond.spnt.many .lock_contention ;; #else ld8 r3=[r2] // re-read current->blocked now that we hold the lock - mov r8=EINVAL // default to EINVAL #endif add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16 add r19=IA64_TASK_SIGNAL_OFFSET,r16 @@ -490,7 +499,9 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set (p6) br.cond.spnt.few 1b // yes -> retry #ifdef CONFIG_SMP - st4.rel [r31]=r0 // release the lock + // __ticket_spin_unlock(r31) + st2.rel [r31]=r20 + mov r20=0 // i must not leak kernel bits... #endif SSM_PSR_I(p0, p9, r31) ;; @@ -512,7 +523,8 @@ EX(.fail_efault, (p15) st8 [r34]=r3) .sig_pending: #ifdef CONFIG_SMP - st4.rel [r31]=r0 // release the lock + // __ticket_spin_unlock(r31) + st2.rel [r31]=r20 // release the lock #endif SSM_PSR_I(p0, p9, r17) ;; diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h index 9c1acb2b1a92..b2eeb0de1c8d 100644 --- a/arch/m32r/include/asm/signal.h +++ b/arch/m32r/include/asm/signal.h @@ -157,7 +157,6 @@ typedef struct sigaltstack { #undef __HAVE_ARCH_SIG_BITOPS struct pt_regs; -extern int do_signal(struct pt_regs *regs, sigset_t *oldset); #define ptrace_signal_deliver(regs, cookie) do { } while (0) diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index 76125777483c..c70545689da8 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h @@ -351,6 +351,7 @@ #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __IGNORE_lchown #define __IGNORE_setuid diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 403869833b98..225412bc227e 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S @@ -235,10 +235,9 @@ work_resched: work_notifysig: ; deal with pending signals and ; notify-resume requests mv r0, sp ; arg1 : struct pt_regs *regs - ldi r1, #0 ; arg2 : sigset_t *oldset - mv r2, r9 ; arg3 : __u32 thread_info_flags + mv r1, r9 ; arg2 : __u32 thread_info_flags bl do_notify_resume - bra restore_all + bra resume_userspace ; perform syscall exit tracing ALIGN diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index e555091eb97c..0021ade4cba8 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c @@ -592,16 +592,17 @@ void user_enable_single_step(struct task_struct *child) if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) != sizeof(insn)) - break; + return -EIO; compute_next_pc(insn, pc, &next_pc, child); if (next_pc & 0x80000000) - break; + return -EIO; if (embed_debug_trap(child, next_pc)) - break; + return -EIO; invalidate_cache(); + return 0; } void user_disable_single_step(struct task_struct *child) diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 144b0f124fc7..7bbe38645ed5 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c @@ -28,37 +28,6 @@ #define DEBUG_SIG 0 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -int do_signal(struct pt_regs *, sigset_t *); - -asmlinkage int -sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, - unsigned long r2, unsigned long r3, unsigned long r4, - unsigned long r5, unsigned long r6, struct pt_regs *regs) -{ - sigset_t newset; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - - if (copy_from_user(&newset, unewset, sizeof(newset))) - return -EFAULT; - sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); - - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - current->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; -} - asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r2, unsigned long r3, unsigned long r4, @@ -218,7 +187,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) return (void __user *)((sp - frame_size) & -8ul); } -static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, +static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; @@ -275,22 +244,34 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, current->comm, current->pid, frame, regs->pc); #endif - return; + return 0; give_sigsegv: force_sigsegv(sig, current); + return -EFAULT; +} + +static int prev_insn(struct pt_regs *regs) +{ + u16 inst; + if (get_user(&inst, (u16 __user *)(regs->bpc - 2))) + return -EFAULT; + if ((inst & 0xfff0) == 0x10f0) /* trap ? */ + regs->bpc -= 2; + else + regs->bpc -= 4; + regs->syscall_nr = -1; + return 0; } /* * OK, we're invoking a handler */ -static void +static int handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { - unsigned short inst; - /* Are we from a system call? */ if (regs->syscall_nr >= 0) { /* If so, check system call restarting.. */ @@ -308,16 +289,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, /* fallthrough */ case -ERESTARTNOINTR: regs->r0 = regs->orig_r0; - inst = *(unsigned short *)(regs->bpc - 2); - if ((inst & 0xfff0) == 0x10f0) /* trap ? */ - regs->bpc -= 2; - else - regs->bpc -= 4; + if (prev_insn(regs) < 0) + return -EFAULT; } } /* Set up the stack frame */ - setup_rt_frame(sig, ka, info, oldset, regs); + if (setup_rt_frame(sig, ka, info, oldset, regs)) + return -EFAULT; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); @@ -325,6 +304,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + return 0; } /* @@ -332,12 +312,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -int do_signal(struct pt_regs *regs, sigset_t *oldset) +static void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; - unsigned short inst; + sigset_t *oldset; /* * We want the common case to go fast, which @@ -346,12 +326,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) * if so. */ if (!user_mode(regs)) - return 1; + return; if (try_to_freeze()) goto no_signal; - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); @@ -363,8 +345,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) */ /* Whee! Actually deliver the signal. */ - handle_signal(signr, &ka, &info, oldset, regs); - return 1; + if (handle_signal(signr, &ka, &info, oldset, regs) == 0) + clear_thread_flag(TIF_RESTORE_SIGMASK); + + return; } no_signal: @@ -375,31 +359,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) { regs->r0 = regs->orig_r0; - inst = *(unsigned short *)(regs->bpc - 2); - if ((inst & 0xfff0) == 0x10f0) /* trap ? */ - regs->bpc -= 2; - else - regs->bpc -= 4; - } - if (regs->r0 == -ERESTART_RESTARTBLOCK){ + prev_insn(regs); + } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ regs->r0 = regs->orig_r0; regs->r7 = __NR_restart_syscall; - inst = *(unsigned short *)(regs->bpc - 2); - if ((inst & 0xfff0) == 0x10f0) /* trap ? */ - regs->bpc -= 2; - else - regs->bpc -= 4; + prev_insn(regs); } } - return 0; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } } /* * notification of userspace execution resumption * - triggered by current->work.notify_resume */ -void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, - __u32 thread_info_flags) +void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags) { /* Pending single-step? */ if (thread_info_flags & _TIF_SINGLESTEP) @@ -407,7 +384,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) - do_signal(regs,oldset); + do_signal(regs); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 60b15d0aa072..b43b36beafe3 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -340,10 +340,13 @@ #define __NR_set_thread_area 334 #define __NR_atomic_cmpxchg_32 335 #define __NR_atomic_barrier 336 +#define __NR_fanotify_init 337 +#define __NR_fanotify_mark 338 +#define __NR_prlimit64 339 #ifdef __KERNEL__ -#define NR_syscalls 337 +#define NR_syscalls 340 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 2391bdff0996..6360c437dcf5 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -765,4 +765,7 @@ sys_call_table: .long sys_set_thread_area .long sys_atomic_cmpxchg_32 /* 335 */ .long sys_atomic_barrier + .long sys_fanotify_init + .long sys_fanotify_mark + .long sys_prlimit64 diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index 8f0640847ad2..05285d08e547 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c @@ -162,7 +162,7 @@ static void mac_init_asc( void ) void mac_mksound( unsigned int freq, unsigned int length ) { __u32 cfreq = ( freq << 5 ) / 468; - __u32 flags; + unsigned long flags; int i; if ( mac_special_bell == NULL ) @@ -224,7 +224,7 @@ static void mac_nosound( unsigned long ignored ) */ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) { - __u32 flags; + unsigned long flags; /* if the bell is already ringing, ring longer */ if ( mac_bell_duration > 0 ) @@ -271,7 +271,7 @@ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsig static void mac_quadra_ring_bell( unsigned long ignored ) { int i, count = mac_asc_samplespersec / HZ; - __u32 flags; + unsigned long flags; /* * we neither want a sound buffer overflow nor underflow, so we need to match diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index b30b3eb197a5..79b1ed198c07 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S @@ -355,6 +355,9 @@ ENTRY(sys_call_table) .long sys_set_thread_area .long sys_atomic_cmpxchg_32 /* 335 */ .long sys_atomic_barrier + .long sys_fanotify_init + .long sys_fanotify_mark + .long sys_prlimit64 .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 613f6912dfc1..dbc51065df5b 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -145,7 +145,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = (struct pt_regs *) ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 444b9f918fdf..7c2a2f7f8dc1 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -8,7 +8,6 @@ mainmenu "Linux Kernel Configuration" config MN10300 def_bool y select HAVE_OPROFILE - select HAVE_ARCH_TRACEHOOK config AM33 def_bool y diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug index ff80e86b9bd2..ce83c74b3fd7 100644 --- a/arch/mn10300/Kconfig.debug +++ b/arch/mn10300/Kconfig.debug @@ -101,7 +101,7 @@ config GDBSTUB_DEBUG_BREAKPOINT choice prompt "GDB stub port" - default GDBSTUB_TTYSM0 + default GDBSTUB_ON_TTYSM0 depends on GDBSTUB help Select the serial port used for GDB-stub. diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h index f49ac49e09ad..3f50e9661076 100644 --- a/arch/mn10300/include/asm/bitops.h +++ b/arch/mn10300/include/asm/bitops.h @@ -229,9 +229,9 @@ int ffs(int x) #include <asm-generic/bitops/hweight.h> #define ext2_set_bit_atomic(lock, nr, addr) \ - test_and_set_bit((nr) ^ 0x18, (addr)) + test_and_set_bit((nr), (addr)) #define ext2_clear_bit_atomic(lock, nr, addr) \ - test_and_clear_bit((nr) ^ 0x18, (addr)) + test_and_clear_bit((nr), (addr)) #include <asm-generic/bitops/ext2-non-atomic.h> #include <asm-generic/bitops/minix-le.h> diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h index 7e891fce2370..1865d72a86ff 100644 --- a/arch/mn10300/include/asm/signal.h +++ b/arch/mn10300/include/asm/signal.h @@ -78,7 +78,7 @@ typedef unsigned long sigset_t; /* These should not be considered constants from userland. */ #define SIGRTMIN 32 -#define SIGRTMAX (_NSIG-1) +#define SIGRTMAX _NSIG /* * SA_FLAGS values: diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index 9d49073e827a..db509dd80565 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c @@ -156,17 +156,17 @@ struct mn10300_serial_port mn10300_serial_port_sif0 = { ._intr = &SC0ICR, ._rxb = &SC0RXB, ._txb = &SC0TXB, - .rx_name = "ttySM0/Rx", - .tx_name = "ttySM0/Tx", + .rx_name = "ttySM0:Rx", + .tx_name = "ttySM0:Tx", #ifdef CONFIG_MN10300_TTYSM0_TIMER8 - .tm_name = "ttySM0/Timer8", + .tm_name = "ttySM0:Timer8", ._tmxmd = &TM8MD, ._tmxbr = &TM8BR, ._tmicr = &TM8ICR, .tm_irq = TM8IRQ, .div_timer = MNSCx_DIV_TIMER_16BIT, #else /* CONFIG_MN10300_TTYSM0_TIMER2 */ - .tm_name = "ttySM0/Timer2", + .tm_name = "ttySM0:Timer2", ._tmxmd = &TM2MD, ._tmxbr = (volatile u16 *) &TM2BR, ._tmicr = &TM2ICR, @@ -209,17 +209,17 @@ struct mn10300_serial_port mn10300_serial_port_sif1 = { ._intr = &SC1ICR, ._rxb = &SC1RXB, ._txb = &SC1TXB, - .rx_name = "ttySM1/Rx", - .tx_name = "ttySM1/Tx", + .rx_name = "ttySM1:Rx", + .tx_name = "ttySM1:Tx", #ifdef CONFIG_MN10300_TTYSM1_TIMER9 - .tm_name = "ttySM1/Timer9", + .tm_name = "ttySM1:Timer9", ._tmxmd = &TM9MD, ._tmxbr = &TM9BR, ._tmicr = &TM9ICR, .tm_irq = TM9IRQ, .div_timer = MNSCx_DIV_TIMER_16BIT, #else /* CONFIG_MN10300_TTYSM1_TIMER3 */ - .tm_name = "ttySM1/Timer3", + .tm_name = "ttySM1:Timer3", ._tmxmd = &TM3MD, ._tmxbr = (volatile u16 *) &TM3BR, ._tmicr = &TM3ICR, @@ -260,9 +260,9 @@ struct mn10300_serial_port mn10300_serial_port_sif2 = { .uart.lock = __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock), .name = "ttySM2", - .rx_name = "ttySM2/Rx", - .tx_name = "ttySM2/Tx", - .tm_name = "ttySM2/Timer10", + .rx_name = "ttySM2:Rx", + .tx_name = "ttySM2:Tx", + .tm_name = "ttySM2:Timer10", ._iobase = &SC2CTR, ._control = &SC2CTR, ._status = &SC2STR, diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index 717db14c2cc3..d4de05ab7864 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c @@ -65,10 +65,10 @@ asmlinkage long sys_sigaction(int sig, old_sigset_t mask; if (verify_area(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); } @@ -77,10 +77,10 @@ asmlinkage long sys_sigaction(int sig, if (!ret && oact) { if (verify_area(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; @@ -102,6 +102,9 @@ static int restore_sigcontext(struct pt_regs *regs, { unsigned int err = 0; + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + if (is_using_fpu(current)) fpu_kill_state(current); @@ -330,8 +333,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, regs->d0 = sig; regs->d1 = (unsigned long) &frame->sc; - set_fs(USER_DS); - /* the tracer may want to single-step inside the handler */ if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); @@ -345,7 +346,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, return 0; give_sigsegv: - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); return -EFAULT; } @@ -413,8 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->d0 = sig; regs->d1 = (long) &frame->info; - set_fs(USER_DS); - /* the tracer may want to single-step inside the handler */ if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); @@ -428,10 +427,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return 0; give_sigsegv: - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); return -EFAULT; } +static inline void stepback(struct pt_regs *regs) +{ + regs->pc -= 2; + regs->orig_d0 = -1; +} + /* * handle the actual delivery of a signal to userspace */ @@ -459,7 +464,7 @@ static int handle_signal(int sig, /* fallthrough */ case -ERESTARTNOINTR: regs->d0 = regs->orig_d0; - regs->pc -= 2; + stepback(regs); } } @@ -527,12 +532,12 @@ static void do_signal(struct pt_regs *regs) case -ERESTARTSYS: case -ERESTARTNOINTR: regs->d0 = regs->orig_d0; - regs->pc -= 2; + stepback(regs); break; case -ERESTART_RESTARTBLOCK: regs->d0 = __NR_restart_syscall; - regs->pc -= 2; + stepback(regs); break; } } diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile index 28b9d983db0c..1557277fbc5c 100644 --- a/arch/mn10300/mm/Makefile +++ b/arch/mn10300/mm/Makefile @@ -2,13 +2,11 @@ # Makefile for the MN10300-specific memory management code # +cacheflush-y := cache.o cache-mn10300.o +cacheflush-$(CONFIG_MN10300_CACHE_WBACK) += cache-flush-mn10300.o + +cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o + obj-y := \ init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \ - misalignment.o dma-alloc.o - -ifneq ($(CONFIG_MN10300_CACHE_DISABLED),y) -obj-y += cache.o cache-mn10300.o -ifeq ($(CONFIG_MN10300_CACHE_WBACK),y) -obj-y += cache-flush-mn10300.o -endif -endif + misalignment.o dma-alloc.o $(cacheflush-y) diff --git a/arch/mn10300/mm/cache-disabled.c b/arch/mn10300/mm/cache-disabled.c new file mode 100644 index 000000000000..f669ea42aba6 --- /dev/null +++ b/arch/mn10300/mm/cache-disabled.c @@ -0,0 +1,21 @@ +/* Handle the cache being disabled + * + * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#include <linux/mm.h> + +/* + * allow userspace to flush the instruction cache + */ +asmlinkage long sys_cacheflush(unsigned long start, unsigned long end) +{ + if (end < start) + return -EINVAL; + return 0; +} diff --git a/arch/mn10300/mm/cache.c b/arch/mn10300/mm/cache.c index 1b76719ec1c3..9261217e8d2c 100644 --- a/arch/mn10300/mm/cache.c +++ b/arch/mn10300/mm/cache.c @@ -54,13 +54,30 @@ EXPORT_SYMBOL(flush_icache_page); void flush_icache_range(unsigned long start, unsigned long end) { #ifdef CONFIG_MN10300_CACHE_WBACK - unsigned long addr, size, off; + unsigned long addr, size, base, off; struct page *page; pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *ppte, pte; + if (end > 0x80000000UL) { + /* addresses above 0xa0000000 do not go through the cache */ + if (end > 0xa0000000UL) { + end = 0xa0000000UL; + if (start >= end) + return; + } + + /* kernel addresses between 0x80000000 and 0x9fffffff do not + * require page tables, so we just map such addresses directly */ + base = (start >= 0x80000000UL) ? start : 0x80000000UL; + mn10300_dcache_flush_range(base, end); + if (base == start) + goto invalidate; + end = base; + } + for (; start < end; start += size) { /* work out how much of the page to flush */ off = start & (PAGE_SIZE - 1); @@ -104,6 +121,7 @@ void flush_icache_range(unsigned long start, unsigned long end) } #endif +invalidate: mn10300_icache_inv(); } EXPORT_SYMBOL(flush_icache_range); diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 02b77baa5da6..efa0b60c63fe 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -147,7 +147,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static __inline__ void __user *compat_alloc_user_space(long len) +static __inline__ void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = ¤t->thread.regs; return (void __user *)regs->gr[30]; diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 396d21a80058..a11d4eac4f97 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h @@ -134,7 +134,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = current->thread.regs; unsigned long usp = regs->gpr[1]; diff --git a/arch/powerpc/include/asm/fsldma.h b/arch/powerpc/include/asm/fsldma.h index a67aeed17d40..debc5ed96d6e 100644 --- a/arch/powerpc/include/asm/fsldma.h +++ b/arch/powerpc/include/asm/fsldma.h @@ -11,6 +11,7 @@ #ifndef __ARCH_POWERPC_ASM_FSLDMA_H__ #define __ARCH_POWERPC_ASM_FSLDMA_H__ +#include <linux/slab.h> #include <linux/dmaengine.h> /* diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 7109f5b1baa8..2300426e531a 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -138,6 +138,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } + regs->trap = 0; return 0; /* no signals delivered */ } @@ -164,6 +165,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } + regs->trap = 0; if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 266610119f66..b96a3a010c26 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -511,6 +511,7 @@ static long restore_user_regs(struct pt_regs *regs, if (!sig) save_r2 = (unsigned int)regs->gpr[2]; err = restore_general_regs(regs, sr); + regs->trap = 0; err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); if (!sig) regs->gpr[2] = (unsigned long) save_r2; @@ -884,7 +885,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, regs->nip = (unsigned long) ka->sa.sa_handler; /* enter the signal handler in big-endian mode */ regs->msr &= ~MSR_LE; - regs->trap = 0; return 1; badframe: @@ -1228,7 +1228,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, regs->nip = (unsigned long) ka->sa.sa_handler; /* enter the signal handler in big-endian mode */ regs->msr &= ~MSR_LE; - regs->trap = 0; return 1; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 2fe6fc64b614..27c4a4584f80 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -178,7 +178,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); /* skip SOFTE */ - err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); + regs->trap = 0; err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 104f2007f097..a875c2f542e1 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -181,7 +181,7 @@ static inline int is_compat_task(void) #endif -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { unsigned long stack; diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index 5016f76ea98a..6f57325bb883 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h @@ -167,7 +167,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 357ced3c33ff..6318e622cfb0 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1038,6 +1038,7 @@ static int __hw_perf_event_init(struct perf_event *event) if (atomic_read(&nmi_active) < 0) return -ENODEV; + pmap = NULL; if (attr->type == PERF_TYPE_HARDWARE) { if (attr->config >= sparc_pmu->max_events) return -EINVAL; @@ -1046,9 +1047,18 @@ static int __hw_perf_event_init(struct perf_event *event) pmap = sparc_map_cache_event(attr->config); if (IS_ERR(pmap)) return PTR_ERR(pmap); - } else + } else if (attr->type != PERF_TYPE_RAW) return -EOPNOTSUPP; + if (pmap) { + hwc->event_base = perf_event_encode(pmap); + } else { + /* User gives us "(encoding << 16) | pic_mask" for + * PERF_TYPE_RAW events. + */ + hwc->event_base = attr->config; + } + /* We save the enable bits in the config_base. */ hwc->config_base = sparc_pmu->irq_bit; if (!attr->exclude_user) @@ -1058,8 +1068,6 @@ static int __hw_perf_event_init(struct perf_event *event) if (!attr->exclude_hv) hwc->config_base |= sparc_pmu->hv_bit; - hwc->event_base = perf_event_encode(pmap); - n = 0; if (event->group_leader != event) { n = collect_events(event->group_leader, diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index ea22cd373c64..75fad425e249 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -453,8 +453,66 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) return err; } -static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, - int signo, sigset_t *oldset) +/* The I-cache flush instruction only works in the primary ASI, which + * right now is the nucleus, aka. kernel space. + * + * Therefore we have to kick the instructions out using the kernel + * side linear mapping of the physical address backing the user + * instructions. + */ +static void flush_signal_insns(unsigned long address) +{ + unsigned long pstate, paddr; + pte_t *ptep, pte; + pgd_t *pgdp; + pud_t *pudp; + pmd_t *pmdp; + + /* Commit all stores of the instructions we are about to flush. */ + wmb(); + + /* Disable cross-call reception. In this way even a very wide + * munmap() on another cpu can't tear down the page table + * hierarchy from underneath us, since that can't complete + * until the IPI tlb flush returns. + */ + + __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); + __asm__ __volatile__("wrpr %0, %1, %%pstate" + : : "r" (pstate), "i" (PSTATE_IE)); + + pgdp = pgd_offset(current->mm, address); + if (pgd_none(*pgdp)) + goto out_irqs_on; + pudp = pud_offset(pgdp, address); + if (pud_none(*pudp)) + goto out_irqs_on; + pmdp = pmd_offset(pudp, address); + if (pmd_none(*pmdp)) + goto out_irqs_on; + + ptep = pte_offset_map(pmdp, address); + pte = *ptep; + if (!pte_present(pte)) + goto out_unmap; + + paddr = (unsigned long) page_address(pte_page(pte)); + + __asm__ __volatile__("flush %0 + %1" + : /* no outputs */ + : "r" (paddr), + "r" (address & (PAGE_SIZE - 1)) + : "memory"); + +out_unmap: + pte_unmap(ptep); +out_irqs_on: + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); + +} + +static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, + int signo, sigset_t *oldset) { struct signal_frame32 __user *sf; int sigframe_size; @@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; } else { - /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); - pgd_t *pgdp = pgd_offset(current->mm, address); - pud_t *pudp = pud_offset(pgdp, address); - pmd_t *pmdp = pmd_offset(pudp, address); - pte_t *ptep; - pte_t pte; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); @@ -562,34 +614,22 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; - preempt_disable(); - ptep = pte_offset_map(pmdp, address); - pte = *ptep; - if (pte_present(pte)) { - unsigned long page = (unsigned long) - page_address(pte_page(pte)); - - wmb(); - __asm__ __volatile__("flush %0 + %1" - : /* no outputs */ - : "r" (page), - "r" (address & (PAGE_SIZE - 1)) - : "memory"); - } - pte_unmap(ptep); - preempt_enable(); + flush_signal_insns(address); } - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, - unsigned long signr, sigset_t *oldset, - siginfo_t *info) +static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, + unsigned long signr, sigset_t *oldset, + siginfo_t *info) { struct rt_signal_frame32 __user *sf; int sigframe_size; @@ -687,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; else { - /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); - pgd_t *pgdp = pgd_offset(current->mm, address); - pud_t *pudp = pud_offset(pgdp, address); - pmd_t *pmdp = pmd_offset(pudp, address); - pte_t *ptep; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); @@ -704,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; - preempt_disable(); - ptep = pte_offset_map(pmdp, address); - if (pte_present(*ptep)) { - unsigned long page = (unsigned long) - page_address(pte_page(*ptep)); - - wmb(); - __asm__ __volatile__("flush %0 + %1" - : /* no outputs */ - : "r" (page), - "r" (address & (PAGE_SIZE - 1)) - : "memory"); - } - pte_unmap(ptep); - preempt_enable(); + flush_signal_insns(address); } - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signr, current); + return -EFAULT; } -static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, - siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs) +static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, + siginfo_t *info, + sigset_t *oldset, struct pt_regs *regs) { + int err; + if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame32(ka, regs, signr, oldset, info); + err = setup_rt_frame32(ka, regs, signr, oldset, info); else - setup_frame32(ka, regs, signr, oldset); + err = setup_frame32(ka, regs, signr, oldset); + + if (err) + return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); @@ -743,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, sigaddset(¤t->blocked,signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_signal_handler(signr, info, ka, regs, 0); + + return 0; } static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, @@ -789,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, if (signr > 0) { if (restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); - handle_signal32(signr, &ka, &info, oldset, regs); - - /* 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 TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - - tracehook_signal_handler(signr, &info, &ka, regs, 0); + if (handle_signal32(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 TS_RESTORE_SIGMASK flag. + */ + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + } return; } if (restart_syscall && @@ -809,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 9882df92ba0a..5e5c5fd03783 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -315,8 +315,8 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) return err; } -static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, - int signo, sigset_t *oldset) +static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, + int signo, sigset_t *oldset) { struct signal_frame __user *sf; int sigframe_size, err; @@ -384,16 +384,19 @@ static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } - return; + return 0; sigill_and_return: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, - int signo, sigset_t *oldset, siginfo_t *info) +static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, + int signo, sigset_t *oldset, siginfo_t *info) { struct rt_signal_frame __user *sf; int sigframe_size; @@ -466,22 +469,30 @@ static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static inline void +static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { + int err; + if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(ka, regs, signr, oldset, info); + err = setup_rt_frame(ka, regs, signr, oldset, info); else - setup_frame(ka, regs, signr, oldset); + err = setup_frame(ka, regs, signr, oldset); + + if (err) + return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); @@ -489,6 +500,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_signal_handler(signr, info, ka, regs, 0); + + return 0; } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -546,17 +561,15 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); - handle_signal(signr, &ka, &info, oldset, regs); - - /* 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); - - tracehook_signal_handler(signr, &info, &ka, regs, 0); + 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); + } return; } if (restart_syscall && @@ -567,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) regs->u_regs[UREG_I0] = orig_i0; regs->pc -= 4; regs->npc -= 4; + pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; regs->npc -= 4; + pt_regs_clear_syscall(regs); } /* if there's no signal to deliver, we just put the saved sigmask diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 9fa48c30037e..006fe4515886 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -409,7 +409,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * return (void __user *) sp; } -static inline void +static inline int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) { @@ -483,26 +483,37 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, } /* 4. return to kernel instructions */ regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, - siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs) +static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, + siginfo_t *info, + sigset_t *oldset, struct pt_regs *regs) { - setup_rt_frame(ka, regs, signr, oldset, - (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); + int err; + + err = setup_rt_frame(ka, regs, signr, oldset, + (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); + if (err) + return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) sigaddset(¤t->blocked,signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_signal_handler(signr, info, ka, regs, 0); + + return 0; } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -571,16 +582,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); - handle_signal(signr, &ka, &info, oldset, regs); - - /* 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 TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - - tracehook_signal_handler(signr, &info, &ka, regs, 0); + 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 TS_RESTORE_SIGMASK flag. + */ + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + } return; } if (restart_syscall && @@ -591,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 50794137d710..675c9e11ada5 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c @@ -166,7 +166,6 @@ sparc_breakpoint (struct pt_regs *regs) { siginfo_t info; - lock_kernel(); #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc); #endif @@ -180,7 +179,6 @@ sparc_breakpoint (struct pt_regs *regs) #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc); #endif - unlock_kernel(); } asmlinkage int diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index f8514e291e15..12b9f352595f 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c @@ -323,7 +323,6 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) { enum direction dir; - lock_kernel(); if(!(current->thread.flags & SPARC_FLAG_UNALIGNED) || (((insn >> 30) & 3) != 3)) goto kill_user; @@ -377,5 +376,5 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) kill_user: user_mna_trap_fault(regs, insn); out: - unlock_kernel(); + ; } diff --git a/arch/sparc/kernel/windows.c b/arch/sparc/kernel/windows.c index f24d298bda29..b351770cbdd6 100644 --- a/arch/sparc/kernel/windows.c +++ b/arch/sparc/kernel/windows.c @@ -112,7 +112,6 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who) struct thread_info *tp = current_thread_info(); int window; - lock_kernel(); flush_user_windows(); for(window = 0; window < tp->w_saved; window++) { unsigned long sp = tp->rwbuf_stkptrs[window]; @@ -123,5 +122,4 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who) do_exit(SIGILL); } tp->w_saved = 0; - unlock_kernel(); } diff --git a/arch/tile/include/arch/chip_tile64.h b/arch/tile/include/arch/chip_tile64.h index 1246573be59e..261aaba092d4 100644 --- a/arch/tile/include/arch/chip_tile64.h +++ b/arch/tile/include/arch/chip_tile64.h @@ -150,6 +150,9 @@ /** Is the PROC_STATUS SPR supported? */ #define CHIP_HAS_PROC_STATUS_SPR() 0 +/** Is the DSTREAM_PF SPR supported? */ +#define CHIP_HAS_DSTREAM_PF() 0 + /** Log of the number of mshims we have. */ #define CHIP_LOG_NUM_MSHIMS() 2 diff --git a/arch/tile/include/arch/chip_tilepro.h b/arch/tile/include/arch/chip_tilepro.h index e864c47fc89c..70017699a74c 100644 --- a/arch/tile/include/arch/chip_tilepro.h +++ b/arch/tile/include/arch/chip_tilepro.h @@ -150,6 +150,9 @@ /** Is the PROC_STATUS SPR supported? */ #define CHIP_HAS_PROC_STATUS_SPR() 1 +/** Is the DSTREAM_PF SPR supported? */ +#define CHIP_HAS_DSTREAM_PF() 0 + /** Log of the number of mshims we have. */ #define CHIP_LOG_NUM_MSHIMS() 2 diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h index 5a34da6cdd79..8b60ec8b2d19 100644 --- a/arch/tile/include/asm/compat.h +++ b/arch/tile/include/asm/compat.h @@ -195,7 +195,7 @@ static inline unsigned long ptr_to_compat_reg(void __user *uptr) return (long)(int)(long __force)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *)regs->sp - len; @@ -214,8 +214,9 @@ extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka, struct compat_sigaction; struct compat_siginfo; struct compat_sigaltstack; -long compat_sys_execve(char __user *path, compat_uptr_t __user *argv, - compat_uptr_t __user *envp); +long compat_sys_execve(const char __user *path, + const compat_uptr_t __user *argv, + const compat_uptr_t __user *envp); long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, struct compat_sigaction __user *oact, size_t sigsetsize); diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h index 8c95bef3fa45..ee43328713ab 100644 --- a/arch/tile/include/asm/io.h +++ b/arch/tile/include/asm/io.h @@ -164,22 +164,22 @@ static inline void _tile_writeq(u64 val, unsigned long addr) #define iowrite32 writel #define iowrite64 writeq -static inline void *memcpy_fromio(void *dst, void *src, int len) +static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, + size_t len) { int x; BUG_ON((unsigned long)src & 0x3); for (x = 0; x < len; x += 4) *(u32 *)(dst + x) = readl(src + x); - return dst; } -static inline void *memcpy_toio(void *dst, void *src, int len) +static inline void memcpy_toio(volatile void __iomem *dst, const void *src, + size_t len) { int x; BUG_ON((unsigned long)dst & 0x3); for (x = 0; x < len; x += 4) writel(*(u32 *)(src + x), dst + x); - return dst; } /* diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h index d942d09b252e..ccd5f8425688 100644 --- a/arch/tile/include/asm/processor.h +++ b/arch/tile/include/asm/processor.h @@ -103,6 +103,18 @@ struct thread_struct { /* Any other miscellaneous processor state bits */ unsigned long proc_status; #endif +#if !CHIP_HAS_FIXED_INTVEC_BASE() + /* Interrupt base for PL0 interrupts */ + unsigned long interrupt_vector_base; +#endif +#if CHIP_HAS_TILE_RTF_HWM() + /* Tile cache retry fifo high-water mark */ + unsigned long tile_rtf_hwm; +#endif +#if CHIP_HAS_DSTREAM_PF() + /* Data stream prefetch control */ + unsigned long dstream_pf; +#endif #ifdef CONFIG_HARDWALL /* Is this task tied to an activated hardwall? */ struct hardwall_info *hardwall; diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index acdae814e016..4a02bb073979 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h @@ -51,10 +51,7 @@ typedef uint_reg_t pt_reg_t; /* * This struct defines the way the registers are stored on the stack during a - * system call/exception. It should be a multiple of 8 bytes to preserve - * normal stack alignment rules. - * - * Must track <sys/ucontext.h> and <sys/procfs.h> + * system call or exception. "struct sigcontext" has the same shape. */ struct pt_regs { /* Saved main processor registers; 56..63 are special. */ @@ -80,11 +77,6 @@ struct pt_regs { #endif /* __ASSEMBLY__ */ -/* Flag bits in pt_regs.flags */ -#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */ -#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */ -#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */ - #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 @@ -101,6 +93,11 @@ struct pt_regs { #ifdef __KERNEL__ +/* Flag bits in pt_regs.flags */ +#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */ +#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */ +#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */ + #ifndef __ASSEMBLY__ #define instruction_pointer(regs) ((regs)->pc) diff --git a/arch/tile/include/asm/sigcontext.h b/arch/tile/include/asm/sigcontext.h index 7cd7672e3ad4..5e2d03336f53 100644 --- a/arch/tile/include/asm/sigcontext.h +++ b/arch/tile/include/asm/sigcontext.h @@ -15,13 +15,21 @@ #ifndef _ASM_TILE_SIGCONTEXT_H #define _ASM_TILE_SIGCONTEXT_H -/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */ -#include <asm/ptrace.h> - -/* Must track <sys/ucontext.h> */ +#include <arch/abi.h> +/* + * struct sigcontext has the same shape as struct pt_regs, + * but is simplified since we know the fault is from userspace. + */ struct sigcontext { - struct pt_regs regs; + uint_reg_t gregs[53]; /* General-purpose registers. */ + uint_reg_t tp; /* Aliases gregs[TREG_TP]. */ + uint_reg_t sp; /* Aliases gregs[TREG_SP]. */ + uint_reg_t lr; /* Aliases gregs[TREG_LR]. */ + uint_reg_t pc; /* Program counter. */ + uint_reg_t ics; /* In Interrupt Critical Section? */ + uint_reg_t faultnum; /* Fault number. */ + uint_reg_t pad[5]; }; #endif /* _ASM_TILE_SIGCONTEXT_H */ diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h index eb0253f32202..c1ee1d61d44c 100644 --- a/arch/tile/include/asm/signal.h +++ b/arch/tile/include/asm/signal.h @@ -24,6 +24,7 @@ #include <asm-generic/signal.h> #if defined(__KERNEL__) && !defined(__ASSEMBLY__) +struct pt_regs; int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); void do_signal(struct pt_regs *regs); diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h index af165a74537f..ce99ffefeacf 100644 --- a/arch/tile/include/asm/syscalls.h +++ b/arch/tile/include/asm/syscalls.h @@ -62,10 +62,12 @@ long sys_fork(void); long _sys_fork(struct pt_regs *regs); long sys_vfork(void); long _sys_vfork(struct pt_regs *regs); -long sys_execve(char __user *filename, char __user * __user *argv, - char __user * __user *envp); -long _sys_execve(char __user *filename, char __user * __user *argv, - char __user * __user *envp, struct pt_regs *regs); +long sys_execve(const char __user *filename, + const char __user *const __user *argv, + const char __user *const __user *envp); +long _sys_execve(const char __user *filename, + const char __user *const __user *argv, + const char __user *const __user *envp, struct pt_regs *regs); /* kernel/signal.c */ long sys_sigaltstack(const stack_t __user *, stack_t __user *); @@ -86,10 +88,13 @@ int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *); #endif #ifdef CONFIG_COMPAT -long compat_sys_execve(char __user *path, compat_uptr_t __user *argv, - compat_uptr_t __user *envp); -long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, - compat_uptr_t __user *envp, struct pt_regs *regs); +long compat_sys_execve(const char __user *path, + const compat_uptr_t __user *argv, + const compat_uptr_t __user *envp); +long _compat_sys_execve(const char __user *path, + const compat_uptr_t __user *argv, + const compat_uptr_t __user *envp, + struct pt_regs *regs); long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, struct compat_sigaltstack __user *uoss_ptr); long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 84f296ca9e63..8f58bdff20d7 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S @@ -1506,13 +1506,6 @@ handle_ill: } STD_ENDPROC(handle_ill) - .pushsection .rodata, "a" - .align 8 -bpt_code: - bpt - ENDPROC(bpt_code) - .popsection - /* Various stub interrupt handlers and syscall handlers */ STD_ENTRY_LOCAL(_kernel_double_fault) diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 985cc28c74c5..84c29111756c 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -408,6 +408,15 @@ static void save_arch_state(struct thread_struct *t) #if CHIP_HAS_PROC_STATUS_SPR() t->proc_status = __insn_mfspr(SPR_PROC_STATUS); #endif +#if !CHIP_HAS_FIXED_INTVEC_BASE() + t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0); +#endif +#if CHIP_HAS_TILE_RTF_HWM() + t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM); +#endif +#if CHIP_HAS_DSTREAM_PF() + t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF); +#endif } static void restore_arch_state(const struct thread_struct *t) @@ -428,14 +437,14 @@ static void restore_arch_state(const struct thread_struct *t) #if CHIP_HAS_PROC_STATUS_SPR() __insn_mtspr(SPR_PROC_STATUS, t->proc_status); #endif +#if !CHIP_HAS_FIXED_INTVEC_BASE() + __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base); +#endif #if CHIP_HAS_TILE_RTF_HWM() - /* - * Clear this whenever we switch back to a process in case - * the previous process was monkeying with it. Even if enabled - * in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a - * performance hint, so isn't worth a full save/restore. - */ - __insn_mtspr(SPR_TILE_RTF_HWM, 0); + __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm); +#endif +#if CHIP_HAS_DSTREAM_PF() + __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf); #endif } @@ -561,8 +570,9 @@ out: } #ifdef CONFIG_COMPAT -long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, - compat_uptr_t __user *envp, struct pt_regs *regs) +long _compat_sys_execve(const char __user *path, + const compat_uptr_t __user *argv, + const compat_uptr_t __user *envp, struct pt_regs *regs) { long error; char *filename; @@ -657,7 +667,7 @@ void show_regs(struct pt_regs *regs) regs->regs[51], regs->regs[52], regs->tp); pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); #else - for (i = 0; i < 52; i += 3) + for (i = 0; i < 52; i += 4) pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", i, regs->regs[i], i+1, regs->regs[i+1], diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 45b66a3c991f..ce183aa1492c 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c @@ -61,13 +61,19 @@ int restore_sigcontext(struct pt_regs *regs, /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; + /* + * Enforce that sigcontext is like pt_regs, and doesn't mess + * up our stack alignment rules. + */ + BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs)); + BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0); + for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) - err |= __get_user(((long *)regs)[i], - &((long __user *)(&sc->regs))[i]); + err |= __get_user(regs->regs[i], &sc->gregs[i]); regs->faultnum = INT_SWINT_1_SIGRETURN; - err |= __get_user(*pr0, &sc->regs.regs[0]); + err |= __get_user(*pr0, &sc->gregs[0]); return err; } @@ -112,8 +118,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) int i, err = 0; for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) - err |= __put_user(((long *)regs)[i], - &((long __user *)(&sc->regs))[i]); + err |= __put_user(regs->regs[i], &sc->gregs[i]); return err; } @@ -203,19 +208,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * Set up registers for signal handler. * Registers that we don't modify keep the value they had from * user-space at the time we took the signal. + * We always pass siginfo and mcontext, regardless of SA_SIGINFO, + * since some things rely on this (e.g. glibc's debug/segfault.c). */ regs->pc = (unsigned long) ka->sa.sa_handler; regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ regs->sp = (unsigned long) frame; regs->lr = restorer; regs->regs[0] = (unsigned long) usig; - - if (ka->sa.sa_flags & SA_SIGINFO) { - /* Need extra arguments, so mark to restore caller-saves. */ - regs->regs[1] = (unsigned long) &frame->info; - regs->regs[2] = (unsigned long) &frame->uc; - regs->flags |= PT_FLAGS_CALLER_SAVES; - } + regs->regs[1] = (unsigned long) &frame->info; + regs->regs[2] = (unsigned long) &frame->uc; + regs->flags |= PT_FLAGS_CALLER_SAVES; /* * Notify any tracer that was single-stepping it. diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index 38a68b0b4581..ea2e0ce28380 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c @@ -175,7 +175,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt) pr_err(" <received signal %d>\n", frame->info.si_signo); } - return &frame->uc.uc_mcontext.regs; + return (struct pt_regs *)&frame->uc.uc_mcontext; } return NULL; } diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index cd145eda3579..49b5e1eb3262 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -62,7 +62,7 @@ static long execve1(const char *file, return error; } -long um_execve(const char *file, char __user *__user *argv, char __user *__user *env) +long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) { long err; @@ -72,8 +72,8 @@ long um_execve(const char *file, char __user *__user *argv, char __user *__user return err; } -long sys_execve(const char __user *file, char __user *__user *argv, - char __user *__user *env) +long sys_execve(const char __user *file, const char __user *const __user *argv, + const char __user *const __user *env) { long error; char *filename; diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h index 1303a105fe91..5bf97db24a04 100644 --- a/arch/um/kernel/internal.h +++ b/arch/um/kernel/internal.h @@ -1 +1 @@ -extern long um_execve(const char *file, char __user *__user *argv, char __user *__user *env); +extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env); diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 5ddb246626db..f958cb876ee3 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -60,8 +60,8 @@ int kernel_execve(const char *filename, fs = get_fs(); set_fs(KERNEL_DS); - ret = um_execve(filename, (char __user *__user *)argv, - (char __user *__user *) envp); + ret = um_execve(filename, (const char __user *const __user *)argv, + (const char __user *const __user *) envp); set_fs(fs); return ret; diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 8aa1b59b9074..e8c8881351b3 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -74,7 +74,7 @@ endif ifdef CONFIG_CC_STACKPROTECTOR cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh - ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y) + ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) stackp-y := -fstack-protector KBUILD_CFLAGS += $(stackp-y) else diff --git a/arch/x86/boot/early_serial_console.c b/arch/x86/boot/early_serial_console.c index 030f4b93e255..5df2869c874b 100644 --- a/arch/x86/boot/early_serial_console.c +++ b/arch/x86/boot/early_serial_console.c @@ -58,7 +58,19 @@ static void parse_earlyprintk(void) if (arg[pos] == ',') pos++; - if (!strncmp(arg, "ttyS", 4)) { + /* + * make sure we have + * "serial,0x3f8,115200" + * "serial,ttyS0,115200" + * "ttyS0,115200" + */ + if (pos == 7 && !strncmp(arg + pos, "0x", 2)) { + port = simple_strtoull(arg + pos, &e, 16); + if (port == 0 || arg + pos == e) + port = DEFAULT_SERIAL_PORT; + else + pos = e - arg; + } else if (!strncmp(arg + pos, "ttyS", 4)) { static const int bases[] = { 0x3f8, 0x2f8 }; int idx = 0; diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index b86feabed69b..518bb99c3394 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -50,7 +50,12 @@ /* * Reload arg registers from stack in case ptrace changed them. * We don't reload %eax because syscall_trace_enter() returned - * the value it wants us to use in the table lookup. + * the %rax value we should see. Instead, we just truncate that + * value to 32 bits again as we did on entry from user mode. + * If it's a new value set by user_regset during entry tracing, + * this matches the normal truncation of the user-mode value. + * If it's -1 to make us punt the syscall, then (u32)-1 is still + * an appropriately invalid value. */ .macro LOAD_ARGS32 offset, _r9=0 .if \_r9 @@ -60,6 +65,7 @@ movl \offset+48(%rsp),%edx movl \offset+56(%rsp),%esi movl \offset+64(%rsp),%edi + movl %eax,%eax /* zero extension */ .endm .macro CFI_STARTPROC32 simple @@ -153,7 +159,7 @@ ENTRY(ia32_sysenter_target) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) CFI_REMEMBER_STATE jnz sysenter_tracesys - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys sysenter_do_call: IA32_ARG_FIXUP @@ -195,7 +201,7 @@ sysexit_from_sys_call: movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ call audit_syscall_entry movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys movl %ebx,%edi /* reload 1st syscall arg */ movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ @@ -248,7 +254,7 @@ sysenter_tracesys: call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ jmp sysenter_do_call CFI_ENDPROC @@ -314,7 +320,7 @@ ENTRY(ia32_cstar_target) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) CFI_REMEMBER_STATE jnz cstar_tracesys - cmpl $IA32_NR_syscalls-1,%eax + cmpq $IA32_NR_syscalls-1,%rax ja ia32_badsys cstar_do_call: IA32_ARG_FIXUP 1 @@ -367,7 +373,7 @@ cstar_tracesys: LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ RESTORE_REST xchgl %ebp,%r9d - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ jmp cstar_do_call END(ia32_cstar_target) @@ -425,7 +431,7 @@ ENTRY(ia32_syscall) orl $TS_COMPAT,TI_status(%r10) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) jnz ia32_tracesys - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys ia32_do_call: IA32_ARG_FIXUP @@ -444,7 +450,7 @@ ia32_tracesys: call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ jmp ia32_do_call END(ia32_syscall) diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h index d2544f1d705d..cb030374b90a 100644 --- a/arch/x86/include/asm/amd_iommu_proto.h +++ b/arch/x86/include/asm/amd_iommu_proto.h @@ -38,4 +38,10 @@ static inline void amd_iommu_stats_init(void) { } #endif /* !CONFIG_AMD_IOMMU_STATS */ +static inline bool is_rd890_iommu(struct pci_dev *pdev) +{ + return (pdev->vendor == PCI_VENDOR_ID_ATI) && + (pdev->device == PCI_DEVICE_ID_RD890_IOMMU); +} + #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 7014e88bc779..08616180deaf 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h @@ -368,6 +368,9 @@ struct amd_iommu { /* capabilities of that IOMMU read from ACPI */ u32 cap; + /* flags read from acpi table */ + u8 acpi_flags; + /* * Capability pointer. There could be more than one IOMMU per PCI * device function if there are more than one AMD IOMMU capability @@ -411,6 +414,15 @@ struct amd_iommu { /* default dma_ops domain for that IOMMU */ struct dma_ops_domain *default_dom; + + /* + * This array is required to work around a potential BIOS bug. + * The BIOS may miss to restore parts of the PCI configuration + * space when the system resumes from S3. The result is that the + * IOMMU does not execute commands anymore which leads to system + * failure. + */ + u32 cache_cfg[4]; }; /* diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 545776efeb16..bafd80defa43 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -309,7 +309,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) { return ((1UL << (nr % BITS_PER_LONG)) & - (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; + (addr[nr / BITS_PER_LONG])) != 0; } static inline int variable_test_bit(int nr, volatile const unsigned long *addr) diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index 306160e58b48..1d9cd27c2920 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h @@ -205,7 +205,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *)regs->sp - len; diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 781a50b29a49..3f76523589af 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -168,6 +168,7 @@ #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ +#define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ /* Virtualization flags: Linux defined, word 8 */ #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ @@ -296,6 +297,7 @@ extern const char * const x86_power_flags[32]; #endif /* CONFIG_X86_64 */ +#if __GNUC__ >= 4 /* * Static testing of CPU features. Used the same as boot_cpu_has(). * These are only valid after alternatives have run, but will statically @@ -304,7 +306,7 @@ extern const char * const x86_power_flags[32]; */ static __always_inline __pure bool __static_cpu_has(u16 bit) { -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#if __GNUC__ > 4 || __GNUC_MINOR__ >= 5 asm goto("1: jmp %l[t_no]\n" "2:\n" ".section .altinstructions,\"a\"\n" @@ -345,7 +347,6 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) #endif } -#if __GNUC__ >= 4 #define static_cpu_has(bit) \ ( \ __builtin_constant_p(boot_cpu_has(bit)) ? \ diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index 004e6e25e913..1d5c08a1bdfd 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h @@ -68,7 +68,6 @@ extern unsigned long force_hpet_address; extern u8 hpet_blockid; extern int hpet_force_user; extern u8 hpet_msi_disable; -extern u8 hpet_readback_cmp; extern int is_hpet_enabled(void); extern int hpet_enable(void); extern void hpet_disable(void); diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index 528a11e8d3e3..824ca07860d0 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h @@ -20,7 +20,7 @@ struct arch_hw_breakpoint { #include <linux/list.h> /* Available HW breakpoint length encodings */ -#define X86_BREAKPOINT_LEN_X 0x00 +#define X86_BREAKPOINT_LEN_X 0x40 #define X86_BREAKPOINT_LEN_1 0x40 #define X86_BREAKPOINT_LEN_2 0x44 #define X86_BREAKPOINT_LEN_4 0x4c diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h index f35eb45d6576..c4191b3b7056 100644 --- a/arch/x86/include/asm/iomap.h +++ b/arch/x86/include/asm/iomap.h @@ -26,11 +26,11 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> -void * +void __iomem * iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); void -iounmap_atomic(void *kvaddr, enum km_type type); +iounmap_atomic(void __iomem *kvaddr, enum km_type type); int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot); diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 51cfd730ac5d..1f99ecfc48e1 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -152,9 +152,14 @@ struct x86_emulate_ops { struct operand { enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type; unsigned int bytes; - unsigned long orig_val, *ptr; + union { + unsigned long orig_val; + u64 orig_val64; + }; + unsigned long *ptr; union { unsigned long val; + u64 val64; char valptr[sizeof(unsigned long) + 2]; }; }; diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 0925676266bd..fedf32a8c3ec 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -11,6 +11,8 @@ ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_tsc.o = -pg CFLAGS_REMOVE_rtc.o = -pg CFLAGS_REMOVE_paravirt-spinlocks.o = -pg +CFLAGS_REMOVE_pvclock.o = -pg +CFLAGS_REMOVE_kvmclock.o = -pg CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index fb7a5f052e2b..fb16f17e59be 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -61,7 +61,7 @@ struct cstate_entry { unsigned int ecx; } states[ACPI_PROCESSOR_MAX_POWER]; }; -static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */ +static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index fa044e1e30a2..679b6450382b 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -1953,6 +1953,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, size_t size, int dir) { + dma_addr_t flush_addr; dma_addr_t i, start; unsigned int pages; @@ -1960,6 +1961,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, (dma_addr + size > dma_dom->aperture_size)) return; + flush_addr = dma_addr; pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); dma_addr &= PAGE_MASK; start = dma_addr; @@ -1974,7 +1976,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, dma_ops_free_addresses(dma_dom, dma_addr, pages); if (amd_iommu_unmap_flush || dma_dom->need_flush) { - iommu_flush_pages(&dma_dom->domain, dma_addr, size); + iommu_flush_pages(&dma_dom->domain, flush_addr, size); dma_dom->need_flush = false; } } diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 3cc63e2b8dd4..5a170cbbbed8 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -632,6 +632,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu) iommu->last_device = calc_devid(MMIO_GET_BUS(range), MMIO_GET_LD(range)); iommu->evt_msi_num = MMIO_MSI_NUM(misc); + + if (is_rd890_iommu(iommu->dev)) { + pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]); + pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]); + pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]); + pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]); + } } /* @@ -649,29 +656,9 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, struct ivhd_entry *e; /* - * First set the recommended feature enable bits from ACPI - * into the IOMMU control registers + * First save the recommended feature enable bits from ACPI */ - h->flags & IVHD_FLAG_HT_TUN_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : - iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); - - h->flags & IVHD_FLAG_PASSPW_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : - iommu_feature_disable(iommu, CONTROL_PASSPW_EN); - - h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : - iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); - - h->flags & IVHD_FLAG_ISOC_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_ISOC_EN) : - iommu_feature_disable(iommu, CONTROL_ISOC_EN); - - /* - * make IOMMU memory accesses cache coherent - */ - iommu_feature_enable(iommu, CONTROL_COHERENT_EN); + iommu->acpi_flags = h->flags; /* * Done. Now parse the device entries @@ -1116,6 +1103,40 @@ static void init_device_table(void) } } +static void iommu_init_flags(struct amd_iommu *iommu) +{ + iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : + iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); + + iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : + iommu_feature_disable(iommu, CONTROL_PASSPW_EN); + + iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : + iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); + + iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_ISOC_EN) : + iommu_feature_disable(iommu, CONTROL_ISOC_EN); + + /* + * make IOMMU memory accesses cache coherent + */ + iommu_feature_enable(iommu, CONTROL_COHERENT_EN); +} + +static void iommu_apply_quirks(struct amd_iommu *iommu) +{ + if (is_rd890_iommu(iommu->dev)) { + pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]); + pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]); + pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]); + pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]); + } +} + /* * This function finally enables all IOMMUs found in the system after * they have been initialized @@ -1126,6 +1147,8 @@ static void enable_iommus(void) for_each_iommu(iommu) { iommu_disable(iommu); + iommu_apply_quirks(iommu); + iommu_init_flags(iommu); iommu_set_device_table(iommu); iommu_enable_command_buffer(iommu); iommu_enable_event_buffer(iommu); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index f1efebaf5510..5c5b8f3dddb5 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -306,14 +306,19 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc, old_cfg = old_desc->chip_data; - memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); + cfg->vector = old_cfg->vector; + cfg->move_in_progress = old_cfg->move_in_progress; + cpumask_copy(cfg->domain, old_cfg->domain); + cpumask_copy(cfg->old_domain, old_cfg->old_domain); init_copy_irq_2_pin(old_cfg, cfg, node); } -static void free_irq_cfg(struct irq_cfg *old_cfg) +static void free_irq_cfg(struct irq_cfg *cfg) { - kfree(old_cfg); + free_cpumask_var(cfg->domain); + free_cpumask_var(cfg->old_domain); + kfree(cfg); } void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 7b598b84c902..f744f54cb248 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -698,9 +698,11 @@ void __init uv_system_init(void) for (j = 0; j < 64; j++) { if (!test_bit(j, &present)) continue; - uv_blade_info[blade].pnode = (i * 64 + j); + pnode = (i * 64 + j); + uv_blade_info[blade].pnode = pnode; uv_blade_info[blade].nr_possible_cpus = 0; uv_blade_info[blade].nr_online_cpus = 0; + max_pnode = max(pnode, max_pnode); blade++; } } @@ -738,7 +740,6 @@ void __init uv_system_init(void) uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid); uv_node_to_blade[nid] = blade; uv_cpu_to_blade[cpu] = blade; - max_pnode = max(pnode, max_pnode); } /* Add blade/pnode info for nodes without cpus */ @@ -750,7 +751,6 @@ void __init uv_system_init(void) pnode = (paddr >> m_val) & pnode_mask; blade = boot_pnode_to_blade(pnode); uv_node_to_blade[nid] = blade; - max_pnode = max(pnode, max_pnode); } map_gru_high(max_pnode); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 490dac63c2d2..f2f9ac7da25c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -545,7 +545,7 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c) } } -static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) +void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) { u32 tfms, xlvl; u32 ebx; diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 3624e8a0f71b..f668bb1f7d43 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -33,5 +33,6 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[], *const __x86_cpu_dev_end[]; extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); +extern void get_cpu_cap(struct cpuinfo_x86 *c); #endif diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 85f69cdeae10..b4389441efbb 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -39,6 +39,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); c->cpuid_level = cpuid_eax(0); + get_cpu_cap(c); } } diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 224392d8fe8c..5e975298fa81 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -530,7 +530,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) err = -ENOMEM; goto out; } - if (!alloc_cpumask_var(&b->cpus, GFP_KERNEL)) { + if (!zalloc_cpumask_var(&b->cpus, GFP_KERNEL)) { kfree(b); err = -ENOMEM; goto out; @@ -543,7 +543,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) #ifndef CONFIG_SMP cpumask_setall(b->cpus); #else - cpumask_copy(b->cpus, c->llc_shared_map); + cpumask_set_cpu(cpu, b->cpus); #endif per_cpu(threshold_banks, cpu)[bank] = b; diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index c2a8b26d4fea..d9368eeda309 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -202,10 +202,11 @@ static int therm_throt_process(bool new_event, int event, int level) #ifdef CONFIG_SYSFS /* Add/Remove thermal_throttle interface for CPU device: */ -static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) +static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev, + unsigned int cpu) { int err; - struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); + struct cpuinfo_x86 *c = &cpu_data(cpu); err = sysfs_create_group(&sys_dev->kobj, &thermal_attr_group); if (err) @@ -251,7 +252,7 @@ thermal_throttle_cpu_callback(struct notifier_block *nfb, case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: mutex_lock(&therm_cpu_lock); - err = thermal_throttle_add_dev(sys_dev); + err = thermal_throttle_add_dev(sys_dev, cpu); mutex_unlock(&therm_cpu_lock); WARN_ON(err); break; @@ -287,7 +288,7 @@ static __init int thermal_throttle_init_device(void) #endif /* connect live CPUs to sysfs */ for_each_online_cpu(cpu) { - err = thermal_throttle_add_dev(get_cpu_sysdev(cpu)); + err = thermal_throttle_add_dev(get_cpu_sysdev(cpu), cpu); WARN_ON(err); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index f2da20fda02d..03a5b0385ad6 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -102,6 +102,7 @@ struct cpu_hw_events { */ struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; int enabled; int n_events; @@ -1010,6 +1011,7 @@ static int x86_pmu_start(struct perf_event *event) x86_perf_event_set_period(event); cpuc->events[idx] = event; __set_bit(idx, cpuc->active_mask); + __set_bit(idx, cpuc->running); x86_pmu.enable(event); perf_event_update_userpage(event); @@ -1141,8 +1143,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) cpuc = &__get_cpu_var(cpu_hw_events); for (idx = 0; idx < x86_pmu.num_counters; idx++) { - if (!test_bit(idx, cpuc->active_mask)) + if (!test_bit(idx, cpuc->active_mask)) { + /* + * Though we deactivated the counter some cpus + * might still deliver spurious interrupts still + * in flight. Catch them: + */ + if (__test_and_clear_bit(idx, cpuc->running)) + handled++; continue; + } event = cpuc->events[idx]; hwc = &event->hw; @@ -1154,7 +1164,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) /* * event overflow */ - handled = 1; + handled++; data.period = event->hw.last_period; if (!x86_perf_event_set_period(event)) @@ -1200,12 +1210,20 @@ void perf_events_lapic_init(void) apic_write(APIC_LVTPC, APIC_DM_NMI); } +struct pmu_nmi_state { + unsigned int marked; + int handled; +}; + +static DEFINE_PER_CPU(struct pmu_nmi_state, pmu_nmi); + static int __kprobes perf_event_nmi_handler(struct notifier_block *self, unsigned long cmd, void *__args) { struct die_args *args = __args; - struct pt_regs *regs; + unsigned int this_nmi; + int handled; if (!atomic_read(&active_events)) return NOTIFY_DONE; @@ -1214,22 +1232,47 @@ perf_event_nmi_handler(struct notifier_block *self, case DIE_NMI: case DIE_NMI_IPI: break; - + case DIE_NMIUNKNOWN: + this_nmi = percpu_read(irq_stat.__nmi_count); + if (this_nmi != __get_cpu_var(pmu_nmi).marked) + /* let the kernel handle the unknown nmi */ + return NOTIFY_DONE; + /* + * This one is a PMU back-to-back nmi. Two events + * trigger 'simultaneously' raising two back-to-back + * NMIs. If the first NMI handles both, the latter + * will be empty and daze the CPU. So, we drop it to + * avoid false-positive 'unknown nmi' messages. + */ + return NOTIFY_STOP; default: return NOTIFY_DONE; } - regs = args->regs; - apic_write(APIC_LVTPC, APIC_DM_NMI); - /* - * Can't rely on the handled return value to say it was our NMI, two - * events could trigger 'simultaneously' raising two back-to-back NMIs. - * - * If the first NMI handles both, the latter will be empty and daze - * the CPU. - */ - x86_pmu.handle_irq(regs); + + handled = x86_pmu.handle_irq(args->regs); + if (!handled) + return NOTIFY_DONE; + + this_nmi = percpu_read(irq_stat.__nmi_count); + if ((handled > 1) || + /* the next nmi could be a back-to-back nmi */ + ((__get_cpu_var(pmu_nmi).marked == this_nmi) && + (__get_cpu_var(pmu_nmi).handled > 1))) { + /* + * We could have two subsequent back-to-back nmis: The + * first handles more than one counter, the 2nd + * handles only one counter and the 3rd handles no + * counter. + * + * This is the 2nd nmi because the previous was + * handling more than one counter. We will mark the + * next (3rd) and then drop it if unhandled. + */ + __get_cpu_var(pmu_nmi).marked = this_nmi + 1; + __get_cpu_var(pmu_nmi).handled = handled; + } return NOTIFY_STOP; } diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index d8d86d014008..ee05c90012d2 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -712,7 +712,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) struct perf_sample_data data; struct cpu_hw_events *cpuc; int bit, loops; - u64 ack, status; + u64 status; + int handled = 0; perf_sample_data_init(&data, 0); @@ -728,6 +729,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) loops = 0; again: + intel_pmu_ack_status(status); if (++loops > 100) { WARN_ONCE(1, "perfevents: irq loop stuck!\n"); perf_event_print_debug(); @@ -736,19 +738,22 @@ again: } inc_irq_stat(apic_perf_irqs); - ack = status; intel_pmu_lbr_read(); /* * PEBS overflow sets bit 62 in the global status register */ - if (__test_and_clear_bit(62, (unsigned long *)&status)) + if (__test_and_clear_bit(62, (unsigned long *)&status)) { + handled++; x86_pmu.drain_pebs(regs); + } for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { struct perf_event *event = cpuc->events[bit]; + handled++; + if (!test_bit(bit, cpuc->active_mask)) continue; @@ -761,8 +766,6 @@ again: x86_pmu_stop(event); } - intel_pmu_ack_status(ack); - /* * Repeat if there is more work to be done: */ @@ -772,7 +775,7 @@ again: done: intel_pmu_enable_all(0); - return 1; + return handled; } static struct event_constraint * diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 7e578e9cc58b..b560db3305be 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -692,7 +692,7 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) inc_irq_stat(apic_perf_irqs); } - return handled > 0; + return handled; } /* diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 34b4dad6f0b8..d49079515122 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) const struct cpuid_bit *cb; static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { + { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 }, { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index e5cc7e82e60d..ebdb85cf2686 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -18,7 +18,6 @@ #include <asm/apic.h> #include <asm/iommu.h> #include <asm/gart.h> -#include <asm/hpet.h> static void __init fix_hypertransport_config(int num, int slot, int func) { @@ -192,21 +191,6 @@ static void __init ati_bugs_contd(int num, int slot, int func) } #endif -/* - * Force the read back of the CMP register in hpet_next_event() - * to work around the problem that the CMP register write seems to be - * delayed. See hpet_next_event() for details. - * - * We do this on all SMBUS incarnations for now until we have more - * information about the affected chipsets. - */ -static void __init ati_hpet_bugs(int num, int slot, int func) -{ -#ifdef CONFIG_HPET_TIMER - hpet_readback_cmp = 1; -#endif -} - #define QFLAG_APPLY_ONCE 0x1 #define QFLAG_APPLIED 0x2 #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) @@ -236,8 +220,6 @@ static struct chipset early_qrk[] __initdata = { PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs }, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd }, - { PCI_VENDOR_ID_ATI, PCI_ANY_ID, - PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_hpet_bugs }, {} }; diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 351f9c0fea1f..7494999141b3 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -35,7 +35,6 @@ unsigned long hpet_address; u8 hpet_blockid; /* OS timer block num */ u8 hpet_msi_disable; -u8 hpet_readback_cmp; #ifdef CONFIG_PCI_MSI static unsigned long hpet_num_timers; @@ -395,23 +394,27 @@ static int hpet_next_event(unsigned long delta, * at that point and we would wait for the next hpet interrupt * forever. We found out that reading the CMP register back * forces the transfer so we can rely on the comparison with - * the counter register below. + * the counter register below. If the read back from the + * compare register does not match the value we programmed + * then we might have a real hardware problem. We can not do + * much about it here, but at least alert the user/admin with + * a prominent warning. * - * That works fine on those ATI chipsets, but on newer Intel - * chipsets (ICH9...) this triggers due to an erratum: Reading - * the comparator immediately following a write is returning - * the old value. + * An erratum on some chipsets (ICH9,..), results in + * comparator read immediately following a write returning old + * value. Workaround for this is to read this value second + * time, when first read returns old value. * - * We restrict the read back to the affected ATI chipsets (set - * by quirks) and also run it with hpet=verbose for debugging - * purposes. + * In fact the write to the comparator register is delayed up + * to two HPET cycles so the workaround we tried to restrict + * the readback to those known to be borked ATI chipsets + * failed miserably. So we give up on optimizations forever + * and penalize all HPET incarnations unconditionally. */ - if (hpet_readback_cmp || hpet_verbose) { - u32 cmp = hpet_readl(HPET_Tn_CMP(timer)); - - if (cmp != cnt) + if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) { + if (hpet_readl(HPET_Tn_CMP(timer)) != cnt) printk_once(KERN_WARNING - "hpet: compare register read back failed.\n"); + "hpet: compare register read back failed.\n"); } return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; @@ -503,7 +506,7 @@ static int hpet_assign_irq(struct hpet_dev *dev) { unsigned int irq; - irq = create_irq(); + irq = create_irq_nr(0, -1); if (!irq) return -EINVAL; diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index a474ec37c32f..ff15c9dcc25d 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -206,11 +206,27 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp) int arch_bp_generic_fields(int x86_len, int x86_type, int *gen_len, int *gen_type) { - /* Len */ - switch (x86_len) { - case X86_BREAKPOINT_LEN_X: + /* Type */ + switch (x86_type) { + case X86_BREAKPOINT_EXECUTE: + if (x86_len != X86_BREAKPOINT_LEN_X) + return -EINVAL; + + *gen_type = HW_BREAKPOINT_X; *gen_len = sizeof(long); + return 0; + case X86_BREAKPOINT_WRITE: + *gen_type = HW_BREAKPOINT_W; break; + case X86_BREAKPOINT_RW: + *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; + break; + default: + return -EINVAL; + } + + /* Len */ + switch (x86_len) { case X86_BREAKPOINT_LEN_1: *gen_len = HW_BREAKPOINT_LEN_1; break; @@ -229,21 +245,6 @@ int arch_bp_generic_fields(int x86_len, int x86_type, return -EINVAL; } - /* Type */ - switch (x86_type) { - case X86_BREAKPOINT_EXECUTE: - *gen_type = HW_BREAKPOINT_X; - break; - case X86_BREAKPOINT_WRITE: - *gen_type = HW_BREAKPOINT_W; - break; - case X86_BREAKPOINT_RW: - *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; - break; - default: - return -EINVAL; - } - return 0; } @@ -316,9 +317,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) ret = -EINVAL; switch (info->len) { - case X86_BREAKPOINT_LEN_X: - align = sizeof(long) -1; - break; case X86_BREAKPOINT_LEN_1: align = 0; break; diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c index a874495b3673..e2a595257390 100644 --- a/arch/x86/kernel/trampoline.c +++ b/arch/x86/kernel/trampoline.c @@ -45,8 +45,7 @@ void __init setup_trampoline_page_table(void) /* Copy kernel address range */ clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY, swapper_pg_dir + KERNEL_PGD_BOUNDARY, - min_t(unsigned long, KERNEL_PGD_PTRS, - KERNEL_PGD_BOUNDARY)); + KERNEL_PGD_PTRS); /* Initialize low mappings */ clone_pgd_range(trampoline_pg_dir, diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index d632934cb638..26a863a9c2a8 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -655,7 +655,7 @@ void restore_sched_clock_state(void) local_irq_save(flags); - get_cpu_var(cyc2ns_offset) = 0; + __get_cpu_var(cyc2ns_offset) = 0; offset = cyc2ns_suspend - sched_clock(); for_each_possible_cpu(cpu) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b38bd8b92aa6..66ca98aafdd6 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1870,17 +1870,16 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - u64 old = c->dst.orig_val; + u64 old = c->dst.orig_val64; if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { - c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); ctxt->eflags &= ~EFLG_ZF; } else { - c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) | - (u32) c->regs[VCPU_REGS_RBX]; + c->dst.val64 = ((u64)c->regs[VCPU_REGS_RCX] << 32) | + (u32) c->regs[VCPU_REGS_RBX]; ctxt->eflags |= EFLG_ZF; } @@ -2616,7 +2615,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) c->src.valptr, c->src.bytes); if (rc != X86EMUL_CONTINUE) goto done; - c->src.orig_val = c->src.val; + c->src.orig_val64 = c->src.val64; } if (c->src2.type == OP_MEM) { diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 8d10c063d7f2..4b7b73ce2098 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -64,6 +64,9 @@ static void pic_unlock(struct kvm_pic *s) if (!found) found = s->kvm->bsp_vcpu; + if (!found) + return; + kvm_vcpu_kick(found); } } diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index ffed06871c5c..63c314502993 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h @@ -43,7 +43,6 @@ struct kvm_kpic_state { u8 irr; /* interrupt request register */ u8 imr; /* interrupt mask register */ u8 isr; /* interrupt service register */ - u8 isr_ack; /* interrupt ack detection */ u8 priority_add; /* highest irq priority */ u8 irq_base; u8 read_reg_select; @@ -56,6 +55,7 @@ struct kvm_kpic_state { u8 init4; /* true if 4 byte init */ u8 elcr; /* PIIX edge/trigger selection */ u8 elcr_mask; + u8 isr_ack; /* interrupt ack detection */ struct kvm_pic *pics_state; }; diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 9257510b4836..9d5f55848455 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -324,9 +324,8 @@ static void lguest_load_gdt(const struct desc_ptr *desc) } /* - * For a single GDT entry which changes, we do the lazy thing: alter our GDT, - * then tell the Host to reload the entire thing. This operation is so rare - * that this naive implementation is reasonable. + * For a single GDT entry which changes, we simply change our copy and + * then tell the host about it. */ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, const void *desc, int type) @@ -338,9 +337,13 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, } /* - * OK, I lied. There are three "thread local storage" GDT entries which change + * There are three "thread local storage" GDT entries which change * on every context switch (these three entries are how glibc implements - * __thread variables). So we have a hypercall specifically for this case. + * __thread variables). As an optimization, we have a hypercall + * specifically for this case. + * + * Wouldn't it be nicer to have a general LOAD_GDT_ENTRIES hypercall + * which took a range of entries? */ static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) { diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 84e236ce76ba..72fc70cf6184 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c @@ -74,7 +74,7 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) /* * Map 'pfn' using fixed map 'type' and protections 'prot' */ -void * +void __iomem * iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) { /* @@ -86,12 +86,12 @@ iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC)) prot = PAGE_KERNEL_UC_MINUS; - return kmap_atomic_prot_pfn(pfn, type, prot); + return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, type, prot); } EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); void -iounmap_atomic(void *kvaddr, enum km_type type) +iounmap_atomic(void __iomem *kvaddr, enum km_type type) { unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index f6b48f6c5951..009b819f48d0 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -568,8 +568,13 @@ static int __init init_sysfs(void) int error; error = sysdev_class_register(&oprofile_sysclass); - if (!error) - error = sysdev_register(&device_oprofile); + if (error) + return error; + + error = sysdev_register(&device_oprofile); + if (error) + sysdev_class_unregister(&oprofile_sysclass); + return error; } @@ -580,8 +585,10 @@ static void exit_sysfs(void) } #else -#define init_sysfs() do { } while (0) -#define exit_sysfs() do { } while (0) + +static inline int init_sysfs(void) { return 0; } +static inline void exit_sysfs(void) { } + #endif /* CONFIG_PM */ static int __init p4_init(char **cpu_type) @@ -664,7 +671,9 @@ static int __init ppro_init(char **cpu_type) case 14: *cpu_type = "i386/core"; break; - case 15: case 23: + case 0x0f: + case 0x16: + case 0x17: *cpu_type = "i386/core_2"; break; case 0x1a: @@ -695,6 +704,8 @@ int __init op_nmi_init(struct oprofile_operations *ops) char *cpu_type = NULL; int ret = 0; + using_nmi = 0; + if (!cpu_has_apic) return -ENODEV; @@ -774,7 +785,10 @@ int __init op_nmi_init(struct oprofile_operations *ops) mux_init(ops); - init_sysfs(); + ret = init_sysfs(); + if (ret) + return ret; + using_nmi = 1; printk(KERN_INFO "oprofile: using NMI interrupt.\n"); return 0; |