diff options
-rw-r--r-- | arch/x86/kernel/kprobes.c | 12 | ||||
-rw-r--r-- | arch/x86/mm/Makefile_32 | 2 | ||||
-rw-r--r-- | arch/x86/mm/Makefile_64 | 2 | ||||
-rw-r--r-- | arch/x86/mm/extable.c | 62 | ||||
-rw-r--r-- | arch/x86/mm/extable_32.c | 35 | ||||
-rw-r--r-- | arch/x86/mm/extable_64.c | 34 |
6 files changed, 65 insertions, 82 deletions
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 8de82c8cedd6..7848bf74e2ab 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -904,19 +904,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
904 | * In case the user-specified fault handler returned | 904 | * In case the user-specified fault handler returned |
905 | * zero, try to fix up. | 905 | * zero, try to fix up. |
906 | */ | 906 | */ |
907 | #ifdef CONFIG_X86_64 | ||
908 | { | ||
909 | const struct exception_table_entry *fixup; | ||
910 | fixup = search_exception_tables(regs->ip); | ||
911 | if (fixup) { | ||
912 | regs->ip = fixup->fixup; | ||
913 | return 1; | ||
914 | } | ||
915 | } | ||
916 | #else | ||
917 | if (fixup_exception(regs)) | 907 | if (fixup_exception(regs)) |
918 | return 1; | 908 | return 1; |
919 | #endif | 909 | |
920 | /* | 910 | /* |
921 | * fixup routine could not handle it, | 911 | * fixup routine could not handle it, |
922 | * Let do_page_fault() fix it. | 912 | * Let do_page_fault() fix it. |
diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32 index a01aca79dc69..6a5e981981f7 100644 --- a/arch/x86/mm/Makefile_32 +++ b/arch/x86/mm/Makefile_32 | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux i386-specific parts of the memory manager. | 2 | # Makefile for the linux i386-specific parts of the memory manager. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap.o | 5 | obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable.o pageattr_32.o mmap.o |
6 | 6 | ||
7 | obj-$(CONFIG_NUMA) += discontig_32.o | 7 | obj-$(CONFIG_NUMA) += discontig_32.o |
8 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 8 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64 index b5a74486c3aa..09c997fe5856 100644 --- a/arch/x86/mm/Makefile_64 +++ b/arch/x86/mm/Makefile_64 | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux x86_64-specific parts of the memory manager. | 2 | # Makefile for the linux x86_64-specific parts of the memory manager. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap.o | 5 | obj-y := init_64.o fault_64.o ioremap_64.o extable.o pageattr_64.o mmap.o |
6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
7 | obj-$(CONFIG_NUMA) += numa_64.o | 7 | obj-$(CONFIG_NUMA) += numa_64.o |
8 | obj-$(CONFIG_K8_NUMA) += k8topology_64.o | 8 | obj-$(CONFIG_K8_NUMA) += k8topology_64.o |
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c new file mode 100644 index 000000000000..7e8db53528a7 --- /dev/null +++ b/arch/x86/mm/extable.c | |||
@@ -0,0 +1,62 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/spinlock.h> | ||
3 | #include <asm/uaccess.h> | ||
4 | |||
5 | |||
6 | int fixup_exception(struct pt_regs *regs) | ||
7 | { | ||
8 | const struct exception_table_entry *fixup; | ||
9 | |||
10 | #ifdef CONFIG_PNPBIOS | ||
11 | if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) { | ||
12 | extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; | ||
13 | extern u32 pnp_bios_is_utter_crap; | ||
14 | pnp_bios_is_utter_crap = 1; | ||
15 | printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n"); | ||
16 | __asm__ volatile( | ||
17 | "movl %0, %%esp\n\t" | ||
18 | "jmp *%1\n\t" | ||
19 | : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip)); | ||
20 | panic("do_trap: can't hit this"); | ||
21 | } | ||
22 | #endif | ||
23 | |||
24 | fixup = search_exception_tables(regs->ip); | ||
25 | if (fixup) { | ||
26 | regs->ip = fixup->fixup; | ||
27 | return 1; | ||
28 | } | ||
29 | |||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | #ifdef CONFIG_X86_64 | ||
34 | /* | ||
35 | * Need to defined our own search_extable on X86_64 to work around | ||
36 | * a B stepping K8 bug. | ||
37 | */ | ||
38 | const struct exception_table_entry * | ||
39 | search_extable(const struct exception_table_entry *first, | ||
40 | const struct exception_table_entry *last, | ||
41 | unsigned long value) | ||
42 | { | ||
43 | /* B stepping K8 bug */ | ||
44 | if ((value >> 32) == 0) | ||
45 | value |= 0xffffffffUL << 32; | ||
46 | |||
47 | while (first <= last) { | ||
48 | const struct exception_table_entry *mid; | ||
49 | long diff; | ||
50 | |||
51 | mid = (last - first) / 2 + first; | ||
52 | diff = mid->insn - value; | ||
53 | if (diff == 0) | ||
54 | return mid; | ||
55 | else if (diff < 0) | ||
56 | first = mid+1; | ||
57 | else | ||
58 | last = mid-1; | ||
59 | } | ||
60 | return NULL; | ||
61 | } | ||
62 | #endif | ||
diff --git a/arch/x86/mm/extable_32.c b/arch/x86/mm/extable_32.c deleted file mode 100644 index 41685461f8b2..000000000000 --- a/arch/x86/mm/extable_32.c +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/i386/mm/extable.c | ||
3 | */ | ||
4 | |||
5 | #include <linux/module.h> | ||
6 | #include <linux/spinlock.h> | ||
7 | #include <asm/uaccess.h> | ||
8 | |||
9 | int fixup_exception(struct pt_regs *regs) | ||
10 | { | ||
11 | const struct exception_table_entry *fixup; | ||
12 | |||
13 | #ifdef CONFIG_PNPBIOS | ||
14 | if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) | ||
15 | { | ||
16 | extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; | ||
17 | extern u32 pnp_bios_is_utter_crap; | ||
18 | pnp_bios_is_utter_crap = 1; | ||
19 | printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n"); | ||
20 | __asm__ volatile( | ||
21 | "movl %0, %%esp\n\t" | ||
22 | "jmp *%1\n\t" | ||
23 | : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip)); | ||
24 | panic("do_trap: can't hit this"); | ||
25 | } | ||
26 | #endif | ||
27 | |||
28 | fixup = search_exception_tables(regs->ip); | ||
29 | if (fixup) { | ||
30 | regs->ip = fixup->fixup; | ||
31 | return 1; | ||
32 | } | ||
33 | |||
34 | return 0; | ||
35 | } | ||
diff --git a/arch/x86/mm/extable_64.c b/arch/x86/mm/extable_64.c deleted file mode 100644 index 79ac6e7100af..000000000000 --- a/arch/x86/mm/extable_64.c +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/x86_64/mm/extable.c | ||
3 | */ | ||
4 | |||
5 | #include <linux/module.h> | ||
6 | #include <linux/spinlock.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <asm/uaccess.h> | ||
9 | |||
10 | /* Simple binary search */ | ||
11 | const struct exception_table_entry * | ||
12 | search_extable(const struct exception_table_entry *first, | ||
13 | const struct exception_table_entry *last, | ||
14 | unsigned long value) | ||
15 | { | ||
16 | /* Work around a B stepping K8 bug */ | ||
17 | if ((value >> 32) == 0) | ||
18 | value |= 0xffffffffUL << 32; | ||
19 | |||
20 | while (first <= last) { | ||
21 | const struct exception_table_entry *mid; | ||
22 | long diff; | ||
23 | |||
24 | mid = (last - first) / 2 + first; | ||
25 | diff = mid->insn - value; | ||
26 | if (diff == 0) | ||
27 | return mid; | ||
28 | else if (diff < 0) | ||
29 | first = mid+1; | ||
30 | else | ||
31 | last = mid-1; | ||
32 | } | ||
33 | return NULL; | ||
34 | } | ||