static int mc_queue_handle(uint32_t flags) { struct xen_mc mc_op; int ret = 0; mc_op.cmd = XEN_MC_fetch; mc_op.interface_version = XEN_MCA_INTERFACE_VERSION; set_xen_guest_handle(mc_op.u.mc_fetch.data, &g_mi); do { mc_op.u.mc_fetch.flags = flags; ret = HYPERVISOR_mca(&mc_op); if (ret) { pr_err("Failed to fetch %surgent error log\n", flags == XEN_MC_URGENT ? "" : "non"); break; } if (mc_op.u.mc_fetch.flags & XEN_MC_NODATA || mc_op.u.mc_fetch.flags & XEN_MC_FETCHFAILED) break; else { ret = convert_log(&g_mi); if (ret) pr_warn("Failed to convert this error log, continue acking it anyway\n"); mc_op.u.mc_fetch.flags = flags | XEN_MC_ACK; ret = HYPERVISOR_mca(&mc_op); if (ret) { pr_err("Failed to ack previous error log\n"); break; } } } while (1); return ret; }
static irqreturn_t mce_dom0_interrupt(int irq, void *dev_id) { xen_mc_t mc_op; int result = 0; printk(KERN_DEBUG "MCE_DOM0_LOG: enter dom0 mce vIRQ handler\n"); mc_op.cmd = XEN_MC_fetch; mc_op.interface_version = XEN_MCA_INTERFACE_VERSION; set_xen_guest_handle(mc_op.u.mc_fetch.data, g_mi); urgent: mc_op.u.mc_fetch.flags = XEN_MC_URGENT; result = HYPERVISOR_mca(&mc_op); if (result || mc_op.u.mc_fetch.flags & XEN_MC_NODATA || mc_op.u.mc_fetch.flags & XEN_MC_FETCHFAILED) { printk(KERN_DEBUG "MCE_DOM0_LOG: No more urgent data\n"); goto nonurgent; } else { result = convert_log(g_mi); if (result) { printk(KERN_ERR "MCE_DOM0_LOG: Log conversion failed\n"); goto end; } /* After fetching the telem from DOM0, we need to dec the telem's * refcnt and release the entry. The telem is reserved and inc * refcnt when filling the telem. */ mc_op.u.mc_fetch.flags = XEN_MC_URGENT | XEN_MC_ACK; result = HYPERVISOR_mca(&mc_op); goto urgent; } nonurgent: mc_op.u.mc_fetch.flags = XEN_MC_NONURGENT; result = HYPERVISOR_mca(&mc_op); if (result || mc_op.u.mc_fetch.flags & XEN_MC_NODATA || mc_op.u.mc_fetch.flags & XEN_MC_FETCHFAILED) { printk(KERN_DEBUG "MCE_DOM0_LOG: No more nonurgent data\n"); goto end; } else { result = convert_log(g_mi); if (result) { printk(KERN_ERR "MCE_DOM0_LOG: Log conversion failed\n"); goto end; } /* After fetching the telem from DOM0, we need to dec the telem's * refcnt and release the entry. The telem is reserved and inc * refcnt when filling the telem. */ mc_op.u.mc_fetch.flags = XEN_MC_NONURGENT | XEN_MC_ACK; result = HYPERVISOR_mca(&mc_op); goto nonurgent; } end: return IRQ_HANDLED; }