|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |