x86: add IRQ context simulation in module mce-inject
PATCH RESEND 1/1 x86: add IRQ context simulation in module mce-inject
module mce-inject is an interface which is used by user space app such as mce-inject. According to it one can inject all kinds of error combinations into the kernel. In this way, one can check error condition coverage in the kernel. To satisify this needs, module mce-inject must simulate enough scenarios such as process context, IRQ context, even NMI context, to ensure related kernel codes are strong and reliable. In current implementation, IRQ context hasn't been simulated. This patch is for this purpose.
--- arch/x86/include/asm/mce.h | 9 ++++--- arch/x86/kernel/cpu/mcheck/mce-inject.c | 34 +++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-)
arch/x86/include/asm/mce.h +5 -4
@@ -50,10 +50,11 @@#define MCJ_CTX_MASK 3#define MCJ_CTX (flags) ((flags) & MCJ_CTX_MASK)#define MCJ_CTX_RANDOM 0/* inject context: random */ -#define MCJ_CTX_PROCESS 1/* inject context: process */ -#define MCJ_CTX_IRQ 2/* inject context: IRQ */ -#define MCJ_NMI_BROADCAST 4/* do NMI broadcasting */ -#define MCJ_EXCEPTION 8/* raise as exception */ +#define MCJ_CTX_PROCESS 0x1/* inject context: process */ +#define MCJ_CTX_IRQ 0x2/* inject context: IRQ */ +#define MCJ_NMI_BROADCAST 0x4/* do NMI broadcasting */ +#define MCJ_EXCEPTION 0x8/* raise as exception */ +#define MCJ_IRQ_BRAODCAST 0x10/* do IRQ broadcasting */ /* Fields are zero when not available */ struct mce {
arch/x86/kernel/cpu/mcheck/mce-inject.c +30 -4
@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/string.h> #include <linux/fs.h> +#include <linux/preempt.h> #include <linux/smp.h> #include <linux/notifier.h> #include <linux/kdebug.h>
@@ -92,6 +93,18 @@ static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)return NMI_HANDLED ; } +static void mce_irq_ipi (void *info) +{ +int cpu =smp_processor_id (); +struct mce *m = &__get_cpu_var (injectm); + +if (cpumask_test_cpu (cpu, mce_inject_cpumask) && + m->inject_flags &MCJ_EXCEPTION ) { +cpumask_clear_cpu (cpu, mce_inject_cpumask); +raise_exception (m,NULL ); + } +} +/* Inject mce on current CPU */ static int raise_local (void ) {
@@ -139,9 +152,10 @@ static void raise_mce(struct mce *m)return ;#ifdef CONFIG_X86_LOCAL_APIC -if (m->inject_flags &MCJ_NMI_BROADCAST ) { +if (m->inject_flags & (MCJ_IRQ_BRAODCAST |MCJ_NMI_BROADCAST )) {unsigned long start;int cpu; +get_online_cpus ();cpumask_copy (mce_inject_cpumask, cpu_online_mask);cpumask_clear_cpu (get_cpu (), mce_inject_cpumask);
@@ -151,13 +165,25 @@ static void raise_mce(struct mce *m) MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)cpumask_clear_cpu (cpu, mce_inject_cpumask); } -if (!cpumask_empty (mce_inject_cpumask)) - apic->send_IPI_mask (mce_inject_cpumask,NMI_VECTOR ); +if (!cpumask_empty (mce_inject_cpumask)) { +if (m->inject_flags &MCJ_IRQ_BRAODCAST ) { +/* +* don't wait because mce_irq_ipi is necessary +* to be sync with following raise_local +*/ +preempt_disable (); +smp_call_function_many (mce_inject_cpumask, + mce_irq_ipi,NULL ,0 ); +preempt_enable (); + }else if (m->inject_flags &MCJ_NMI_BROADCAST ) + apic->send_IPI_mask (mce_inject_cpumask, +NMI_VECTOR ); + } start = jiffies;while (!cpumask_empty (mce_inject_cpumask)) {if (!time_before (jiffies, start +2 *HZ )) {printk (KERN_ERR -"Timeout waiting for mce inject NMI %lx\n" , +"Timeout waiting for mce inject %lx\n" , *cpumask_bits (mce_inject_cpumask));break ; }
Signature · 1 line
1.7.7.rc0.70.g82660
PATCH 1/1 x86: add IRQ context simulation in module mce-inject
mce-inject provides a mechanism to simulate errors so that test scripts can check for correct operation of the kernel without requiring any specialized hardware to create rare events.
The existing code can simulate events in normal process context and also in NMI context - but not in IRQ context. This patch fills that gap.
---
[Re-wrote the commit comment - Chen Gong's original text is below,
in case I missed any critical aspect - Tony]
module mce-inject is an interface which is used by user space app such as mce-inject. According to it one can inject all kinds of error combinations into the kernel. In this way, one can check error condition coverage in the kernel. To satisify this needs, module mce-inject must simulate enough scenarios such as process context, IRQ context, even NMI context, to ensure related kernel codes are strong and reliable. In current implementation, IRQ context hasn't been simulated. This patch is for this purpose.
arch/x86/include/asm/mce.h | 9 ++++--- arch/x86/kernel/cpu/mcheck/mce-inject.c | 34 +++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-)
arch/x86/include/asm/mce.h +5 -4
@@ -50,10 +50,11 @@#define MCJ_CTX_MASK 3#define MCJ_CTX (flags) ((flags) & MCJ_CTX_MASK)#define MCJ_CTX_RANDOM 0/* inject context: random */ -#define MCJ_CTX_PROCESS 1/* inject context: process */ -#define MCJ_CTX_IRQ 2/* inject context: IRQ */ -#define MCJ_NMI_BROADCAST 4/* do NMI broadcasting */ -#define MCJ_EXCEPTION 8/* raise as exception */ +#define MCJ_CTX_PROCESS 0x1/* inject context: process */ +#define MCJ_CTX_IRQ 0x2/* inject context: IRQ */ +#define MCJ_NMI_BROADCAST 0x4/* do NMI broadcasting */ +#define MCJ_EXCEPTION 0x8/* raise as exception */ +#define MCJ_IRQ_BRAODCAST 0x10/* do IRQ broadcasting */ /* Fields are zero when not available */ struct mce {
arch/x86/kernel/cpu/mcheck/mce-inject.c +30 -4
@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/string.h> #include <linux/fs.h> +#include <linux/preempt.h> #include <linux/smp.h> #include <linux/notifier.h> #include <linux/kdebug.h>
@@ -92,6 +93,18 @@ static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)return NMI_HANDLED ; } +static void mce_irq_ipi (void *info) +{ +int cpu =smp_processor_id (); +struct mce *m = &__get_cpu_var (injectm); + +if (cpumask_test_cpu (cpu, mce_inject_cpumask) && + m->inject_flags &MCJ_EXCEPTION ) { +cpumask_clear_cpu (cpu, mce_inject_cpumask); +raise_exception (m,NULL ); + } +} +/* Inject mce on current CPU */ static int raise_local (void ) {
@@ -139,9 +152,10 @@ static void raise_mce(struct mce *m)return ;#ifdef CONFIG_X86_LOCAL_APIC -if (m->inject_flags &MCJ_NMI_BROADCAST ) { +if (m->inject_flags & (MCJ_IRQ_BRAODCAST |MCJ_NMI_BROADCAST )) {unsigned long start;int cpu; +get_online_cpus ();cpumask_copy (mce_inject_cpumask, cpu_online_mask);cpumask_clear_cpu (get_cpu (), mce_inject_cpumask);
@@ -151,13 +165,25 @@ static void raise_mce(struct mce *m) MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)cpumask_clear_cpu (cpu, mce_inject_cpumask); } -if (!cpumask_empty (mce_inject_cpumask)) - apic->send_IPI_mask (mce_inject_cpumask,NMI_VECTOR ); +if (!cpumask_empty (mce_inject_cpumask)) { +if (m->inject_flags &MCJ_IRQ_BRAODCAST ) { +/* +* don't wait because mce_irq_ipi is necessary +* to be sync with following raise_local +*/ +preempt_disable (); +smp_call_function_many (mce_inject_cpumask, + mce_irq_ipi,NULL ,0 ); +preempt_enable (); + }else if (m->inject_flags &MCJ_NMI_BROADCAST ) + apic->send_IPI_mask (mce_inject_cpumask, +NMI_VECTOR ); + } start = jiffies;while (!cpumask_empty (mce_inject_cpumask)) {if (!time_before (jiffies, start +2 *HZ )) {printk (KERN_ERR -"Timeout waiting for mce inject NMI %lx\n" , +"Timeout waiting for mce inject %lx\n" , *cpumask_bits (mce_inject_cpumask));break ; }
Signature · 7 lines
1.7.7.rc0.70.g82660 -- 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/
Quoted 109 lines · Tony
mce-inject provides a mechanism to simulate errors so that test scripts can check for correct operation of the kernel without requiring any specialized hardware to create rare events.
The existing code can simulate events in normal process context and also in NMI context - but not in IRQ context. This patch fills that gap.
Signed-off-by Chen Gong<[email protected]>Acked-by Tony Luck<[email protected]>---
[Re-wrote the commit comment - Chen Gong's original text is below,
in case I missed any critical aspect - Tony]
module mce-inject is an interface which is used by user space app such as mce-inject. According to it one can inject all kinds of error combinations into the kernel. In this way, one can check error condition coverage in the kernel. To satisify this needs, module mce-inject must simulate enough scenarios such as process context, IRQ context, even NMI context, to ensure related kernel codes are strong and reliable. In current implementation, IRQ context hasn't been simulated. This patch is for this purpose.arch/x86/include/asm/mce.h | 9 ++++--- arch/x86/kernel/cpu/mcheck/mce-inject.c | 34 +++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-)arch/x86/include/asm/mce.h +5
-4@@ -50,10 +50,11 @@#define MCJ_CTX_MASK 3#define MCJ_CTX (flags) ((flags)& MCJ_CTX_MASK)#define MCJ_CTX_RANDOM 0/* inject context: random */ -#define MCJ_CTX_PROCESS 1/* inject context: process */ -#define MCJ_CTX_IRQ 2/* inject context: IRQ */ -#define MCJ_NMI_BROADCAST 4/* do NMI broadcasting */ -#define MCJ_EXCEPTION 8/* raise as exception */ +#define MCJ_CTX_PROCESS 0x1/* inject context: process */ +#define MCJ_CTX_IRQ 0x2/* inject context: IRQ */ +#define MCJ_NMI_BROADCAST 0x4/* do NMI broadcasting */ +#define MCJ_EXCEPTION 0x8/* raise as exception */ +#define MCJ_IRQ_BRAODCAST 0x10/* do IRQ broadcasting */ /* Fields are zero when not available */ struct mce {arch/x86/kernel/cpu/mcheck/mce-inject.c +28
-3@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/string.h> #include <linux/fs.h> +#include <linux/preempt.h> #include <linux/smp.h> #include <linux/notifier.h> #include <linux/kdebug.h> @@ -92,6 +93,18 @@ static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)return NMI_HANDLED ; } +static void mce_irq_ipi (void *info) +{ +int cpu =smp_processor_id (); +struct mce *m =&__get_cpu_var (injectm); + +if (cpumask_test_cpu (cpu, mce_inject_cpumask)&& + m->inject_flags&MCJ_EXCEPTION ) { +cpumask_clear_cpu (cpu, mce_inject_cpumask); +raise_exception (m,NULL ); + } +} +/* Inject mce on current CPU */ static int raise_local (void ) {@@ -139,9 +152,10 @@ static void raise_mce(struct mce *m)return ;#ifdef CONFIG_X86_LOCAL_APIC -if (m->inject_flags&MCJ_NMI_BROADCAST ) { +if (m->inject_flags& (MCJ_IRQ_BRAODCAST |MCJ_NMI_BROADCAST )) {unsigned long start;int cpu; +get_online_cpus ();cpumask_copy (mce_inject_cpumask, cpu_online_mask);cpumask_clear_cpu (get_cpu (), mce_inject_cpumask);@@ -151,13 +165,25 @@ static void raise_mce(struct mce *m) MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)cpumask_clear_cpu (cpu, mce_inject_cpumask); } -if (!cpumask_empty (mce_inject_cpumask)) - apic->send_IPI_mask (mce_inject_cpumask,NMI_VECTOR ); +if (!cpumask_empty (mce_inject_cpumask)) { +if (m->inject_flags&MCJ_IRQ_BRAODCAST ) { +/* +* don't wait because mce_irq_ipi is necessary +* to be sync with following raise_local +*/ +preempt_disable (); +smp_call_function_many (mce_inject_cpumask, + mce_irq_ipi,NULL ,0 ); +preempt_enable (); + }else if (m->inject_flags&MCJ_NMI_BROADCAST ) + apic->send_IPI_mask (mce_inject_cpumask, +NMI_VECTOR );
arch/x86/kernel/cpu/mcheck/mce-inject.c static void raise_mce(struct mce *m) · line 189
Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce-inject.c +2
-1+ } start = jiffies;while (!cpumask_empty (mce_inject_cpumask)) {if (!time_before (jiffies, start +2 *HZ )) {printk (KERN_ERR -"Timeout waiting for mce inject NMI %lx\n" , +"Timeout waiting for mce inject %lx\n" , *cpumask_bits (mce_inject_cpumask));break ; }
Hi, would you please help to merge this patch into -x86 tree? If you miss it. Thx in advance!
mce-inject provides a mechanism to simulate errors so that test scripts can check for correct operation of the kernel without requiring any specialized hardware to create rare events.
The existing code can simulate events in normal process context and also in NMI context - but not in IRQ context. This patch fills that gap.
---
[Re-wrote the commit comment - Chen Gong's original text is below,
in case I missed any critical aspect - Tony]
module mce-inject is an interface which is used by user space app such as mce-inject. According to it one can inject all kinds of error combinations into the kernel. In this way, one can check error condition coverage in the kernel. To satisify this needs, module mce-inject must simulate enough scenarios such as process context, IRQ context, even NMI context, to ensure related kernel codes are strong and reliable. In current implementation, IRQ context hasn't been simulated. This patch is for this purpose.
arch/x86/include/asm/mce.h | 9 ++++--- arch/x86/kernel/cpu/mcheck/mce-inject.c | 34 +++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-)
arch/x86/include/asm/mce.h +5 -4
@@ -50,10 +50,11 @@#define MCJ_CTX_MASK 3#define MCJ_CTX (flags) ((flags) & MCJ_CTX_MASK)#define MCJ_CTX_RANDOM 0/* inject context: random */ -#define MCJ_CTX_PROCESS 1/* inject context: process */ -#define MCJ_CTX_IRQ 2/* inject context: IRQ */ -#define MCJ_NMI_BROADCAST 4/* do NMI broadcasting */ -#define MCJ_EXCEPTION 8/* raise as exception */ +#define MCJ_CTX_PROCESS 0x1/* inject context: process */ +#define MCJ_CTX_IRQ 0x2/* inject context: IRQ */ +#define MCJ_NMI_BROADCAST 0x4/* do NMI broadcasting */ +#define MCJ_EXCEPTION 0x8/* raise as exception */ +#define MCJ_IRQ_BRAODCAST 0x10/* do IRQ broadcasting */ /* Fields are zero when not available */ struct mce {
arch/x86/kernel/cpu/mcheck/mce-inject.c +30 -4
@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/string.h> #include <linux/fs.h> +#include <linux/preempt.h> #include <linux/smp.h> #include <linux/notifier.h> #include <linux/kdebug.h>
@@ -92,6 +93,18 @@ static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)return NMI_HANDLED ; } +static void mce_irq_ipi (void *info) +{ +int cpu =smp_processor_id (); +struct mce *m = &__get_cpu_var (injectm); + +if (cpumask_test_cpu (cpu, mce_inject_cpumask) && + m->inject_flags &MCJ_EXCEPTION ) { +cpumask_clear_cpu (cpu, mce_inject_cpumask); +raise_exception (m,NULL ); + } +} +/* Inject mce on current CPU */ static int raise_local (void ) {
@@ -139,9 +152,10 @@ static void raise_mce(struct mce *m)return ;#ifdef CONFIG_X86_LOCAL_APIC -if (m->inject_flags &MCJ_NMI_BROADCAST ) { +if (m->inject_flags & (MCJ_IRQ_BRAODCAST |MCJ_NMI_BROADCAST )) {unsigned long start;int cpu; +get_online_cpus ();cpumask_copy (mce_inject_cpumask, cpu_online_mask);cpumask_clear_cpu (get_cpu (), mce_inject_cpumask);
@@ -151,13 +165,25 @@ static void raise_mce(struct mce *m) MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)cpumask_clear_cpu (cpu, mce_inject_cpumask); } -if (!cpumask_empty (mce_inject_cpumask)) - apic->send_IPI_mask (mce_inject_cpumask,NMI_VECTOR ); +if (!cpumask_empty (mce_inject_cpumask)) { +if (m->inject_flags &MCJ_IRQ_BRAODCAST ) { +/* +* don't wait because mce_irq_ipi is necessary +* to be sync with following raise_local +*/ +preempt_disable (); +smp_call_function_many (mce_inject_cpumask, + mce_irq_ipi,NULL ,0 ); +preempt_enable (); + }else if (m->inject_flags &MCJ_NMI_BROADCAST ) + apic->send_IPI_mask (mce_inject_cpumask, +NMI_VECTOR ); + } start = jiffies;while (!cpumask_empty (mce_inject_cpumask)) {if (!time_before (jiffies, start +2 *HZ )) {printk (KERN_ERR -"Timeout waiting for mce inject NMI %lx\n" , +"Timeout waiting for mce inject %lx\n" , *cpumask_bits (mce_inject_cpumask));break ; }
Signature · 12 lines
1.7.7.rc0.70.g82660 -- 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/ -- 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/
Quoted 10 lines · Luck, Tony
mce-inject provides a mechanism to simulate errors so that test scripts can check for correct operation of the kernel without requiring any specialized hardware to create rare events.
The existing code can simulate events in normal process context and also in NMI context - but not in IRQ context. This patch fills that gap.
Signed-off-by Chen Gong <[email protected]>Acked-by Tony Luck <[email protected]>
Looks good to me. Will show up in the RAS tree i guess?
Thanks,
Ingo