xen/arch/x86/hvm/irq.c | 2 +- xen/arch/x86/include/asm/domain.h | 9 +++++++-- xen/arch/x86/traps.c | 6 ++++++ xen/include/public/arch-x86/cpuid.h | 5 +++++ 4 files changed, 19 insertions(+), 3 deletions(-)
Have is_hvm_pv_evtchn_domain() return true for vector callbacks for
evtchn delivery set up on a per-vCPU basis via
HVMOP_set_evtchn_upcall_vector.
Assume that if vCPU0 uses HVMOP_set_evtchn_upcall_vector, all
remaining vCPUs will too and thus remove is_hvm_pv_evtchn_vcpu() and
replace sole caller with is_hvm_pv_evtchn_domain().
is_hvm_pv_evtchn_domain() returning true is a condition for setting up
physical IRQ to event channel mappings. Therefore, also add a CPUID
bit so that guests know whether the check in is_hvm_pv_evtchn_domain()
will fail when using HVMOP_set_evtchn_upcall_vector. This matters for
guests that route PIRQs over event channels since
is_hvm_pv_evtchn_domain() is a condition in physdev_map_pirq().
The naming of the CPUID bit is quite generic about upcall support
being available. That's done so that the define name doesn't become
overly long.
A guest that doesn't care about physical interrupts routed over event
channels can just test for the availability of the hypercall directly
(HVMOP_set_evtchn_upcall_vector) without checking the CPUID bit.
Signed-off-by: Jane Malalane <jane.malalane@citrix.com>
---
CC: Jan Beulich <jbeulich@suse.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: "Roger Pau Monné" <roger.pau@citrix.com>
CC: Wei Liu <wl@xen.org>
v4:
* Remove is_hvm_pv_evtchn_vcpu and replace sole caller.
v3:
* Improve commit message and title.
v2:
* Since the naming of the CPUID bit is quite generic, better explain
when it should be checked for, in code comments and commit message.
---
xen/arch/x86/hvm/irq.c | 2 +-
xen/arch/x86/include/asm/domain.h | 9 +++++++--
xen/arch/x86/traps.c | 6 ++++++
xen/include/public/arch-x86/cpuid.h | 5 +++++
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index 5a7f39b54f..19252448cb 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -325,7 +325,7 @@ void hvm_assert_evtchn_irq(struct vcpu *v)
vlapic_set_irq(vcpu_vlapic(v), vector, 0);
}
- else if ( is_hvm_pv_evtchn_vcpu(v) )
+ else if ( is_hvm_pv_evtchn_domain(v->domain) )
vcpu_kick(v);
else if ( v->vcpu_id == 0 )
hvm_set_callback_irq_level(v);
diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h
index 35898d725f..dcd221cc6f 100644
--- a/xen/arch/x86/include/asm/domain.h
+++ b/xen/arch/x86/include/asm/domain.h
@@ -14,9 +14,14 @@
#define has_32bit_shinfo(d) ((d)->arch.has_32bit_shinfo)
+/*
+ * Set to true if either the global vector-type callback or per-vCPU
+ * LAPIC vectors are used. Assume all vCPUs will use
+ * HVMOP_set_evtchn_upcall_vector as long as the initial vCPU does.
+ */
#define is_hvm_pv_evtchn_domain(d) (is_hvm_domain(d) && \
- (d)->arch.hvm.irq->callback_via_type == HVMIRQ_callback_vector)
-#define is_hvm_pv_evtchn_vcpu(v) (is_hvm_pv_evtchn_domain(v->domain))
+ ((d)->arch.hvm.irq->callback_via_type == HVMIRQ_callback_vector || \
+ (d)->vcpu[0]->arch.hvm.evtchn_upcall_vector))
#define is_domain_direct_mapped(d) ((void)(d), 0)
#define VCPU_TRAP_NONE 0
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 25bffe47d7..1a7f9df067 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1152,6 +1152,12 @@ void cpuid_hypervisor_leaves(const struct vcpu *v, uint32_t leaf,
res->a |= XEN_HVM_CPUID_DOMID_PRESENT;
res->c = d->domain_id;
+ /*
+ * Per-vCPU event channel upcalls are implemented and work
+ * correctly with PIRQs routed over event channels.
+ */
+ res->a |= XEN_HVM_CPUID_UPCALL_VECTOR;
+
break;
case 5: /* PV-specific parameters */
diff --git a/xen/include/public/arch-x86/cpuid.h b/xen/include/public/arch-x86/cpuid.h
index f2b2b3632c..c49eefeaf8 100644
--- a/xen/include/public/arch-x86/cpuid.h
+++ b/xen/include/public/arch-x86/cpuid.h
@@ -109,6 +109,11 @@
* field from 8 to 15 bits, allowing to target APIC IDs up 32768.
*/
#define XEN_HVM_CPUID_EXT_DEST_ID (1u << 5)
+/*
+ * Per-vCPU event channel upcalls work correctly with physical IRQs
+ * bound to event channels.
+ */
+#define XEN_HVM_CPUID_UPCALL_VECTOR (1u << 6)
/*
* Leaf 6 (0x40000x05)
--
2.11.0
On Fri, Jun 10, 2022 at 12:07:04PM +0100, Jane Malalane wrote: > Have is_hvm_pv_evtchn_domain() return true for vector callbacks for > evtchn delivery set up on a per-vCPU basis via > HVMOP_set_evtchn_upcall_vector. > > Assume that if vCPU0 uses HVMOP_set_evtchn_upcall_vector, all > remaining vCPUs will too and thus remove is_hvm_pv_evtchn_vcpu() and > replace sole caller with is_hvm_pv_evtchn_domain(). > > is_hvm_pv_evtchn_domain() returning true is a condition for setting up > physical IRQ to event channel mappings. Therefore, also add a CPUID > bit so that guests know whether the check in is_hvm_pv_evtchn_domain() > will fail when using HVMOP_set_evtchn_upcall_vector. This matters for > guests that route PIRQs over event channels since > is_hvm_pv_evtchn_domain() is a condition in physdev_map_pirq(). > > The naming of the CPUID bit is quite generic about upcall support > being available. That's done so that the define name doesn't become > overly long. > > A guest that doesn't care about physical interrupts routed over event > channels can just test for the availability of the hypercall directly > (HVMOP_set_evtchn_upcall_vector) without checking the CPUID bit. > > Signed-off-by: Jane Malalane <jane.malalane@citrix.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> Thanks, Roger.
© 2016 - 2024 Red Hat, Inc.