diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-05 17:52:25 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-05 17:52:25 +0100 |
commit | 0660a9b16ad502874de3e793875fa23eed7b038a (patch) | |
tree | d0181e31d7dd616e16defd3b1b4fcd867e26e78f /arch/tile/kernel | |
parent | leds-net5501: taints kernel, add license (diff) | |
parent | arch/tile: mark "hardwall" device as non-seekable (diff) | |
download | linux-0660a9b16ad502874de3e793875fa23eed7b038a.tar.xz linux-0660a9b16ad502874de3e793875fa23eed7b038a.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
arch/tile: mark "hardwall" device as non-seekable
asm-generic/stat.h: support 64-bit file time_t for stat()
arch/tile: don't allow user code to set the PL via ptrace or signal return
arch/tile: correct double syscall restart for nested signals
arch/tile: avoid __must_check warning on one strict_strtol check
arch/tile: bomb raw_local_irq_ to arch_local_irq_
arch/tile: complete migration to new kmap_atomic scheme
Diffstat (limited to 'arch/tile/kernel')
-rw-r--r-- | arch/tile/kernel/compat.c | 10 | ||||
-rw-r--r-- | arch/tile/kernel/early_printk.c | 2 | ||||
-rw-r--r-- | arch/tile/kernel/hardwall.c | 6 | ||||
-rw-r--r-- | arch/tile/kernel/irq.c | 4 | ||||
-rw-r--r-- | arch/tile/kernel/machine_kexec.c | 6 | ||||
-rw-r--r-- | arch/tile/kernel/messaging.c | 2 | ||||
-rw-r--r-- | arch/tile/kernel/ptrace.c | 39 | ||||
-rw-r--r-- | arch/tile/kernel/reboot.c | 6 | ||||
-rw-r--r-- | arch/tile/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/tile/kernel/signal.c | 9 | ||||
-rw-r--r-- | arch/tile/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/tile/kernel/time.c | 8 |
12 files changed, 56 insertions, 46 deletions
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c index 77739cdd9462..67617a05e602 100644 --- a/arch/tile/kernel/compat.c +++ b/arch/tile/kernel/compat.c @@ -148,11 +148,11 @@ long tile_compat_sys_msgrcv(int msqid, #define compat_sys_readahead sys32_readahead #define compat_sys_sync_file_range compat_sys_sync_file_range2 -/* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */ -#define compat_sys_stat64 sys_newstat -#define compat_sys_lstat64 sys_newlstat -#define compat_sys_fstat64 sys_newfstat -#define compat_sys_fstatat64 sys_newfstatat +/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */ +#define compat_sys_stat64 sys_stat64 +#define compat_sys_lstat64 sys_lstat64 +#define compat_sys_fstat64 sys_fstat64 +#define compat_sys_fstatat64 sys_fstatat64 /* The native sys_ptrace dynamically handles compat binaries. */ #define compat_sys_ptrace sys_ptrace diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c index 2c54fd43a8a0..493a0e66d916 100644 --- a/arch/tile/kernel/early_printk.c +++ b/arch/tile/kernel/early_printk.c @@ -54,7 +54,7 @@ void early_printk(const char *fmt, ...) void early_panic(const char *fmt, ...) { va_list ap; - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); va_start(ap, fmt); early_printk("Kernel panic - not syncing: "); early_vprintk(fmt, ap); diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 1e54a7843410..e910530436e6 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c @@ -151,12 +151,12 @@ enum direction_protect { static void enable_firewall_interrupts(void) { - raw_local_irq_unmask_now(INT_UDN_FIREWALL); + arch_local_irq_unmask_now(INT_UDN_FIREWALL); } static void disable_firewall_interrupts(void) { - raw_local_irq_mask_now(INT_UDN_FIREWALL); + arch_local_irq_mask_now(INT_UDN_FIREWALL); } /* Set up hardwall on this cpu based on the passed hardwall_info. */ @@ -768,13 +768,13 @@ static int hardwall_release(struct inode *inode, struct file *file) } static const struct file_operations dev_hardwall_fops = { + .open = nonseekable_open, .unlocked_ioctl = hardwall_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = hardwall_compat_ioctl, #endif .flush = hardwall_flush, .release = hardwall_release, - .llseek = noop_llseek, }; static struct cdev hardwall_dev; diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index e63917687e99..128805ef8f2c 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c @@ -26,7 +26,7 @@ #define IS_HW_CLEARED 1 /* - * The set of interrupts we enable for raw_local_irq_enable(). + * The set of interrupts we enable for arch_local_irq_enable(). * This is initialized to have just a single interrupt that the kernel * doesn't actually use as a sentinel. During kernel init, * interrupts are added as the kernel gets prepared to support them. @@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void) /* Enable interrupt delivery. */ unmask_irqs(~0UL); #if CHIP_HAS_IPI() - raw_local_irq_unmask(INT_IPI_K); + arch_local_irq_unmask(INT_IPI_K); #endif } diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c index ba7a265d6179..0d8b9e933487 100644 --- a/arch/tile/kernel/machine_kexec.c +++ b/arch/tile/kernel/machine_kexec.c @@ -182,13 +182,13 @@ static void kexec_find_and_set_command_line(struct kimage *image) if ((entry & IND_SOURCE)) { void *va = - kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0); + kmap_atomic_pfn(entry >> PAGE_SHIFT); r = kexec_bn2cl(va); if (r) { command_line = r; break; } - kunmap_atomic(va, KM_USER0); + kunmap_atomic(va); } } @@ -198,7 +198,7 @@ static void kexec_find_and_set_command_line(struct kimage *image) hverr = hv_set_command_line( (HV_VirtAddr) command_line, strlen(command_line)); - kunmap_atomic(command_line, KM_USER0); + kunmap_atomic(command_line); } else { pr_info("%s: no command line found; making empty\n", __func__); diff --git a/arch/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c index 997e3933f726..0858ee6b520f 100644 --- a/arch/tile/kernel/messaging.c +++ b/arch/tile/kernel/messaging.c @@ -34,7 +34,7 @@ void __cpuinit init_messaging(void) panic("hv_register_message_state: error %d", rc); /* Make sure downcall interrupts will be enabled. */ - raw_local_irq_unmask(INT_INTCTRL_K); + arch_local_irq_unmask(INT_INTCTRL_K); } void hv_message_intr(struct pt_regs *regs, int intnum) diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 9cd29884c09f..e92e40527d6d 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c @@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request, { unsigned long __user *datap = (long __user __force *)data; unsigned long tmp; - int i; long ret = -EIO; - unsigned long *childregs; char *childreg; + struct pt_regs copyregs; + int ex1_offset; switch (request) { @@ -80,6 +80,16 @@ long arch_ptrace(struct task_struct *child, long request, if (addr >= PTREGS_SIZE) break; childreg = (char *)task_pt_regs(child) + addr; + + /* Guard against overwrites of the privilege level. */ + ex1_offset = PTREGS_OFFSET_EX1; +#if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN) + if (is_compat_task()) /* point at low word */ + ex1_offset += sizeof(compat_long_t); +#endif + if (addr == ex1_offset) + data = PL_ICS_EX1(USER_PL, EX1_ICS(data)); + #ifdef CONFIG_COMPAT if (is_compat_task()) { if (addr & (sizeof(compat_long_t)-1)) @@ -96,26 +106,19 @@ long arch_ptrace(struct task_struct *child, long request, break; case PTRACE_GETREGS: /* Get all registers from the child. */ - if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) - break; - childregs = (long *)task_pt_regs(child); - for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); - ++i) { - ret = __put_user(childregs[i], &datap[i]); - if (ret != 0) - break; + if (copy_to_user(datap, task_pt_regs(child), + sizeof(struct pt_regs)) == 0) { + ret = 0; } break; case PTRACE_SETREGS: /* Set all registers in the child. */ - if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) - break; - childregs = (long *)task_pt_regs(child); - for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); - ++i) { - ret = __get_user(childregs[i], &datap[i]); - if (ret != 0) - break; + if (copy_from_user(©regs, datap, + sizeof(struct pt_regs)) == 0) { + copyregs.ex1 = + PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1)); + *task_pt_regs(child) = copyregs; + ret = 0; } break; diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c index acd86d20beba..baa3d905fee2 100644 --- a/arch/tile/kernel/reboot.c +++ b/arch/tile/kernel/reboot.c @@ -27,7 +27,7 @@ void machine_halt(void) { warn_early_printk(); - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); smp_send_stop(); hv_halt(); } @@ -35,14 +35,14 @@ void machine_halt(void) void machine_power_off(void) { warn_early_printk(); - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); smp_send_stop(); hv_power_off(); } void machine_restart(char *cmd) { - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); smp_send_stop(); hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); } diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index ae51cad12da0..fb0b3cbeae14 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -868,14 +868,14 @@ void __cpuinit setup_cpu(int boot) /* Allow asynchronous TLB interrupts. */ #if CHIP_HAS_TILE_DMA() - raw_local_irq_unmask(INT_DMATLB_MISS); - raw_local_irq_unmask(INT_DMATLB_ACCESS); + arch_local_irq_unmask(INT_DMATLB_MISS); + arch_local_irq_unmask(INT_DMATLB_ACCESS); #endif #if CHIP_HAS_SN_PROC() - raw_local_irq_unmask(INT_SNITLB_MISS); + arch_local_irq_unmask(INT_SNITLB_MISS); #endif #ifdef __tilegx__ - raw_local_irq_unmask(INT_SINGLE_STEP_K); + arch_local_irq_unmask(INT_SINGLE_STEP_K); #endif /* diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index fb28e85ae3ae..687719d4abd1 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c @@ -71,6 +71,9 @@ int restore_sigcontext(struct pt_regs *regs, for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) err |= __get_user(regs->regs[i], &sc->gregs[i]); + /* Ensure that the PL is always set to USER_PL. */ + regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); + regs->faultnum = INT_SWINT_1_SIGRETURN; err |= __get_user(*pr0, &sc->gregs[0]); @@ -330,7 +333,7 @@ void do_signal(struct pt_regs *regs) current_thread_info()->status &= ~TS_RESTORE_SIGMASK; } - return; + goto done; } /* Did we come from a system call? */ @@ -358,4 +361,8 @@ void do_signal(struct pt_regs *regs) current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } + +done: + /* Avoid double syscall restart if there are nested signals. */ + regs->faultnum = INT_SWINT_1_SIGRETURN; } diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index 75255d90aff3..9575b37a8b75 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c @@ -115,7 +115,7 @@ static void smp_start_cpu_interrupt(void) static void smp_stop_cpu_interrupt(void) { set_cpu_online(smp_processor_id(), 0); - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); for (;;) asm("nap"); } diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index 6bed820e1421..f2e156e44692 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -132,7 +132,7 @@ static int tile_timer_set_next_event(unsigned long ticks, { BUG_ON(ticks > MAX_TICK); __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); - raw_local_irq_unmask_now(INT_TILE_TIMER); + arch_local_irq_unmask_now(INT_TILE_TIMER); return 0; } @@ -143,7 +143,7 @@ static int tile_timer_set_next_event(unsigned long ticks, static void tile_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - raw_local_irq_mask_now(INT_TILE_TIMER); + arch_local_irq_mask_now(INT_TILE_TIMER); } /* @@ -172,7 +172,7 @@ void __cpuinit setup_tile_timer(void) evt->cpumask = cpumask_of(smp_processor_id()); /* Start out with timer not firing. */ - raw_local_irq_mask_now(INT_TILE_TIMER); + arch_local_irq_mask_now(INT_TILE_TIMER); /* Register tile timer. */ clockevents_register_device(evt); @@ -188,7 +188,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num) * Mask the timer interrupt here, since we are a oneshot timer * and there are now by definition no events pending. */ - raw_local_irq_mask(INT_TILE_TIMER); + arch_local_irq_mask(INT_TILE_TIMER); /* Track time spent here in an interrupt context */ irq_enter(); |