git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
vserver 1.9.5.x5
[linux-2.6.git]
/
arch
/
sparc64
/
mm
/
fault.c
diff --git
a/arch/sparc64/mm/fault.c
b/arch/sparc64/mm/fault.c
index
63b989f
..
45edb94
100644
(file)
--- a/
arch/sparc64/mm/fault.c
+++ b/
arch/sparc64/mm/fault.c
@@
-175,6
+175,7
@@
static void bad_kernel_pc(struct pt_regs *regs)
static unsigned int get_user_insn(unsigned long tpc)
{
pgd_t *pgdp = pgd_offset(current->mm, tpc);
static unsigned int get_user_insn(unsigned long tpc)
{
pgd_t *pgdp = pgd_offset(current->mm, tpc);
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep, pte;
unsigned long pa;
pmd_t *pmdp;
pte_t *ptep, pte;
unsigned long pa;
@@
-183,7
+184,10
@@
static unsigned int get_user_insn(unsigned long tpc)
if (pgd_none(*pgdp))
goto outret;
if (pgd_none(*pgdp))
goto outret;
- pmdp = pmd_offset(pgdp, tpc);
+ pudp = pud_offset(pgdp, tpc);
+ if (pud_none(*pudp))
+ goto outret;
+ pmdp = pmd_offset(pudp, tpc);
if (pmd_none(*pmdp))
goto outret;
if (pmd_none(*pmdp))
goto outret;
@@
-352,7
+356,7
@@
asmlinkage void do_sparc64_fault(struct pt_regs *regs)
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_
interrupt
() || !mm)
+ if (in_
atomic
() || !mm)
goto intr_or_no_mm;
if (test_thread_flag(TIF_32BIT)) {
goto intr_or_no_mm;
if (test_thread_flag(TIF_32BIT)) {
@@
-361,7
+365,15
@@
asmlinkage void do_sparc64_fault(struct pt_regs *regs)
address &= 0xffffffff;
}
address &= 0xffffffff;
}
- down_read(&mm->mmap_sem);
+ if (!down_read_trylock(&mm->mmap_sem)) {
+ if ((regs->tstate & TSTATE_PRIV) &&
+ !search_exception_tables(regs->tpc)) {
+ insn = get_fault_insn(regs, insn);
+ goto handle_kernel_fault;
+ }
+ down_read(&mm->mmap_sem);
+ }
+
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@
-446,16
+458,18
@@
good_area:
}
switch (handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE))) {
}
switch (handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE))) {
- case
1
:
+ case
VM_FAULT_MINOR
:
current->min_flt++;
break;
current->min_flt++;
break;
- case
2
:
+ case
VM_FAULT_MAJOR
:
current->maj_flt++;
break;
current->maj_flt++;
break;
- case
0
:
+ case
VM_FAULT_SIGBUS
:
goto do_sigbus;
goto do_sigbus;
-
default
:
+
case VM_FAULT_OOM
:
goto out_of_memory;
goto out_of_memory;
+ default:
+ BUG();
}
up_read(&mm->mmap_sem);
}
up_read(&mm->mmap_sem);