git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Pull release into acpica branch
[pandora-kernel.git]
/
arch
/
arm
/
kernel
/
traps.c
diff --git
a/arch/arm/kernel/traps.c
b/arch/arm/kernel/traps.c
index
f6de76e
..
45e9ea6
100644
(file)
--- a/
arch/arm/kernel/traps.c
+++ b/
arch/arm/kernel/traps.c
@@
-198,25
+198,16
@@
void show_stack(struct task_struct *tsk, unsigned long *sp)
barrier();
}
barrier();
}
-DEFINE_SPINLOCK(die_lock);
-
-/*
- * This function is protected against re-entrancy.
- */
-NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
{
{
- struct task_struct *tsk =
current
;
+ struct task_struct *tsk =
thread->task
;
static int die_counter;
static int die_counter;
- console_verbose();
- spin_lock_irq(&die_lock);
- bust_spinlocks(1);
-
printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
print_modules();
__show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
print_modules();
__show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
- tsk->comm, tsk->pid, t
sk->thread_info
+ 1);
+ tsk->comm, tsk->pid, t
hread
+ 1);
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
@@
-224,7
+215,21
@@
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
dump_backtrace(regs, tsk);
dump_instr(regs);
}
dump_backtrace(regs, tsk);
dump_instr(regs);
}
+}
+
+DEFINE_SPINLOCK(die_lock);
+
+/*
+ * This function is protected against re-entrancy.
+ */
+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+{
+ struct thread_info *thread = current_thread_info();
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+ __die(str, err, thread, regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
@@
-345,7
+350,9
@@
static int bad_syscall(int n, struct pt_regs *regs)
struct thread_info *thread = current_thread_info();
siginfo_t info;
struct thread_info *thread = current_thread_info();
siginfo_t info;
- if (current->personality != PER_LINUX && thread->exec_domain->handler) {
+ if (current->personality != PER_LINUX &&
+ current->personality != PER_LINUX_32BIT &&
+ thread->exec_domain->handler) {
thread->exec_domain->handler(n, regs);
return regs->ARM_r0;
}
thread->exec_domain->handler(n, regs);
return regs->ARM_r0;
}
@@
-481,29
+488,33
@@
asmlinkage int arm_syscall(int no, struct pt_regs *regs)
unsigned long addr = regs->ARM_r2;
struct mm_struct *mm = current->mm;
pgd_t *pgd; pmd_t *pmd; pte_t *pte;
unsigned long addr = regs->ARM_r2;
struct mm_struct *mm = current->mm;
pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+ spinlock_t *ptl;
regs->ARM_cpsr &= ~PSR_C_BIT;
regs->ARM_cpsr &= ~PSR_C_BIT;
-
spin_lock(&mm->page_table_lock
);
+
down_read(&mm->mmap_sem
);
pgd = pgd_offset(mm, addr);
if (!pgd_present(*pgd))
goto bad_access;
pmd = pmd_offset(pgd, addr);
if (!pmd_present(*pmd))
goto bad_access;
pgd = pgd_offset(mm, addr);
if (!pgd_present(*pgd))
goto bad_access;
pmd = pmd_offset(pgd, addr);
if (!pmd_present(*pmd))
goto bad_access;
- pte = pte_offset_map(pmd, addr);
- if (!pte_present(*pte) || !pte_write(*pte))
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ if (!pte_present(*pte) || !pte_write(*pte)) {
+ pte_unmap_unlock(pte, ptl);
goto bad_access;
goto bad_access;
+ }
val = *(unsigned long *)addr;
val -= regs->ARM_r0;
if (val == 0) {
*(unsigned long *)addr = regs->ARM_r1;
regs->ARM_cpsr |= PSR_C_BIT;
}
val = *(unsigned long *)addr;
val -= regs->ARM_r0;
if (val == 0) {
*(unsigned long *)addr = regs->ARM_r1;
regs->ARM_cpsr |= PSR_C_BIT;
}
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
+ up_read(&mm->mmap_sem);
return val;
bad_access:
return val;
bad_access:
-
spin_unlock(&mm->page_table_lock
);
+
up_read(&mm->mmap_sem
);
/* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
return -1;
/* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
return -1;