add IRQ context simulation in mce-inject
PATCH 1/1 add IRQ context simulation in mce-inject
From: Chen Gong <[email protected]>
Current mce-inject can simulate some kinds of scenarios, such as one CPU working in process context, and other CPUs working in NMI context. To extend the coverage of test range, a new IRQ context for other CPUs is added.
--- arch/x86/include/asm/mce.h | 1 + arch/x86/kernel/cpu/mcheck/mce-inject.c | 34 +++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-)
arch/x86/include/asm/mce.h +1 -0
@@ -54,6 +54,7 @@#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_IRQ_BRAODCAST 0x10/* do IRQ broadcasting */ /* Fields are zero when not available */ struct mce {
arch/x86/kernel/cpu/mcheck/mce-inject.c +29 -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>
@@ -94,6 +95,18 @@ static int mce_raise_notify(struct notifier_block *self,return NOTIFY_STOP ; } +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 ); + } +} +static struct notifier_block mce_raise_nb = { .notifier_call = mce_raise_notify, .priority =NMI_LOCAL_NORMAL_PRIOR ,
@@ -146,9 +159,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);
@@ -158,13 +172,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.1
Quoted 6 lines · Chen Gong
From: Chen Gong <[email protected]>
Current mce-inject can simulate some kinds of scenarios, such as one CPU working in process context, and other CPUs working in NMI context. To extend the coverage of test range, a new IRQ context for other CPUs is added.
Looks good to me.
-Andi
Quoted 8 lines · Andi Kleen
Quoted 6 lines · Chen Gong
From: Chen Gong <[email protected]>
Current mce-inject can simulate some kinds of scenarios, such as one CPU working in process context, and other CPUs working in NMI context. To extend the coverage of test range, a new IRQ context for other CPUs is added.
Quoted 4 lines
Looks good to me.
-Andi--
Hi, Andi
I will resend this patch, do you agree I add you as the "Signed-off-By" in the next post?