@@ -140,6 +140,8 @@ struct XenEvtchnState {
140
140
141
141
uint64_t callback_param ;
142
142
bool evtchn_in_kernel ;
143
+ bool setting_callback_gsi ;
144
+ int extern_gsi_level ;
143
145
uint32_t callback_gsi ;
144
146
145
147
QEMUBH * gsi_bh ;
@@ -431,9 +433,22 @@ void xen_evtchn_set_callback_level(int level)
431
433
}
432
434
433
435
if (s -> callback_gsi && s -> callback_gsi < s -> nr_callback_gsis ) {
434
- qemu_set_irq (s -> callback_gsis [s -> callback_gsi ], level );
435
- if (level ) {
436
- /* Ensure the vCPU polls for deassertion */
436
+ /*
437
+ * Ugly, but since we hold the BQL we can set this flag so that
438
+ * xen_evtchn_set_gsi() can tell the difference between this code
439
+ * setting the GSI, and an external device (PCI INTx) doing so.
440
+ */
441
+ s -> setting_callback_gsi = true;
442
+ /* Do not deassert the line if an external device is asserting it. */
443
+ qemu_set_irq (s -> callback_gsis [s -> callback_gsi ],
444
+ level || s -> extern_gsi_level );
445
+ s -> setting_callback_gsi = false;
446
+
447
+ /*
448
+ * If the callback GSI is the only one asserted, ensure the status
449
+ * is polled for deassertion in kvm_arch_post_run().
450
+ */
451
+ if (level && !s -> extern_gsi_level ) {
437
452
kvm_xen_set_callback_asserted ();
438
453
}
439
454
}
@@ -1596,7 +1611,7 @@ static int allocate_pirq(XenEvtchnState *s, int type, int gsi)
1596
1611
return pirq ;
1597
1612
}
1598
1613
1599
- bool xen_evtchn_set_gsi (int gsi , int level )
1614
+ bool xen_evtchn_set_gsi (int gsi , int * level )
1600
1615
{
1601
1616
XenEvtchnState * s = xen_evtchn_singleton ;
1602
1617
int pirq ;
@@ -1608,16 +1623,35 @@ bool xen_evtchn_set_gsi(int gsi, int level)
1608
1623
}
1609
1624
1610
1625
/*
1611
- * Check that that it *isn't* the event channel GSI, and thus
1612
- * that we are not recursing and it's safe to take s->port_lock.
1613
- *
1614
- * Locking aside, it's perfectly sane to bail out early for that
1615
- * special case, as it would make no sense for the event channel
1616
- * GSI to be routed back to event channels, when the delivery
1617
- * method is to raise the GSI... that recursion wouldn't *just*
1618
- * be a locking issue.
1626
+ * For the callback_gsi we need to implement a logical OR of the event
1627
+ * channel GSI and the external input (e.g. from PCI INTx), because
1628
+ * QEMU itself doesn't support shared level interrupts via demux or
1629
+ * resamplers.
1619
1630
*/
1620
1631
if (gsi && gsi == s -> callback_gsi ) {
1632
+ /* Remember the external state of the GSI pin (e.g. from PCI INTx) */
1633
+ if (!s -> setting_callback_gsi ) {
1634
+ s -> extern_gsi_level = * level ;
1635
+
1636
+ /*
1637
+ * Don't allow the external device to deassert the line if the
1638
+ * eveht channel GSI should still be asserted.
1639
+ */
1640
+ if (!s -> extern_gsi_level ) {
1641
+ struct vcpu_info * vi = kvm_xen_get_vcpu_info_hva (0 );
1642
+ if (vi && vi -> evtchn_upcall_pending ) {
1643
+ /* Need to poll for deassertion */
1644
+ kvm_xen_set_callback_asserted ();
1645
+ * level = 1 ;
1646
+ }
1647
+ }
1648
+ }
1649
+
1650
+ /*
1651
+ * The event channel GSI cannot be routed to PIRQ, as that would make
1652
+ * no sense. It could also deadlock on s->port_lock, if we proceed.
1653
+ * So bail out now.
1654
+ */
1621
1655
return false;
1622
1656
}
1623
1657
@@ -1628,7 +1662,7 @@ bool xen_evtchn_set_gsi(int gsi, int level)
1628
1662
return false;
1629
1663
}
1630
1664
1631
- if (level ) {
1665
+ if (* level ) {
1632
1666
int port = s -> pirq [pirq ].port ;
1633
1667
1634
1668
s -> pirq_gsi_set |= (1U << gsi );
0 commit comments