This commit was manufactured by cvs2svn to create branch
[linux-2.6.git] / arch / i386 / mm / fault.c
index debed47..60206e1 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 #include <asm/desc.h>
+#include <asm/tlbflush.h>
 
 extern void die(const char *,struct pt_regs *,long);
 
@@ -103,8 +104,17 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
        if (seg & (1<<2)) {
                /* Must lock the LDT while reading it. */
                down(&current->mm->context.sem);
+#if 1
+               /* horrible hack for 4/4 disabled kernels.
+                  I'm not quite sure what the TLB flush is good for,
+                  it's mindlessly copied from the read_ldt code */
+               __flush_tlb_global();
+               desc = kmap(current->mm->context.ldt_pages[(seg&~7)/PAGE_SIZE]);
+               desc = (void *)desc + ((seg & ~7) % PAGE_SIZE);
+#else
                desc = current->mm->context.ldt;
                desc = (void *)desc + (seg & ~7);
+#endif
        } else {
                /* Must disable preemption while reading the GDT. */
                desc = (u32 *)&cpu_gdt_table[get_cpu()];
@@ -117,6 +127,9 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
                 (desc[1] & 0xff000000);
 
        if (seg & (1<<2)) { 
+#if 1
+               kunmap((void *)((unsigned long)desc & PAGE_MASK));
+#endif
                up(&current->mm->context.sem);
        } else
                put_cpu();
@@ -247,6 +260,17 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
         * (error_code & 4) == 0, and that the fault was not a
         * protection error (error_code & 1) == 0.
         */
+#ifdef CONFIG_X86_4G
+       /*
+        * On 4/4 all kernels faults are either bugs, vmalloc or prefetch
+        */
+       /* If it's vm86 fall through */
+       if (unlikely(!(regs->eflags & VM_MASK) && ((regs->xcs & 3) == 0))) {
+               if (error_code & 3)
+                       goto bad_area_nosemaphore;
+               goto vmalloc_fault;
+       }
+#else
        if (unlikely(address >= TASK_SIZE)) { 
                if (!(error_code & 5))
                        goto vmalloc_fault;
@@ -256,6 +280,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                 */
                goto bad_area_nosemaphore;
        } 
+#endif
 
        mm = tsk->mm;