Re: [PATCH] x86: unify extable_{32|64}.c
* Masami Hiramatsu <[EMAIL PROTECTED]> wrote: > Hi Harvey, > > Harvey Harrison wrote: > > Introduce fixup_exception() on X86_64 and use it in kprobes to > > eliminate an #ifdef. > > > > Only X86_64 needs search_extable() due to a stepping bug. > > It's a good work! > If you can work on it, please add a prototype declaration of > fixup_exception() in asm-x86/uaccess_64.h too. FYI, i've already added this to x86.git, it was needed for 64-bit to build fine. Ingo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] x86: unify extable_{32|64}.c
Hi Harvey, Harvey Harrison wrote: > Introduce fixup_exception() on X86_64 and use it in kprobes to > eliminate an #ifdef. > > Only X86_64 needs search_extable() due to a stepping bug. It's a good work! If you can work on it, please add a prototype declaration of fixup_exception() in asm-x86/uaccess_64.h too. > > Signed-off-by: Harvey Harrison <[EMAIL PROTECTED]> > --- > arch/x86/kernel/kprobes.c | 12 + > arch/x86/mm/Makefile_32 |2 +- > arch/x86/mm/Makefile_64 |2 +- > arch/x86/mm/extable.c | 62 > + > arch/x86/mm/extable_32.c | 35 - > 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 1a0d96d..045a45e 100644 > --- a/arch/x86/kernel/kprobes.c > +++ b/arch/x86/kernel/kprobes.c > @@ -902,19 +902,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, > int trapnr) >* In case the user-specified fault handler returned >* zero, try to fix up. >*/ > -#ifdef CONFIG_X86_64 > - { > - const struct exception_table_entry *fixup; > - fixup = search_exception_tables(regs->ip); > - if (fixup) { > - regs->ip = fixup->fixup; > - return 1; > - } > - } > -#else > if (fixup_exception(regs)) > return 1; > -#endif > + > /* >* fixup routine could not handle it, >* Let do_page_fault() fix it. > diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32 > index a01aca7..6a5e981 100644 > --- a/arch/x86/mm/Makefile_32 > +++ b/arch/x86/mm/Makefile_32 > @@ -2,7 +2,7 @@ > # Makefile for the linux i386-specific parts of the memory manager. > # > > -obj-y:= init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o > pageattr_32.o mmap.o > +obj-y:= init_32.o pgtable_32.o fault_32.o ioremap_32.o extable.o > pageattr_32.o mmap.o > > obj-$(CONFIG_NUMA) += discontig_32.o > obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o > diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64 > index b5a7448..09c997f 100644 > --- a/arch/x86/mm/Makefile_64 > +++ b/arch/x86/mm/Makefile_64 > @@ -2,7 +2,7 @@ > # Makefile for the linux x86_64-specific parts of the memory manager. > # > > -obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o > pageattr_64.o mmap.o > +obj-y := init_64.o fault_64.o ioremap_64.o extable.o pageattr_64.o > mmap.o > obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o > obj-$(CONFIG_NUMA) += numa_64.o > 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 000..7e8db53 > --- /dev/null > +++ b/arch/x86/mm/extable.c > @@ -0,0 +1,62 @@ > +#include > +#include > +#include > + > + > +int fixup_exception(struct pt_regs *regs) > +{ > + const struct exception_table_entry *fixup; > + > +#ifdef CONFIG_PNPBIOS > + if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) { > + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; > + extern u32 pnp_bios_is_utter_crap; > + pnp_bios_is_utter_crap = 1; > + printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n"); > + __asm__ volatile( > + "movl %0, %%esp\n\t" > + "jmp *%1\n\t" > + : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip)); > + panic("do_trap: can't hit this"); > + } > +#endif > + > + fixup = search_exception_tables(regs->ip); > + if (fixup) { > + regs->ip = fixup->fixup; > + return 1; > + } > + > + 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 |= 0xUL << 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 > diff --git a/arch/x86/mm/extable_32.c b/arch/x86/mm/extable_32.c > deleted file mode 100644 > index 4168546..000 > ---
Re: [PATCH] x86: unify extable_{32|64}.c
* Harvey Harrison <[EMAIL PROTECTED]> wrote: > Introduce fixup_exception() on X86_64 and use it in kprobes to > eliminate an #ifdef. > > Only X86_64 needs search_extable() due to a stepping bug. thanks, applied. Ingo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] x86: unify extable_{32|64}.c
Introduce fixup_exception() on X86_64 and use it in kprobes to eliminate an #ifdef. Only X86_64 needs search_extable() due to a stepping bug. Signed-off-by: Harvey Harrison <[EMAIL PROTECTED]> --- arch/x86/kernel/kprobes.c | 12 + arch/x86/mm/Makefile_32 |2 +- arch/x86/mm/Makefile_64 |2 +- arch/x86/mm/extable.c | 62 + arch/x86/mm/extable_32.c | 35 - 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 1a0d96d..045a45e 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -902,19 +902,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) * In case the user-specified fault handler returned * zero, try to fix up. */ -#ifdef CONFIG_X86_64 - { - const struct exception_table_entry *fixup; - fixup = search_exception_tables(regs->ip); - if (fixup) { - regs->ip = fixup->fixup; - return 1; - } - } -#else if (fixup_exception(regs)) return 1; -#endif + /* * fixup routine could not handle it, * Let do_page_fault() fix it. diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32 index a01aca7..6a5e981 100644 --- a/arch/x86/mm/Makefile_32 +++ b/arch/x86/mm/Makefile_32 @@ -2,7 +2,7 @@ # Makefile for the linux i386-specific parts of the memory manager. # -obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap.o +obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable.o pageattr_32.o mmap.o obj-$(CONFIG_NUMA) += discontig_32.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64 index b5a7448..09c997f 100644 --- a/arch/x86/mm/Makefile_64 +++ b/arch/x86/mm/Makefile_64 @@ -2,7 +2,7 @@ # Makefile for the linux x86_64-specific parts of the memory manager. # -obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap.o +obj-y := init_64.o fault_64.o ioremap_64.o extable.o pageattr_64.o mmap.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_NUMA) += numa_64.o 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 000..7e8db53 --- /dev/null +++ b/arch/x86/mm/extable.c @@ -0,0 +1,62 @@ +#include +#include +#include + + +int fixup_exception(struct pt_regs *regs) +{ + const struct exception_table_entry *fixup; + +#ifdef CONFIG_PNPBIOS + if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) { + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; + extern u32 pnp_bios_is_utter_crap; + pnp_bios_is_utter_crap = 1; + printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n"); + __asm__ volatile( + "movl %0, %%esp\n\t" + "jmp *%1\n\t" + : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip)); + panic("do_trap: can't hit this"); + } +#endif + + fixup = search_exception_tables(regs->ip); + if (fixup) { + regs->ip = fixup->fixup; + return 1; + } + + 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 |= 0xUL << 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 diff --git a/arch/x86/mm/extable_32.c b/arch/x86/mm/extable_32.c deleted file mode 100644 index 4168546..000 --- a/arch/x86/mm/extable_32.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/i386/mm/extable.c - */ - -#include -#include -#include - -int fixup_exception(struct pt_regs *regs) -{ - const struct exception_table_entry *fixup; - -#ifdef CONFIG_PNPBIOS - if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) - { - extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; -
[PATCH] x86: unify extable_{32|64}.c
Introduce fixup_exception() on X86_64 and use it in kprobes to eliminate an #ifdef. Only X86_64 needs search_extable() due to a stepping bug. Signed-off-by: Harvey Harrison [EMAIL PROTECTED] --- arch/x86/kernel/kprobes.c | 12 + arch/x86/mm/Makefile_32 |2 +- arch/x86/mm/Makefile_64 |2 +- arch/x86/mm/extable.c | 62 + arch/x86/mm/extable_32.c | 35 - 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 1a0d96d..045a45e 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -902,19 +902,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) * In case the user-specified fault handler returned * zero, try to fix up. */ -#ifdef CONFIG_X86_64 - { - const struct exception_table_entry *fixup; - fixup = search_exception_tables(regs-ip); - if (fixup) { - regs-ip = fixup-fixup; - return 1; - } - } -#else if (fixup_exception(regs)) return 1; -#endif + /* * fixup routine could not handle it, * Let do_page_fault() fix it. diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32 index a01aca7..6a5e981 100644 --- a/arch/x86/mm/Makefile_32 +++ b/arch/x86/mm/Makefile_32 @@ -2,7 +2,7 @@ # Makefile for the linux i386-specific parts of the memory manager. # -obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap.o +obj-y := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable.o pageattr_32.o mmap.o obj-$(CONFIG_NUMA) += discontig_32.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64 index b5a7448..09c997f 100644 --- a/arch/x86/mm/Makefile_64 +++ b/arch/x86/mm/Makefile_64 @@ -2,7 +2,7 @@ # Makefile for the linux x86_64-specific parts of the memory manager. # -obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap.o +obj-y := init_64.o fault_64.o ioremap_64.o extable.o pageattr_64.o mmap.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_NUMA) += numa_64.o 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 000..7e8db53 --- /dev/null +++ b/arch/x86/mm/extable.c @@ -0,0 +1,62 @@ +#include linux/module.h +#include linux/spinlock.h +#include asm/uaccess.h + + +int fixup_exception(struct pt_regs *regs) +{ + const struct exception_table_entry *fixup; + +#ifdef CONFIG_PNPBIOS + if (unlikely(SEGMENT_IS_PNP_CODE(regs-cs))) { + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; + extern u32 pnp_bios_is_utter_crap; + pnp_bios_is_utter_crap = 1; + printk(KERN_CRIT PNPBIOS fault.. attempting recovery.\n); + __asm__ volatile( + movl %0, %%esp\n\t + jmp *%1\n\t + : : g (pnp_bios_fault_esp), g (pnp_bios_fault_eip)); + panic(do_trap: can't hit this); + } +#endif + + fixup = search_exception_tables(regs-ip); + if (fixup) { + regs-ip = fixup-fixup; + return 1; + } + + 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 |= 0xUL 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 diff --git a/arch/x86/mm/extable_32.c b/arch/x86/mm/extable_32.c deleted file mode 100644 index 4168546..000 --- a/arch/x86/mm/extable_32.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/i386/mm/extable.c - */ - -#include linux/module.h -#include linux/spinlock.h -#include asm/uaccess.h - -int fixup_exception(struct pt_regs *regs) -{ - const struct exception_table_entry *fixup; - -#ifdef CONFIG_PNPBIOS - if (unlikely(SEGMENT_IS_PNP_CODE(regs-cs))) - { -
Re: [PATCH] x86: unify extable_{32|64}.c
* Harvey Harrison [EMAIL PROTECTED] wrote: Introduce fixup_exception() on X86_64 and use it in kprobes to eliminate an #ifdef. Only X86_64 needs search_extable() due to a stepping bug. thanks, applied. Ingo -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] x86: unify extable_{32|64}.c
Hi Harvey, Harvey Harrison wrote: Introduce fixup_exception() on X86_64 and use it in kprobes to eliminate an #ifdef. Only X86_64 needs search_extable() due to a stepping bug. It's a good work! If you can work on it, please add a prototype declaration of fixup_exception() in asm-x86/uaccess_64.h too. Signed-off-by: Harvey Harrison [EMAIL PROTECTED] --- arch/x86/kernel/kprobes.c | 12 + arch/x86/mm/Makefile_32 |2 +- arch/x86/mm/Makefile_64 |2 +- arch/x86/mm/extable.c | 62 + arch/x86/mm/extable_32.c | 35 - 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 1a0d96d..045a45e 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -902,19 +902,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) * In case the user-specified fault handler returned * zero, try to fix up. */ -#ifdef CONFIG_X86_64 - { - const struct exception_table_entry *fixup; - fixup = search_exception_tables(regs-ip); - if (fixup) { - regs-ip = fixup-fixup; - return 1; - } - } -#else if (fixup_exception(regs)) return 1; -#endif + /* * fixup routine could not handle it, * Let do_page_fault() fix it. diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32 index a01aca7..6a5e981 100644 --- a/arch/x86/mm/Makefile_32 +++ b/arch/x86/mm/Makefile_32 @@ -2,7 +2,7 @@ # Makefile for the linux i386-specific parts of the memory manager. # -obj-y:= init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap.o +obj-y:= init_32.o pgtable_32.o fault_32.o ioremap_32.o extable.o pageattr_32.o mmap.o obj-$(CONFIG_NUMA) += discontig_32.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64 index b5a7448..09c997f 100644 --- a/arch/x86/mm/Makefile_64 +++ b/arch/x86/mm/Makefile_64 @@ -2,7 +2,7 @@ # Makefile for the linux x86_64-specific parts of the memory manager. # -obj-y := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap.o +obj-y := init_64.o fault_64.o ioremap_64.o extable.o pageattr_64.o mmap.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_NUMA) += numa_64.o 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 000..7e8db53 --- /dev/null +++ b/arch/x86/mm/extable.c @@ -0,0 +1,62 @@ +#include linux/module.h +#include linux/spinlock.h +#include asm/uaccess.h + + +int fixup_exception(struct pt_regs *regs) +{ + const struct exception_table_entry *fixup; + +#ifdef CONFIG_PNPBIOS + if (unlikely(SEGMENT_IS_PNP_CODE(regs-cs))) { + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; + extern u32 pnp_bios_is_utter_crap; + pnp_bios_is_utter_crap = 1; + printk(KERN_CRIT PNPBIOS fault.. attempting recovery.\n); + __asm__ volatile( + movl %0, %%esp\n\t + jmp *%1\n\t + : : g (pnp_bios_fault_esp), g (pnp_bios_fault_eip)); + panic(do_trap: can't hit this); + } +#endif + + fixup = search_exception_tables(regs-ip); + if (fixup) { + regs-ip = fixup-fixup; + return 1; + } + + 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 |= 0xUL 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 diff --git a/arch/x86/mm/extable_32.c b/arch/x86/mm/extable_32.c deleted file mode 100644 index 4168546..000 --- a/arch/x86/mm/extable_32.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/i386/mm/extable.c - */ - -#include linux/module.h -#include
Re: [PATCH] x86: unify extable_{32|64}.c
* Masami Hiramatsu [EMAIL PROTECTED] wrote: Hi Harvey, Harvey Harrison wrote: Introduce fixup_exception() on X86_64 and use it in kprobes to eliminate an #ifdef. Only X86_64 needs search_extable() due to a stepping bug. It's a good work! If you can work on it, please add a prototype declaration of fixup_exception() in asm-x86/uaccess_64.h too. FYI, i've already added this to x86.git, it was needed for 64-bit to build fine. Ingo -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/