diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-10-31 10:12:45 -0600 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-10-31 19:56:26 -0600 |
commit | bb730cc30135e5c4b568233429ef5593aa35f2e8 (patch) | |
tree | 5dc9a1a915babe594994359f754d48ae00649485 /arch/x86/mm | |
parent | acd21d848252d8ea06b19066b675391d012b1737 (diff) |
Revert "x86/mm: Expand the exception table logic to allow new handling options"
This reverts commit fcf5e5198b447969ed2a56ec335dae3c695a6b46 which is
548acf19234dbda5a52d5a8e7e205af46e9da840 upstream.
Cc: Tony Luck <tony.luck@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/extable.c | 100 | ||||
-rw-r--r-- | arch/x86/mm/fault.c | 2 |
2 files changed, 29 insertions, 73 deletions
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 9dd7e4b7fcde..903ec1e9c326 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -3,9 +3,6 @@ #include <linux/sort.h> #include <asm/uaccess.h> -typedef bool (*ex_handler_t)(const struct exception_table_entry *, - struct pt_regs *, int); - static inline unsigned long ex_insn_addr(const struct exception_table_entry *x) { @@ -16,56 +13,11 @@ ex_fixup_addr(const struct exception_table_entry *x) { return (unsigned long)&x->fixup + x->fixup; } -static inline ex_handler_t -ex_fixup_handler(const struct exception_table_entry *x) -{ - return (ex_handler_t)((unsigned long)&x->handler + x->handler); -} - -bool ex_handler_default(const struct exception_table_entry *fixup, - struct pt_regs *regs, int trapnr) -{ - regs->ip = ex_fixup_addr(fixup); - return true; -} -EXPORT_SYMBOL(ex_handler_default); - -bool ex_handler_fault(const struct exception_table_entry *fixup, - struct pt_regs *regs, int trapnr) -{ - regs->ip = ex_fixup_addr(fixup); - regs->ax = trapnr; - return true; -} -EXPORT_SYMBOL_GPL(ex_handler_fault); - -bool ex_handler_ext(const struct exception_table_entry *fixup, - struct pt_regs *regs, int trapnr) -{ - /* Special hack for uaccess_err */ - current_thread_info()->uaccess_err = 1; - regs->ip = ex_fixup_addr(fixup); - return true; -} -EXPORT_SYMBOL(ex_handler_ext); - -bool ex_has_fault_handler(unsigned long ip) -{ - const struct exception_table_entry *e; - ex_handler_t handler; - - e = search_exception_tables(ip); - if (!e) - return false; - handler = ex_fixup_handler(e); - - return handler == ex_handler_fault; -} -int fixup_exception(struct pt_regs *regs, int trapnr) +int fixup_exception(struct pt_regs *regs) { - const struct exception_table_entry *e; - ex_handler_t handler; + const struct exception_table_entry *fixup; + unsigned long new_ip; #ifdef CONFIG_PNPBIOS if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) { @@ -81,34 +33,42 @@ int fixup_exception(struct pt_regs *regs, int trapnr) } #endif - e = search_exception_tables(regs->ip); - if (!e) - return 0; + fixup = search_exception_tables(regs->ip); + if (fixup) { + new_ip = ex_fixup_addr(fixup); + + if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) { + /* Special hack for uaccess_err */ + current_thread_info()->uaccess_err = 1; + new_ip -= 0x7ffffff0; + } + regs->ip = new_ip; + return 1; + } - handler = ex_fixup_handler(e); - return handler(e, regs, trapnr); + return 0; } /* Restricted version used during very early boot */ int __init early_fixup_exception(unsigned long *ip) { - const struct exception_table_entry *e; + const struct exception_table_entry *fixup; unsigned long new_ip; - ex_handler_t handler; - e = search_exception_tables(*ip); - if (!e) - return 0; + fixup = search_exception_tables(*ip); + if (fixup) { + new_ip = ex_fixup_addr(fixup); - new_ip = ex_fixup_addr(e); - handler = ex_fixup_handler(e); + if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) { + /* uaccess handling not supported during early boot */ + return 0; + } - /* special handling not supported during early boot */ - if (handler != ex_handler_default) - return 0; + *ip = new_ip; + return 1; + } - *ip = new_ip; - return 1; + return 0; } /* @@ -173,8 +133,6 @@ void sort_extable(struct exception_table_entry *start, i += 4; p->fixup += i; i += 4; - p->handler += i; - i += 4; } sort(start, finish - start, sizeof(struct exception_table_entry), @@ -187,8 +145,6 @@ void sort_extable(struct exception_table_entry *start, i += 4; p->fixup -= i; i += 4; - p->handler -= i; - i += 4; } } diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 03898aea6e0f..e830c71a1323 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -663,7 +663,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, int sig; /* Are we prepared to handle this kernel fault? */ - if (fixup_exception(regs, X86_TRAP_PF)) { + if (fixup_exception(regs)) { /* * Any interrupt that takes a fault gets the fixup. This makes * the below recursive fault logic only apply to a faults from |