summaryrefslogtreecommitdiff
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2010-10-06 16:31:32 -0700
committerColin Cross <ccross@android.com>2010-10-06 16:32:09 -0700
commit98959c85632cde43fc83ba1b709f767fc3b8a4ee (patch)
treebe7912bc7cd8c2aab86922da933439ff951ab602 /arch/arm/kernel
parent5c4a97667fdf6705d6c9f9e4b42dd7deb4da6978 (diff)
parentdf5ac72e83df9fd8d735d40d5be464d4b66d6074 (diff)
Merge branch 'android-2.6.36' into android-tegra-2.6.36
Conflicts: drivers/input/touchscreen/Kconfig Change-Id: Ifc75266e258f9513d78c47c12e2f1de1d2344f02
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/debug.S2
-rw-r--r--arch/arm/kernel/process.c73
-rw-r--r--arch/arm/kernel/signal.c9
-rw-r--r--arch/arm/kernel/traps.c6
4 files changed, 87 insertions, 3 deletions
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index a38b4879441d..90ecfa32a226 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -22,7 +22,7 @@
#if defined(CONFIG_DEBUG_ICEDCC)
@@ debug using ARM EmbeddedICE DCC channel
-#if defined(CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V7)
.macro addruart, rx, tmp
.endm
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 69141f0b8388..3161faf3d2e8 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -245,6 +245,77 @@ void machine_restart(char *cmd)
arm_pm_restart(reboot_mode, cmd);
}
+/*
+ * dump a block of kernel memory from around the given address
+ */
+static void show_data(unsigned long addr, int nbytes, const char *name)
+{
+ int i, j;
+ int nlines;
+ u32 *p;
+
+ /*
+ * don't attempt to dump non-kernel addresses or
+ * values that are probably just small negative numbers
+ */
+ if (addr < PAGE_OFFSET || addr > -256UL)
+ return;
+
+ printk("\n%s: %#lx:\n", name, addr);
+
+ /*
+ * round address down to a 32 bit boundary
+ * and always dump a multiple of 32 bytes
+ */
+ p = (u32 *)(addr & ~(sizeof(u32) - 1));
+ nbytes += (addr & (sizeof(u32) - 1));
+ nlines = (nbytes + 31) / 32;
+
+
+ for (i = 0; i < nlines; i++) {
+ /*
+ * just display low 16 bits of address to keep
+ * each line of the dump < 80 characters
+ */
+ printk("%04lx ", (unsigned long)p & 0xffff);
+ for (j = 0; j < 8; j++) {
+ u32 data;
+ if (probe_kernel_address(p, data)) {
+ printk(" ********");
+ } else {
+ printk(" %08x", data);
+ }
+ ++p;
+ }
+ printk("\n");
+ }
+}
+
+static void show_extra_register_data(struct pt_regs *regs, int nbytes)
+{
+ mm_segment_t fs;
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ show_data(regs->ARM_pc - nbytes, nbytes * 2, "PC");
+ show_data(regs->ARM_lr - nbytes, nbytes * 2, "LR");
+ show_data(regs->ARM_sp - nbytes, nbytes * 2, "SP");
+ show_data(regs->ARM_ip - nbytes, nbytes * 2, "IP");
+ show_data(regs->ARM_fp - nbytes, nbytes * 2, "FP");
+ show_data(regs->ARM_r0 - nbytes, nbytes * 2, "R0");
+ show_data(regs->ARM_r1 - nbytes, nbytes * 2, "R1");
+ show_data(regs->ARM_r2 - nbytes, nbytes * 2, "R2");
+ show_data(regs->ARM_r3 - nbytes, nbytes * 2, "R3");
+ show_data(regs->ARM_r4 - nbytes, nbytes * 2, "R4");
+ show_data(regs->ARM_r5 - nbytes, nbytes * 2, "R5");
+ show_data(regs->ARM_r6 - nbytes, nbytes * 2, "R6");
+ show_data(regs->ARM_r7 - nbytes, nbytes * 2, "R7");
+ show_data(regs->ARM_r8 - nbytes, nbytes * 2, "R8");
+ show_data(regs->ARM_r9 - nbytes, nbytes * 2, "R9");
+ show_data(regs->ARM_r10 - nbytes, nbytes * 2, "R10");
+ set_fs(fs);
+}
+
void __show_regs(struct pt_regs *regs)
{
unsigned long flags;
@@ -304,6 +375,8 @@ void __show_regs(struct pt_regs *regs)
printk("Control: %08x%s\n", ctrl, buf);
}
#endif
+
+ show_extra_register_data(regs, 128);
}
void show_regs(struct pt_regs * regs)
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 907d5a620bca..15c46d27ca27 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -602,6 +602,14 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
static inline void setup_syscall_restart(struct pt_regs *regs)
{
+ if (regs->ARM_ORIG_r0 == -ERESTARTNOHAND ||
+ regs->ARM_ORIG_r0 == -ERESTARTSYS ||
+ regs->ARM_ORIG_r0 == -ERESTARTNOINTR ||
+ regs->ARM_ORIG_r0 == -ERESTART_RESTARTBLOCK) {
+ /* the syscall cannot be safely restarted, return -EINTR instead */
+ regs->ARM_r0 = -EINTR;
+ return;
+ }
regs->ARM_r0 = regs->ARM_ORIG_r0;
regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
}
@@ -734,6 +742,7 @@ static void do_signal(struct pt_regs *regs, int syscall)
*/
if (syscall) {
if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) {
+ regs->ARM_r0 = -EAGAIN; /* prevent multiple restarts */
if (thumb_mode(regs)) {
regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
regs->ARM_pc -= 2;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index cda78d59aa31..17c5649340ad 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -454,7 +454,9 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
if (end > vma->vm_end)
end = vma->vm_end;
- flush_cache_user_range(vma, start, end);
+ up_read(&mm->mmap_sem);
+ flush_cache_user_range(start, end);
+ return;
}
up_read(&mm->mmap_sem);
}
@@ -524,7 +526,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
if (has_tls_reg) {
asm ("mcr p15, 0, %0, c13, c0, 3"
: : "r" (regs->ARM_r0));
- } else {
+ } /*else*/ {
/*
* User space must never try to access this directly.
* Expect your app to break eventually if you do so.