[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] x86/irq: further gate PIRQ usage for HVM domains



commit e4956d5e6bdcb7e2e9abfa4474b2dc1160c51a45
Author:     Roger Pau Monne <roger@xxxxxxxxxxxxxx>
AuthorDate: Thu Oct 29 08:46:23 2026 +0100
Commit:     Roger Pau Monne <roger@xxxxxxxxxxxxxx>
CommitDate: Thu Oct 29 14:51:07 2026 +0100

    x86/irq: further gate PIRQ usage for HVM domains
    
    Further restrict PIRQ usage for HVM domains not having the ability to route
    device interrupts over event channels.
    
    It's still possible for HVM domains without PIRQ support to exercise the
    vector == 0 path in hvm_inject_msi(), which is intended to be used only
    when the guest has PIRQ support.  Taking the PIRQ path in hvm_inject_msi()
    inhibits the local APIC from raising an ESR error when the MSI vector is
    0, since an MSI with vector == 0 is always processed as a PIRQ.  Introduce
    a has_pirq() check in hvm_inject_msi().
    
    EVTCHNOP_bind_pirq is also not outright blocked for HVM domains without
    PIRQ support, so guests could attempt to bind device interrupts to event
    channels.  Short-circuit evtchn_bind_pirq() early if the domain has no PIRQ
    support.
    
    Additionally introduce an assert in map_domain_emuirq_pirq() to ensure it's
    never called from HVM domains without PIRQ support.
    
    Finally add an extra check in hvm_domain_use_pirq() so it returns false
    unconditionally if the domain has no PIRQ support.  Also convert the
    is_hvm_domain() check into an ASSERT(); this helper is never called against
    a PV domain.
    
    Fixes: b96b50004804 ("x86: remove XENFEAT_hvm_pirqs for PVHv2 guests")
    Signed-off-by: Roger Pau Monné <roger@xxxxxxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/hvm/irq.c     | 5 +++--
 xen/arch/x86/irq.c         | 2 ++
 xen/common/event_channel.c | 3 +++
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index 5f64361113..50a4314314 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -19,7 +19,8 @@
 
 bool hvm_domain_use_pirq(const struct domain *d, const struct pirq *pirq)
 {
-    return is_hvm_domain(d) && pirq && pirq->arch.hvm.emuirq != IRQ_UNBOUND;
+    ASSERT(is_hvm_domain(d));
+    return has_pirq(d) && pirq && pirq->arch.hvm.emuirq != IRQ_UNBOUND;
 }
 
 /* Must be called with hvm_domain->irq_lock hold */
@@ -382,7 +383,7 @@ int hvm_inject_msi(struct domain *d, uint64_t addr, 
uint32_t data)
         >> MSI_DATA_TRIGGER_SHIFT;
     uint8_t vector = data & MSI_DATA_VECTOR_MASK;
 
-    if ( !vector )
+    if ( has_pirq(d) && !vector )
     {
         unsigned int pirq = ((addr >> 32) & 0xffffff00U) | dest;
 
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index c58d2eb922..32a75f77a4 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2814,6 +2814,8 @@ int map_domain_emuirq_pirq(struct domain *d, int pirq, 
int emuirq)
     if ( !is_hvm_domain(d) )
         return -EINVAL;
 
+    ASSERT(has_pirq(d));
+
     if ( pirq < 0 || pirq >= d->nr_pirqs ||
             emuirq == IRQ_UNBOUND || emuirq >= (int) nr_irqs )
     {
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index bd03e094d0..97104bea15 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -681,6 +681,9 @@ static int evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     int            port = 0, rc;
     unsigned int   pirq = bind->pirq;
 
+    if ( is_hvm_domain(d) && !has_pirq(d) )
+        return -EOPNOTSUPP;
+
     if ( pirq >= d->nr_pirqs )
         return -EINVAL;
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.