# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1266408290 0
# Node ID 50ea24db1f88c57611e5c62f1378873c677c0d11
# Parent e99d20837ac056eb6597b643d3e640bb4216bdca
x86/mcheck: do not blindly de-reference dom0 et al
Since machine checks and CMCIs can happen before Dom0 even gets
constructed, the handlers of these events have to avoid de-referencing
respective pointers without checking.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
xen/arch/x86/cpu/mcheck/amd_nonfatal.c | 7 ++-----
xen/arch/x86/cpu/mcheck/mce.c | 7 ++++---
xen/arch/x86/cpu/mcheck/mce.h | 2 ++
xen/arch/x86/cpu/mcheck/mce_intel.c | 6 +++---
xen/arch/x86/cpu/mcheck/non-fatal.c | 2 +-
5 files changed, 12 insertions(+), 12 deletions(-)
diff -r e99d20837ac0 -r 50ea24db1f88 xen/arch/x86/cpu/mcheck/amd_nonfatal.c
--- a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c Tue Feb 16 18:11:17 2010 +0000
+++ b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c Wed Feb 17 12:04:50 2010 +0000
@@ -84,11 +84,8 @@ static void mce_amd_checkregs(void *info
{
mctelem_cookie_t mctc;
struct mca_summary bs;
- unsigned int event_enabled;
mctc = mcheck_mca_logout(MCA_POLLER, mca_allbanks, &bs, NULL);
-
- event_enabled = guest_enabled_event(dom0->vcpu[0], VIRQ_MCA);
if (bs.errcnt && mctc != NULL) {
static uint64_t dumpcount = 0;
@@ -101,7 +98,7 @@ static void mce_amd_checkregs(void *info
* a simple-minded attempt to avoid spamming the console
* for corrected errors in early startup. */
- if (event_enabled) {
+ if (dom0_vmce_enabled()) {
mctelem_commit(mctc);
send_guest_global_virq(dom0, VIRQ_MCA);
} else if (++dumpcount >= 10) {
@@ -136,7 +133,7 @@ static void mce_amd_work_fn(void *data)
on_each_cpu(mce_amd_checkregs, data, 1);
if (adjust > 0) {
- if (!guest_enabled_event(dom0->vcpu[0], VIRQ_MCA) ) {
+ if (!dom0_vmce_enabled()) {
/* Dom0 did not enable VIRQ_MCA, so Xen is reporting. */
printk("MCE: polling routine found correctable error. "
" Use mcelog to parse above error output.\n");
diff -r e99d20837ac0 -r 50ea24db1f88 xen/arch/x86/cpu/mcheck/mce.c
--- a/xen/arch/x86/cpu/mcheck/mce.c Tue Feb 16 18:11:17 2010 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce.c Wed Feb 17 12:04:50 2010 +0000
@@ -414,7 +414,7 @@ void mcheck_cmn_handler(struct cpu_user_
* as terminal for any context.
*/
ctx_xen = SEG_PL(regs->cs) == 0;
- ctx_dom0 = !ctx_xen && (domid == dom0->domain_id);
+ ctx_dom0 = !ctx_xen && (domid == 0);
ctx_domU = !ctx_xen && !ctx_dom0;
xen_state_lost = bs.uc != 0 || (ctx_xen && (bs.pcc || !ripv)) ||
@@ -463,7 +463,8 @@ void mcheck_cmn_handler(struct cpu_user_
* XXFM Could add some Solaris dom0 contract kill here?
*/
if (dom0_state_lost) {
- if (guest_has_trap_callback(dom0, 0, TRAP_machine_check)) {
+ if (dom0 && dom0->max_vcpus && dom0->vcpu[0] &&
+ guest_has_trap_callback(dom0, 0, TRAP_machine_check)) {
dom_state = DOM0_TRAP;
send_guest_trap(dom0, 0, TRAP_machine_check);
/* XXFM case of return with !ripv ??? */
@@ -532,7 +533,7 @@ cmn_handler_done:
if (bs.errcnt) {
/* Not panicing, so forward telemetry to dom0 now if it
* is interested. */
- if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
+ if (dom0_vmce_enabled()) {
if (mctc != NULL)
mctelem_commit(mctc);
send_guest_global_virq(dom0, VIRQ_MCA);
diff -r e99d20837ac0 -r 50ea24db1f88 xen/arch/x86/cpu/mcheck/mce.h
--- a/xen/arch/x86/cpu/mcheck/mce.h Tue Feb 16 18:11:17 2010 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce.h Wed Feb 17 12:04:50 2010 +0000
@@ -55,6 +55,8 @@ void x86_mc_get_cpu_info(unsigned, uint3
void x86_mc_get_cpu_info(unsigned, uint32_t *, uint16_t *, uint16_t *,
uint32_t *, uint32_t *, uint32_t *, uint32_t *);
+#define dom0_vmce_enabled() (dom0 && dom0->max_vcpus && dom0->vcpu[0] \
+ && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA))
/* Register a handler for machine check exceptions. */
typedef void (*x86_mce_vector_t)(struct cpu_user_regs *, long);
diff -r e99d20837ac0 -r 50ea24db1f88 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c Tue Feb 16 18:11:17 2010 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Wed Feb 17 12:04:50 2010 +0000
@@ -518,7 +518,7 @@ static void mce_softirq(void)
}
/* Step2: Send Log to DOM0 through vIRQ */
- if (dom0 && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
+ if (dom0_vmce_enabled()) {
mce_printk(MCE_VERBOSE, "MCE: send MCE# to DOM0 through virq\n");
send_guest_global_virq(dom0, VIRQ_MCA);
}
@@ -864,7 +864,7 @@ static void cmci_discover(void)
MCA_CMCI_HANDLER, __get_cpu_var(mce_banks_owned), &bs, NULL);
if (bs.errcnt && mctc != NULL) {
- if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
+ if (dom0_vmce_enabled()) {
mctelem_commit(mctc);
send_guest_global_virq(dom0, VIRQ_MCA);
} else {
@@ -979,7 +979,7 @@ fastcall void smp_cmci_interrupt(struct
MCA_CMCI_HANDLER, __get_cpu_var(mce_banks_owned), &bs, NULL);
if (bs.errcnt && mctc != NULL) {
- if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
+ if (dom0_vmce_enabled()) {
mctelem_commit(mctc);
mce_printk(MCE_VERBOSE, "CMCI: send CMCI to DOM0 through virq\n");
send_guest_global_virq(dom0, VIRQ_MCA);
diff -r e99d20837ac0 -r 50ea24db1f88 xen/arch/x86/cpu/mcheck/non-fatal.c
--- a/xen/arch/x86/cpu/mcheck/non-fatal.c Tue Feb 16 18:11:17 2010 +0000
+++ b/xen/arch/x86/cpu/mcheck/non-fatal.c Wed Feb 17 12:04:50 2010 +0000
@@ -53,7 +53,7 @@ static void mce_checkregs (void *info)
* for corrected errors in early startup.
*/
- if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
+ if (dom0_vmce_enabled()) {
mctelem_commit(mctc);
send_guest_global_virq(dom0, VIRQ_MCA);
} else if (++dumpcount >= 10) {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|