Skip to content

Commit

Permalink
x86, 64-bit: Move K8 B step iret fixup to fault entry asm
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Brian Gerst authored and Ingo Molnar committed Oct 12, 2009
1 parent f3834b9 commit ae24ffe
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 35 deletions.
1 change: 0 additions & 1 deletion arch/x86/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 8 additions & 3 deletions arch/x86/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
31 changes: 0 additions & 31 deletions arch/x86/mm/extable.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit ae24ffe

Please sign in to comment.