x86/ras tree changes for v3.19
Subsystems (7)
Linus,
Please pull the latest x86-ras-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-ras-for-linus
# HEAD: c7c9b3929b6a57ad47ab4021c77e46f7ff21c007 x86/mce: Spell "panicked" correctly
The biggest change in this cycle is better support for UCNA (UnCorrected No Action) events:
"Handle all uncorrected error reports in the same way (soft
offline the page). We used to only do that for SRAO (software recoverable action optional) machine checks, but it makes sense to also do it for UCNA (UnCorrected No Action) logs found by CMCI or polling."
plus various x86 MCE handling updates and fixes.
out-of-topic modifications in x86-ras-for-linus:
--------------------------------------------------
drivers/acpi/apei/ghes.c # 8f7c31f6cd49: GHES: Make ghes_estatus_cach
# 8d21d4c91efa: APEI, GHES: Cleanup unnecess
drivers/edac/mce_amd.h # e3480271f592: x86, mce, severity: Extend t
mm/memory-failure.c # 6dc52cbe0b18: RAS, HWPOISON: Fix wrong err
Thanks,
Ingo
------------------>
Borislav Petkov (3):
GHES: Make ghes_estatus_caches static
x86, MCE, AMD: Drop software-defined bank in error thresholding x86/mce: Spell "panicked" correctly
Chen Yucong (6):
x86, MCE, AMD: Use macros to compute bank MSRs
x86, MCE, AMD: Correct thresholding error logging
x86, MCE, AMD: Move invariant code out from loop body
x86, MCE, AMD: Assign interrupt handler only when bank supports it
x86, mce, severity: Extend the the mce_severity mechanism to handle UCNA/DEFERRED error x86, mce: Support memory error recovery for both UCNA and Deferred error in machine_check_poll
Chen, Gong (2):
APEI, GHES: Cleanup unnecessary function for lockless list RAS, HWPOISON: Fix wrong error recovery status
arch/x86/include/asm/mce.h | 5 ++- arch/x86/kernel/cpu/mcheck/mce-internal.h | 4 +- arch/x86/kernel/cpu/mcheck/mce-severity.c | 23 +++++++--- arch/x86/kernel/cpu/mcheck/mce.c | 72 +++++++++++++++++++++++++------ arch/x86/kernel/cpu/mcheck/mce_amd.c | 54 ++++++++++++----------- drivers/acpi/apei/ghes.c | 20 ++------- drivers/edac/mce_amd.h | 3 -- mm/memory-failure.c | 2 +- 8 files changed, 116 insertions(+), 67 deletions(-)
arch/x86/include/asm/mce.h +4 -1
@@ -34,6 +34,10 @@#define MCI_STATUS_S (1ULL<<56)/* Signaled machine check */ #define MCI_STATUS_AR (1ULL<<55)/* Action required */ +/* AMD-specific bits */ +#define MCI_STATUS_DEFERRED (1ULL<<44)/* declare an uncorrected error */ +#define MCI_STATUS_POISON (1ULL<<43)/* access poisonous data */ +/* * Note that the full MCACOD field of IA32_MCi_STATUS MSR is * bits 15:0. But bit 12 is the 'F' bit, defined for corrected
@@ -78,7 +82,6 @@/* Software defined banks */ #define MCE_EXTENDED_BANK 128#define MCE_THERMAL_BANK (MCE_EXTENDED_BANK + 0) -#define K8_MCE_THRESHOLD_BASE (MCE_EXTENDED_BANK + 1)#define MCE_LOG_LEN 32#define MCE_LOG_SIGNATURE "MACHINECHECK"
arch/x86/kernel/cpu/mcheck/mce-internal.h +3 -1
@@ -3,6 +3,8 @@enum severity_level {MCE_NO_SEVERITY , +MCE_DEFERRED_SEVERITY , +MCE_UCNA_SEVERITY =MCE_DEFERRED_SEVERITY ,MCE_KEEP_SEVERITY ,MCE_SOME_SEVERITY ,MCE_AO_SEVERITY ,
@@ -21,7 +23,7 @@ struct mce_bank {char attrname[ATTR_LEN ];/* attribute name */ }; -int mce_severity (struct mce *a,int tolerant,char **msg); +int mce_severity (struct mce *a,int tolerant,char **msg,bool is_excp);struct dentry *mce_get_debugfs_dir (void );extern struct mce_bank *mce_banks;
arch/x86/kernel/cpu/mcheck/mce-severity.c +17 -6
@@ -31,6 +31,7 @@enum context {IN_KERNEL =1 ,IN_USER =2 };enum ser {SER_REQUIRED =1 ,NO_SER =2 }; +enum exception {EXCP_CONTEXT =1 ,NO_EXCP =2 }; static struct severity { u64 mask;
@@ -40,6 +41,7 @@ static struct severity {unsigned char mcgres;unsigned char ser;unsigned char context; +unsigned char excp;unsigned char covered;char *msg; } severities[] = {
@@ -48,6 +50,8 @@ static struct severity {#define USER .context = IN_USER#define SER .ser = SER_REQUIRED#define NOSER .ser = NO_SER +#define EXCP .excp = EXCP_CONTEXT +#define NOEXCP .excp = NO_EXCP#define BITCLR (x) .mask = x, .result = 0#define BITSET (x) .mask = x, .result = x#define MCGMASK (x, y) .mcgmask = x, .mcgres = y
@@ -62,7 +66,7 @@ static struct severity { ),MCESEV (NO ,"Not enabled" , -BITCLR (MCI_STATUS_EN ) +EXCP ,BITCLR (MCI_STATUS_EN ) ), MCESEV( PANIC, "Processor context corrupt",
@@ -71,16 +75,20 @@ static struct severity {/* When MCIP is not set something is very confused */ MCESEV (PANIC ,"MCIP not set in MCA handler" , -MCGMASK (MCG_STATUS_MCIP ,0 ) +EXCP ,MCGMASK (MCG_STATUS_MCIP ,0 ) ),/* Neither return not error IP -- no chance to recover -> PANIC */ MCESEV (PANIC ,"Neither restart nor error IP" , -MCGMASK (MCG_STATUS_RIPV |MCG_STATUS_EIPV ,0 ) +EXCP ,MCGMASK (MCG_STATUS_RIPV |MCG_STATUS_EIPV ,0 ) ),MCESEV (PANIC ,"In kernel and no restart IP" , -KERNEL ,MCGMASK (MCG_STATUS_RIPV ,0 ) +EXCP ,KERNEL ,MCGMASK (MCG_STATUS_RIPV ,0 ) + ), +MCESEV ( +DEFERRED ,"Deferred error" , +NOSER ,MASK (MCI_STATUS_UC |MCI_STATUS_DEFERRED |MCI_STATUS_POISON ,MCI_STATUS_DEFERRED ) ), MCESEV( KEEP, "Corrected error",
@@ -89,7 +97,7 @@ static struct severity {/* ignore OVER for UCNA */ MCESEV ( -KEEP ,"Uncorrected no action required" , +UCNA ,"Uncorrected no action required" ,SER ,MASK (MCI_UC_SAR ,MCI_STATUS_UC ) ), MCESEV(
@@ -178,8 +186,9 @@ static int error_context(struct mce *m)return ((m->cs &3 ) ==3 ) ?IN_USER :IN_KERNEL ; } -int mce_severity (struct mce *m,int tolerant,char **msg) +int mce_severity (struct mce *m,int tolerant,char **msg,bool is_excp) { +enum exception excp = (is_excp ?EXCP_CONTEXT :NO_EXCP );enum context ctx =error_context (m);struct severity *s;
@@ -194,6 +203,8 @@ int mce_severity(struct mce *m, int tolerant, char **msg)continue ;if (s->context && ctx != s->context)continue ; +if (s->excp && excp != s->excp) +continue ;if (msg) *msg = s->msg; s->covered =1 ;
arch/x86/kernel/cpu/mcheck/mce.c +60 -12
143 lines not on this page · raw message
arch/x86/kernel/cpu/mcheck/mce_amd.c +28 -26
100 lines not on this page · raw message
drivers/acpi/apei/ghes.c +3 -17
@@ -128,7 +128,7 @@ static DEFINE_SPINLOCK(ghes_ioremap_lock_irq);static struct gen_pool *ghes_estatus_pool;static unsigned long ghes_estatus_pool_size_request; -struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE ]; +static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE ];static atomic_t ghes_estatus_cache_alloced;static int ghes_ioremap_init (void )
@@ -738,20 +738,6 @@ static LIST_HEAD(ghes_nmi);static int ghes_panic_timeout__read_mostly =30 ; -static struct llist_node *llist_nodes_reverse (struct llist_node *llnode) -{ -struct llist_node *next, *tail =NULL ; - -while (llnode) { - next = llnode->next; - llnode->next = tail; - tail = llnode; - llnode = next; - } - -return tail; -} -static void ghes_proc_in_irq (struct irq_work *irq_work) {struct llist_node *llnode, *next;
@@ -765,7 +751,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)* Because the time order of estatus in list is reversed, * revert it back to proper order. */ - llnode =llist_nodes_reverse (llnode); + llnode =llist_reverse_order (llnode);while (llnode) { next = llnode->next; estatus_node = llist_entry(llnode, struct ghes_estatus_node,
@@ -798,7 +784,7 @@ static void ghes_print_queued_estatus(void)* Because the time order of estatus in list is reversed, * revert it back to proper order. */ - llnode =llist_nodes_reverse (llnode); + llnode =llist_reverse_order (llnode);while (llnode) { estatus_node = llist_entry(llnode, struct ghes_estatus_node, llnode);
drivers/edac/mce_amd.h +0 -3
@@ -32,9 +32,6 @@#define R4 (x) (((x) >> 4) & 0xf)#define R4_MSG (x) ((R4(x) < 9) ? rrrr_msgs[R4(x)] : "Wrong R4!") -#define MCI_STATUS_DEFERRED BIT_64(44) -#define MCI_STATUS_POISON BIT_64(43) -extern const char *const pp_msgs[];enum tt_ids {
mm/memory-failure.c +1 -1
@@ -860,7 +860,6 @@ static int page_action(struct page_state *ps, struct page *p,int count; result = ps->action (p, pfn); -action_result (pfn, ps->msg, result); count =page_count (p) -1 ;if (ps->action == me_swapcache_dirty && result ==DELAYED )
@@ -871,6 +870,7 @@ static int page_action(struct page_state *ps, struct page *p, pfn, ps->msg, count); result =FAILED ; } +action_result (pfn, ps->msg, result);/* Could do more checks here if page looks ok */ /*