Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752589AbbKISlL (ORCPT ); Mon, 9 Nov 2015 13:41:11 -0500 Received: from mga11.intel.com ([192.55.52.93]:55257 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752162AbbKISlI (ORCPT ); Mon, 9 Nov 2015 13:41:08 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,266,1444719600"; d="scan'208";a="831959338" Message-Id: <5bf6f812a7dd2b619487c57987e29b3884c6c4ec.1447093568.git.tony.luck@intel.com> In-Reply-To: References: From: Tony Luck Date: Fri, 6 Nov 2015 12:57:03 -0800 Subject: [PATCH 1/3] x86, ras: Add new infrastructure for machine check fixup tables To: Borislav Petkov Cc: linux-kernel@vger.kernel.org, linux-edac@vger.kernel.org, x86@kernel.org Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4924 Lines: 148 Copy the existing page fault fixup mechanisms to create a new table to be used when fixing machine checks. Note: 1) At this time we only provide a macro to annotate assembly code 2) We assume all fixups will in code builtin to the kernel. Signed-off-by: Tony Luck --- arch/x86/include/asm/asm.h | 7 +++++++ arch/x86/include/asm/uaccess.h | 1 + arch/x86/mm/extable.c | 16 ++++++++++++++++ include/asm-generic/vmlinux.lds.h | 6 ++++++ include/linux/module.h | 1 + kernel/extable.c | 14 ++++++++++++++ 6 files changed, 45 insertions(+) diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 189679aba703..f2fa7973f18f 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -58,6 +58,13 @@ .long (to) - . + 0x7ffffff0 ; \ .popsection +# define _ASM_MCEXTABLE(from, to) \ + .pushsection "__mcex_table", "a" ; \ + .balign 8 ; \ + .long (from) - . ; \ + .long (to) - . ; \ + .popsection + # define _ASM_NOKPROBE(entry) \ .pushsection "_kprobe_blacklist","aw" ; \ _ASM_ALIGN ; \ diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index a8df874f3e88..b8231301a224 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -111,6 +111,7 @@ struct exception_table_entry { #define ARCH_HAS_SEARCH_EXTABLE extern int fixup_exception(struct pt_regs *regs); +extern int fixup_mcexception(struct pt_regs *regs); extern int early_fixup_exception(unsigned long *ip); /* diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 903ec1e9c326..5b328ae00365 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -49,6 +49,22 @@ int fixup_exception(struct pt_regs *regs) return 0; } +int fixup_mcexception(struct pt_regs *regs) +{ + const struct exception_table_entry *fixup; + unsigned long new_ip; + + fixup = search_mcexception_tables(regs->ip); + if (fixup) { + new_ip = ex_fixup_addr(fixup); + + regs->ip = new_ip; + return 1; + } + + return 0; +} + /* Restricted version used during very early boot */ int __init early_fixup_exception(unsigned long *ip) { diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 1781e54ea6d3..21bb20d1172a 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -473,6 +473,12 @@ VMLINUX_SYMBOL(__start___ex_table) = .; \ *(__ex_table) \ VMLINUX_SYMBOL(__stop___ex_table) = .; \ + } \ + . = ALIGN(align); \ + __mcex_table : AT(ADDR(__mcex_table) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___mcex_table) = .; \ + *(__mcex_table) \ + VMLINUX_SYMBOL(__stop___mcex_table) = .; \ } /* diff --git a/include/linux/module.h b/include/linux/module.h index 3a19c79918e0..ffecbfcc462c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -270,6 +270,7 @@ extern const typeof(name) __mod_##type##__##name##_device_table \ /* Given an address, look for it in the exception tables */ const struct exception_table_entry *search_exception_tables(unsigned long add); +const struct exception_table_entry *search_mcexception_tables(unsigned long a); struct notifier_block; diff --git a/kernel/extable.c b/kernel/extable.c index e820ccee9846..261c3e2816db 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -34,6 +34,8 @@ DEFINE_MUTEX(text_mutex); extern struct exception_table_entry __start___ex_table[]; extern struct exception_table_entry __stop___ex_table[]; +extern struct exception_table_entry __start___mcex_table[]; +extern struct exception_table_entry __stop___mcex_table[]; /* Cleared by build time tools if the table is already sorted. */ u32 __initdata __visible main_extable_sort_needed = 1; @@ -45,6 +47,8 @@ void __init sort_main_extable(void) pr_notice("Sorting __ex_table...\n"); sort_extable(__start___ex_table, __stop___ex_table); } + if (__stop___mcex_table > __start___mcex_table) + sort_extable(__start___mcex_table, __stop___mcex_table); } /* Given an address, look for it in the exception tables. */ @@ -58,6 +62,16 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr) return e; } +/* Given an address, look for it in the machine check exception tables. */ +const struct exception_table_entry *search_mcexception_tables( + unsigned long addr) +{ + const struct exception_table_entry *e; + + e = search_extable(__start___mcex_table, __stop___mcex_table-1, addr); + return e; +} + static inline int init_kernel_text(unsigned long addr) { if (addr >= (unsigned long)_sinittext && -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/