summaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-11-05 17:52:25 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2010-11-05 17:52:25 +0100
commit0660a9b16ad502874de3e793875fa23eed7b038a (patch)
treed0181e31d7dd616e16defd3b1b4fcd867e26e78f /arch/tile/kernel
parentleds-net5501: taints kernel, add license (diff)
parentarch/tile: mark "hardwall" device as non-seekable (diff)
downloadlinux-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.c10
-rw-r--r--arch/tile/kernel/early_printk.c2
-rw-r--r--arch/tile/kernel/hardwall.c6
-rw-r--r--arch/tile/kernel/irq.c4
-rw-r--r--arch/tile/kernel/machine_kexec.c6
-rw-r--r--arch/tile/kernel/messaging.c2
-rw-r--r--arch/tile/kernel/ptrace.c39
-rw-r--r--arch/tile/kernel/reboot.c6
-rw-r--r--arch/tile/kernel/setup.c8
-rw-r--r--arch/tile/kernel/signal.c9
-rw-r--r--arch/tile/kernel/smp.c2
-rw-r--r--arch/tile/kernel/time.c8
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(&copyregs, 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, &current->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();