|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 6/7] x86/dmop: Add XEN_DMOP_enable_ext_dest_id DM op
Xen cannot simply advertise XEN_HVM_CPUID_EXT_DEST_ID to the guest
without knowing that the device model will handle extended destination
IDs correctly for passthrough MSIs. A device model that still uses
XEN_DOMCTL_bind_pt_irq would pass only the low 8 bits of the destination
ID, misrouting interrupts to vCPUs with APIC IDs greater than 255. So,
add a DM op XEN_DMOP_enable_ext_dest_id that the device model can call
during domain setup (before vCPUs are started) to signal that it will
use XEN_DMOP_bind_pt_msi_irq for all passthrough MSI bindings. When
called, Xen sets ext_dest_id_enabled in struct hvm_domain, so it's
visible to the guest via CPUID.
Signed-off-by: Julian Vetter <julian.vetter@xxxxxxxxxx>
---
Changes in V3:
- New patch addressing feedback from Roger
---
tools/include/xendevicemodel.h | 14 ++++++++++++++
tools/libs/devicemodel/core.c | 10 ++++++++++
xen/arch/x86/hvm/dm.c | 5 +++++
xen/arch/x86/include/asm/hvm/domain.h | 7 +++++++
xen/include/public/hvm/dm_op.h | 9 +++++++++
5 files changed, 45 insertions(+)
diff --git a/tools/include/xendevicemodel.h b/tools/include/xendevicemodel.h
index 0d5d7b0ff1..270d76fe9c 100644
--- a/tools/include/xendevicemodel.h
+++ b/tools/include/xendevicemodel.h
@@ -412,6 +412,20 @@ int xendevicemodel_unbind_pt_msi_irq(
xendevicemodel_handle *dmod, domid_t domid, uint32_t machine_irq,
uint8_t gvec, uint64_t msi_addr, uint32_t msi_data);
+/**
+ * This function signals to Xen that this device model will use
+ * xendevicemodel_bind_pt_msi_irq() for all passthrough MSI bindings.
+ * After this call, Xen will advertise XEN_HVM_CPUID_EXT_DEST_ID to the
+ * guest, enabling 15-bit destination IDs. Must be called before the
+ * guest vCPUs are started!
+ *
+ * @parm dmod a handle to an open devicemodel interface.
+ * @parm domid the domain id to be serviced.
+ * @return 0 on success, -1 on failure.
+ */
+int xendevicemodel_enable_ext_dest_id(
+ xendevicemodel_handle *dmod, domid_t domid);
+
#endif /* XENDEVICEMODEL_H */
/*
diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
index 4a52fe4750..03838aa37b 100644
--- a/tools/libs/devicemodel/core.c
+++ b/tools/libs/devicemodel/core.c
@@ -689,6 +689,16 @@ int xendevicemodel_unbind_pt_msi_irq(
return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op));
}
+int xendevicemodel_enable_ext_dest_id(
+ xendevicemodel_handle *dmod, domid_t domid)
+{
+ struct xen_dm_op op = {
+ .op = XEN_DMOP_enable_ext_dest_id,
+ };
+
+ return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op));
+}
+
int xendevicemodel_restrict(xendevicemodel_handle *dmod, domid_t domid)
{
return osdep_xendevicemodel_restrict(dmod, domid);
diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index 3d530d948f..7738400540 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -374,6 +374,7 @@ int dm_op(const struct dmop_args *op_args)
[XEN_DMOP_nr_vcpus] = sizeof(struct
xen_dm_op_nr_vcpus),
[XEN_DMOP_bind_pt_msi_irq] = sizeof(struct
xen_dm_op_bind_pt_msi_irq),
[XEN_DMOP_unbind_pt_msi_irq] = sizeof(struct
xen_dm_op_bind_pt_msi_irq),
+ [XEN_DMOP_enable_ext_dest_id] = 0,
};
rc = rcu_lock_remote_domain_by_id(op_args->domid, &d);
@@ -708,6 +709,10 @@ int dm_op(const struct dmop_args *op_args)
break;
}
+ case XEN_DMOP_enable_ext_dest_id:
+ d->arch.hvm.ext_dest_id_enabled = true;
+ break;
+
default:
rc = ioreq_server_dm_op(&op, d, &const_op);
break;
diff --git a/xen/arch/x86/include/asm/hvm/domain.h
b/xen/arch/x86/include/asm/hvm/domain.h
index abf9bc448d..770bc96970 100644
--- a/xen/arch/x86/include/asm/hvm/domain.h
+++ b/xen/arch/x86/include/asm/hvm/domain.h
@@ -105,6 +105,13 @@ struct hvm_domain {
/* Compatibility setting for a bug in x2APIC LDR */
bool bug_x2apic_ldr_vcpu_id;
+ /*
+ * Set by the device model via XEN_DMOP_enable_ext_dest_id to indicate
+ * it uses XEN_DMOP_bind_pt_msi_irq (raw MSI addr/data) for passthrough.
+ * Controls advertisement of XEN_HVM_CPUID_EXT_DEST_ID to the guest.
+ */
+ bool ext_dest_id_enabled;
+
/* hypervisor intercepted msix table */
struct list_head msixtbl_list;
diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
index fd0f3a6a99..2814fe1c3d 100644
--- a/xen/include/public/hvm/dm_op.h
+++ b/xen/include/public/hvm/dm_op.h
@@ -447,6 +447,15 @@ typedef struct xen_dm_op_nr_vcpus xen_dm_op_nr_vcpus_t;
#define XEN_DMOP_bind_pt_msi_irq 21
#define XEN_DMOP_unbind_pt_msi_irq 22
+/*
+ * XEN_DMOP_enable_ext_dest_id: Signal to Xen that this device model will use
+ * XEN_DMOP_bind_pt_msi_irq for all passthrough MSI bindings, passing raw MSI
+ * address/data fields. Once called, Xen will advertise
+ * XEN_HVM_CPUID_EXT_DEST_ID to the guest. Must be called before the guest
+ * starts.
+ */
+#define XEN_DMOP_enable_ext_dest_id 23
+
struct xen_dm_op_bind_pt_msi_irq {
/* IN - physical IRQ (pirq) */
uint32_t machine_irq;
--
2.51.0
--
Julian Vetter | Vates Hypervisor & Kernel Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |