]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/avr32/kernel/entry-avr32b.S
avr32: Cover the kernel page tables in the user PGDs
[linux-2.6-omap-h63xx.git] / arch / avr32 / kernel / entry-avr32b.S
index 3cdd7071f35e131379e4b1d14adbb15e089d3af6..2b398cae110c839fc5b3c3be3d9d7a48fcf3a2ec 100644 (file)
@@ -98,10 +98,6 @@ tlb_miss_common:
        mfsr    r0, SYSREG_TLBEAR
        mfsr    r1, SYSREG_PTBR
 
-       /* Is it the vmalloc space? */
-       bld     r0, 31
-       brcs    handle_vmalloc_miss
-
        /*
         * First level lookup: The PGD contains virtual pointers to
         * the second-level page tables, but they may be NULL if not
@@ -143,15 +139,13 @@ pgtbl_lookup:
        tlbmiss_restore
        rete
 
-handle_vmalloc_miss:
-       /* Simply do the lookup in init's page table */
-       mov     r1, lo(swapper_pg_dir)
-       orh     r1, hi(swapper_pg_dir)
-       rjmp    pgtbl_lookup
-
        /* The slow path of the TLB miss handler */
        .align  2
 page_table_not_present:
+       /* Do we need to synchronize with swapper_pg_dir? */
+       bld     r0, 31
+       brcs    sync_with_swapper_pg_dir
+
 page_not_present:
        tlbmiss_restore
        sub     sp, 4
@@ -162,6 +156,34 @@ page_not_present:
        rcall   do_page_fault
        rjmp    ret_from_exception
 
+       .align  2
+sync_with_swapper_pg_dir:
+       /*
+        * If swapper_pg_dir contains a non-NULL second-level page
+        * table pointer, copy it into the current PGD. If not, we
+        * must handle it as a full-blown page fault.
+        *
+        * Jumping back to pgtbl_lookup causes an unnecessary lookup,
+        * but it is guaranteed to be a cache hit, it won't happen
+        * very often, and we absolutely do not want to sacrifice any
+        * performance in the fast path in order to improve this.
+        */
+       mov     r1, lo(swapper_pg_dir)
+       orh     r1, hi(swapper_pg_dir)
+       ld.w    r3, r1[r2 << 2]
+       cp.w    r3, 0
+       breq    page_not_present
+       mfsr    r1, SYSREG_PTBR
+       st.w    r1[r2 << 2], r3
+       rjmp    pgtbl_lookup
+
+       /*
+        * We currently have two bytes left at this point until we
+        * crash into the system call handler...
+        *
+        * Don't worry, the assembler will let us know.
+        */
+
 
        /* ---                    System Call                    --- */