lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20160314163854.GG15800@pd.tnic>
Date:	Mon, 14 Mar 2016 17:38:54 +0100
From:	Borislav Petkov <bp@...en8.de>
To:	Tony Luck <tony.luck@...el.com>
Cc:	x86-ml <x86@...nel.org>, lkml <linux-kernel@...r.kernel.org>
Subject: [RFC PATCH] Unexport do_machine_check() and machine_check_poll()

Hey Tony,

how about the below, untested change?

Some backporting work to SLE11 got me pondering over why we're exporting
all those MCA-internal things to modules. Modules don't have any
business calling those so how about hiding them behind a single point
mce_call() function which gets a command what to do? This way, we're
free to change stuff later too, if we decide to do so.

Thoughts?

---
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 2ea4527e462f..39c362168aba 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -224,7 +224,6 @@ enum mcp_flags {
 	MCP_UC		= BIT(1),	/* log uncorrected errors */
 	MCP_DONTLOG	= BIT(2),	/* only clear, don't log */
 };
-bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
 
 int mce_notify_irq(void);
 
@@ -243,7 +242,6 @@ extern void mce_disable_bank(int bank);
 
 /* Call the installed machine check handler for this CPU setup. */
 extern void (*machine_check_vector)(struct pt_regs *, long error_code);
-void do_machine_check(struct pt_regs *, long);
 
 /*
  * Threshold handler
@@ -287,4 +285,12 @@ struct cper_sec_mem_err;
 extern void apei_mce_report_mem_error(int corrected,
 				      struct cper_sec_mem_err *mem_err);
 
+enum mce_call_cmds = {
+	MCE_CALL_DECODE,	/* A struct mce for decoding is being supplied. */
+	MCE_CALL_MC,		/* Invoke #MC exception handler. */
+	MCE_CALL_POLL,		/* Poll MCA banks. */
+};
+
+void mce_call(enum mce_call_cmds cmd, struct mce *m);
+
 #endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 4cfba4371a71..e3b896b836c7 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -49,13 +49,10 @@ static void inject_mce(struct mce *m)
 
 static void raise_poll(struct mce *m)
 {
-	unsigned long flags;
 	mce_banks_t b;
 
 	memset(&b, 0xff, sizeof(mce_banks_t));
-	local_irq_save(flags);
-	machine_check_poll(0, &b);
-	local_irq_restore(flags);
+	mce_call(MCE_CALL_POLL, &b);
 	m->finished = 0;
 }
 
@@ -72,7 +69,7 @@ static void raise_exception(struct mce *m, struct pt_regs *pregs)
 	}
 	/* in mcheck exeception handler, irq will be disabled */
 	local_irq_save(flags);
-	do_machine_check(pregs, 0);
+	mce_call(MCE_CALL_MC, pregs);
 	local_irq_restore(flags);
 	m->finished = 0;
 }
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h
index 547720efd923..6bae2bc2b21f 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h
+++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h
@@ -13,6 +13,8 @@ enum severity_level {
 	MCE_PANIC_SEVERITY,
 };
 
+void do_machine_check(struct pt_regs *, long);
+bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
 extern struct atomic_notifier_head x86_mce_decoder_chain;
 
 #define ATTR_LEN		16
@@ -79,5 +81,3 @@ static inline int apei_clear_mce(u64 record_id)
 	return -EINVAL;
 }
 #endif
-
-void mce_inject_log(struct mce *m);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index a006f4cd792b..c39a8c4f8a42 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -198,13 +198,34 @@ void mce_log(struct mce *mce)
 	set_bit(0, &mce_need_notify);
 }
 
-void mce_inject_log(struct mce *m)
+void mce_call(enum mce_call_cmds cmd, void *t)
 {
-	mutex_lock(&mce_chrdev_read_mutex);
-	mce_log(m);
-	mutex_unlock(&mce_chrdev_read_mutex);
+	switch (cmd) {
+	case MCE_CALL_DECODE:
+		mutex_lock(&mce_chrdev_read_mutex);
+		mce_log((struct mce *)t);
+		mutex_unlock(&mce_chrdev_read_mutex);
+		break;
+
+	case MCE_CALL_MC:
+		do_machine_check((struct pt_regs *)t, 0);
+		break;
+
+	case MCE_CALL_POLL: {
+		unsigned long flags;
+
+		local_irq_save(flags);
+		machine_check_poll(0, (mce_flags_t *)t);
+		local_irq_restore(flags);
+		}
+		break;
+
+	default:
+		WARN_ON_ONCE(1);
+		break;
+	}
 }
-EXPORT_SYMBOL_GPL(mce_inject_log);
+EXPORT_SYMBOL_GPL(mce_call);
 
 static struct notifier_block mce_srao_nb;
 
@@ -666,7 +687,6 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 
 	return error_seen;
 }
-EXPORT_SYMBOL_GPL(machine_check_poll);
 
 /*
  * Do a quick check if any of the events requires a panic.
@@ -1180,7 +1200,6 @@ out:
 done:
 	ist_exit(regs);
 }
-EXPORT_SYMBOL_GPL(do_machine_check);
 
 #ifndef CONFIG_MEMORY_FAILURE
 int memory_failure(unsigned long pfn, int vector, int flags)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e2951b6edbbc..8fdbb950416d 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5247,7 +5247,7 @@ static void kvm_machine_check(void)
 		.flags = X86_EFLAGS_IF,
 	};
 
-	do_machine_check(&regs, 0);
+	mce_call(MCE_CALL_MC, &regs);
 #endif
 }
 
diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c
index 55d38cfa46c2..dbfb3e4c3440 100644
--- a/arch/x86/ras/mce_amd_inj.c
+++ b/arch/x86/ras/mce_amd_inj.c
@@ -250,7 +250,7 @@ static void do_inject(void)
 		i_mce.status |= MCI_STATUS_MISCV;
 
 	if (inj_type == SW_INJ) {
-		mce_inject_log(&i_mce);
+		mce_call(MCE_CALL_DECODE, &i_mce);
 		return;
 	}
 

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ