x86, 64-bit: Move K8 B step iret fixup to fault entry asm
authorBrian Gerst <brgerst@gmail.com>
Mon, 12 Oct 2009 14:18:23 +0000 (10:18 -0400)
committerIngo Molnar <mingo@elte.hu>
Mon, 12 Oct 2009 16:29:46 +0000 (18:29 +0200)
Move the handling of truncated %rip from an iret fault to the fault
entry path.

This allows x86-64 to use the standard search_extable() function.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jan Beulich <jbeulich@novell.com>
LKML-Reference: <1255357103-5418-1-git-send-email-brgerst@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/include/asm/uaccess.h
arch/x86/kernel/entry_64.S
arch/x86/mm/extable.c

index d2c6c930b491916843e76d2c6838e53b5890301b..abd3e0ea762ac739b054ddd1922efba71017a742 100644 (file)
@@ -570,7 +570,6 @@ extern struct movsl_mask {
 #ifdef CONFIG_X86_32
 # include "uaccess_32.h"
 #else
-# define ARCH_HAS_SEARCH_EXTABLE
 # include "uaccess_64.h"
 #endif
 
index b5c061f8f358489fee828e48b836d18c3bd6da79..af0f4b226dbeb6f405ce6d72afe62ff3e5db9832 100644 (file)
@@ -1491,12 +1491,17 @@ error_kernelspace:
        leaq irq_return(%rip),%rcx
        cmpq %rcx,RIP+8(%rsp)
        je error_swapgs
-       movl %ecx,%ecx  /* zero extend */
-       cmpq %rcx,RIP+8(%rsp)
-       je error_swapgs
+       movl %ecx,%eax  /* zero extend */
+       cmpq %rax,RIP+8(%rsp)
+       je bstep_iret
        cmpq $gs_change,RIP+8(%rsp)
        je error_swapgs
        jmp error_sti
+
+bstep_iret:
+       /* Fix truncated RIP */
+       movq %rcx,RIP+8(%rsp)
+       je error_swapgs
 END(error_entry)
 
 
index 61b41ca3b5a2ed4bbf1b9100fd870578885182ad..d0474ad2a6e528eb87ef0904edf9311fc035acf3 100644 (file)
@@ -35,34 +35,3 @@ int fixup_exception(struct pt_regs *regs)
 
        return 0;
 }
-
-#ifdef CONFIG_X86_64
-/*
- * Need to defined our own search_extable on X86_64 to work around
- * a B stepping K8 bug.
- */
-const struct exception_table_entry *
-search_extable(const struct exception_table_entry *first,
-              const struct exception_table_entry *last,
-              unsigned long value)
-{
-       /* B stepping K8 bug */
-       if ((value >> 32) == 0)
-               value |= 0xffffffffUL << 32;
-
-       while (first <= last) {
-               const struct exception_table_entry *mid;
-               long diff;
-
-               mid = (last - first) / 2 + first;
-               diff = mid->insn - value;
-               if (diff == 0)
-                       return mid;
-               else if (diff < 0)
-                       first = mid+1;
-               else
-                       last = mid-1;
-       }
-       return NULL;
-}
-#endif