summaryrefslogtreecommitdiffstats
path: root/hw/intc/xive.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc/xive.c')
-rw-r--r--hw/intc/xive.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index deb0db21e0..b8e4c7294d 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -887,6 +887,16 @@ static bool xive_source_lsi_trigger(XiveSource *xsrc, uint32_t srcno)
}
/*
+ * Sources can be configured with PQ offloading in which case the check
+ * on the PQ state bits of MSIs is disabled
+ */
+static bool xive_source_esb_disabled(XiveSource *xsrc, uint32_t srcno)
+{
+ return (xsrc->esb_flags & XIVE_SRC_PQ_DISABLE) &&
+ !xive_source_irq_is_lsi(xsrc, srcno);
+}
+
+/*
* Returns whether the event notification should be forwarded.
*/
static bool xive_source_esb_trigger(XiveSource *xsrc, uint32_t srcno)
@@ -895,6 +905,10 @@ static bool xive_source_esb_trigger(XiveSource *xsrc, uint32_t srcno)
assert(srcno < xsrc->nr_irqs);
+ if (xive_source_esb_disabled(xsrc, srcno)) {
+ return true;
+ }
+
ret = xive_esb_trigger(&xsrc->status[srcno]);
if (xive_source_irq_is_lsi(xsrc, srcno) &&
@@ -915,6 +929,11 @@ static bool xive_source_esb_eoi(XiveSource *xsrc, uint32_t srcno)
assert(srcno < xsrc->nr_irqs);
+ if (xive_source_esb_disabled(xsrc, srcno)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid EOI for IRQ %d\n", srcno);
+ return false;
+ }
+
ret = xive_esb_eoi(&xsrc->status[srcno]);
/*
@@ -936,9 +955,10 @@ static bool xive_source_esb_eoi(XiveSource *xsrc, uint32_t srcno)
static void xive_source_notify(XiveSource *xsrc, int srcno)
{
XiveNotifierClass *xnc = XIVE_NOTIFIER_GET_CLASS(xsrc->xive);
+ bool pq_checked = !xive_source_esb_disabled(xsrc, srcno);
if (xnc->notify) {
- xnc->notify(xsrc->xive, srcno, true);
+ xnc->notify(xsrc->xive, srcno, pq_checked);
}
}