patch-2.4.22 linux-2.4.22/arch/mips/mm/fault.c
Next file: linux-2.4.22/arch/mips/mm/init.c
Previous file: linux-2.4.22/arch/mips/mm/cex-sb1.S
Back to the patch index
Back to the overall index
- Lines: 59
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/mips/mm/fault.c
- Orig date:
2002-11-28 15:53:10.000000000 -0800
diff -urN linux-2.4.21/arch/mips/mm/fault.c linux-2.4.22/arch/mips/mm/fault.c
@@ -19,6 +19,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/version.h>
+#include <linux/vt_kern.h>
#include <asm/branch.h>
#include <asm/hardirq.h>
@@ -159,7 +160,6 @@
bad_area:
up_read(&mm->mmap_sem);
-bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
if (user_mode(regs)) {
tsk->thread.cp0_badvaddr = address;
@@ -246,26 +246,31 @@
/*
* Synchronize this task's top level page-table
* with the 'reference' page table.
+ *
+ * Do _not_ use "tsk" here. We might be inside
+ * an interrupt in the middle of a task switch..
*/
- int offset = pgd_index(address);
+ int offset = __pgd_offset(address);
pgd_t *pgd, *pgd_k;
pmd_t *pmd, *pmd_k;
+ pte_t *pte_k;
- pgd = tsk->active_mm->pgd + offset;
+ pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset;
pgd_k = init_mm.pgd + offset;
- if (!pgd_present(*pgd)) {
- if (!pgd_present(*pgd_k))
- goto bad_area_nosemaphore;
- set_pgd(pgd, *pgd_k);
- return;
- }
+ if (!pgd_present(*pgd_k))
+ goto no_context;
+ set_pgd(pgd, *pgd_k);
pmd = pmd_offset(pgd, address);
pmd_k = pmd_offset(pgd_k, address);
-
- if (pmd_present(*pmd) || !pmd_present(*pmd_k))
- goto bad_area_nosemaphore;
+ if (!pmd_present(*pmd_k))
+ goto no_context;
set_pmd(pmd, *pmd_k);
+
+ pte_k = pte_offset(pmd_k, address);
+ if (!pte_present(*pte_k))
+ goto no_context;
+ return;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)