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

[PATCH v5 09/11] x86/dmop: Add XEN_DMOP_{,un}bind_pt_msi_irq



Add two device-model ops that bind / unbind a passthrough interrupt to a
guest MSI from the raw MSI message (address + data) the guest
programmed. Xen decodes the message itself via pt_irq_bind_msi(), so the
emulator needs no knowledge of the MSI layout and, in particular,
extended (15-bit) destination IDs are handled without emulator changes.

The MSI-X table base is passed as a guest-physical address. Fields are
named msg_addr / msg_data / pirq, and the flag is
XEN_DMOP_MSI_BIND_UNMASKED. The unbind op only requires a valid pirq
mapping, not current IRQ permission, so an emulator can remove a binding
even after the device has been deassigned.

With this in place, PT_IRQ_TYPE_MSI is removed from
XEN_DOMCTL_{,un}bind_pt_irq (returns -EINVAL) and from
pt_irq_create_bind(). libxc's xc_domain_{update,unbind}_msi_irq() and
vPCI already funnel through pt_irq_bind_msi(). This is an incompatible
change for device models still using the domctl sub-case (noted in
CHANGELOG.md and public/domctl.h).

libxendevicemodel gains xendevicemodel_{,un}bind_pt_msi_irq() (map
version VERS_1.5).

Signed-off-by: Julian Vetter <julian.vetter@xxxxxxxxxx>
---
Changes in v5:
- Retitled to "{,un}bind_pt_msi_irq".
- Struct/flag renamed: pirq (was machine_irq), msg_addr / msg_data (was
  addr / data), XEN_DMOP_MSI_BIND_UNMASKED (was
  XEN_DMOP_MSI_FLAG_UNMASKED).
- Documented gtable as a guest-physical address.
- Diagnostics shortened to "%pd: fn() failed: %ld".
- The unbind op drops the current-domain IRQ-permission check, so an
  emulator can unbind after the device has been deassigned.
- Comment added noting access is gated by xsm_dm_op().
- This patch now also removes PT_IRQ_TYPE_MSI: a hard -EINVAL from
  XEN_DOMCTL_{,un}bind_pt_irq (not -EOPNOTSUPP) and deletion of the
  now-dead case from pt_irq_create_bind()
- Incompatible changes are recorded in CHANGELOG.md and public/domctl.h.
- Added the missing libxendevicemodel.map VERS_1.5 entry and Makefile
  MINOR bump. v4 never exported the new symbols.
- Stale XEN_DMOP_enable_ext_dest_id #define and a stray blank line
  before a typedef removed.

Signed-off-by: Julian Vetter <julian.vetter@xxxxxxxxxx>
---
 CHANGELOG.md                                 |  6 ++
 tools/include/xendevicemodel.h               | 30 +++++++++
 tools/libs/ctrl/xc_domain.c                  | 51 +++++++--------
 tools/libs/devicemodel/Makefile              |  2 +-
 tools/libs/devicemodel/core.c                | 38 +++++++++++
 tools/libs/devicemodel/libxendevicemodel.map |  6 ++
 xen/arch/x86/domctl.c                        | 11 +++-
 xen/arch/x86/hvm/dm.c                        | 66 ++++++++++++++++++++
 xen/drivers/passthrough/x86/hvm.c            | 35 +----------
 xen/include/public/hvm/dm_op.h               | 38 +++++++++++
 xen/include/xlat.lst                         |  2 +
 11 files changed, 221 insertions(+), 64 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa1a777dd4..76f5d06c91 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,9 @@ The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/)
  - On x86:
    - Enable pf-fixup option by default for PVH dom0.
    - The libxenguest bzImage loader now uses the system liblz4 library.
+   - XEN_DOMCTL_{,un}bind_pt_irq no longer accept PT_IRQ_TYPE_MSI, device
+     models must bind passthrough MSIs via the new
+     XEN_DMOP_{,un}bind_pt_msi_irq, which carry the raw MSI message.
 
 ### Added
  - Support for per-domain Xenstore quota in C xenstored (includes
@@ -47,6 +50,9 @@ The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/)
    - Support for CPIO microcode in discrete multiboot modules.
    - Introduce get-core-temp command to xenpm to query CPU temperatures on
      Intel platforms.
+   - XEN_DMOP_{,un}bind_pt_msi_irq for binding passthrough MSIs from the raw
+     guest MSI message, enabling extended (15-bit) destination IDs for HVM
+     guests whose device models opt in.
 
  - On Arm:
    - Support for guest suspend and resume to/from RAM via vPSCI.
diff --git a/tools/include/xendevicemodel.h b/tools/include/xendevicemodel.h
index 227e7fd810..698d719119 100644
--- a/tools/include/xendevicemodel.h
+++ b/tools/include/xendevicemodel.h
@@ -375,6 +375,36 @@ int xendevicemodel_nr_vcpus(
  */
 int xendevicemodel_restrict(xendevicemodel_handle *dmod, domid_t domid);
 
+/**
+ * This function binds a passthrough interrupt to a guest MSI, described by the
+ * raw MSI message (address and data) the guest programmed. Xen decodes the
+ * message itself, so the caller does not need to interpret it.
+ *
+ * @parm dmod a handle to an open devicemodel interface.
+ * @parm domid the domain id to be serviced.
+ * @parm pirq the pass-through IRQ (pirq).
+ * @parm msg_addr the MSI message address, as programmed by the guest.
+ * @parm msg_data the MSI message data, as programmed by the guest.
+ * @parm gtable the MSI-X table base guest-physical address, or 0 for plain 
MSI.
+ * @parm unmasked if non-zero, leave the IRQ unmasked after binding.
+ * @return 0 on success, -1 on failure.
+ */
+int xendevicemodel_bind_pt_msi_irq(
+    xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq,
+    uint64_t msg_addr, uint32_t msg_data, uint64_t gtable, int unmasked);
+
+/**
+ * This function unbinds a passthrough interrupt previously bound with
+ * xendevicemodel_bind_pt_msi_irq.
+ *
+ * @parm dmod a handle to an open devicemodel interface.
+ * @parm domid the domain id to be serviced.
+ * @parm pirq the pass-through IRQ (pirq).
+ * @return 0 on success, -1 on failure.
+ */
+int xendevicemodel_unbind_pt_msi_irq(
+    xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq);
+
 #endif /* XENDEVICEMODEL_H */
 
 /*
diff --git a/tools/libs/ctrl/xc_domain.c b/tools/libs/ctrl/xc_domain.c
index 94cfab0fa1..b4eed42f97 100644
--- a/tools/libs/ctrl/xc_domain.c
+++ b/tools/libs/ctrl/xc_domain.c
@@ -1677,6 +1677,21 @@ int xc_deassign_dt_device(
 
 
 
+static void xc_msi_gflags_to_addr_data(uint32_t gvec, uint32_t gflags,
+                                        uint64_t *msi_addr, uint32_t *msi_data)
+{
+    *msi_addr = 0xfee00000U |
+        ((uint64_t)((gflags & XEN_DOMCTL_VMSI_X86_DEST_ID_MASK) << 12)) |
+        (gflags & XEN_DOMCTL_VMSI_X86_RH_MASK ? (1U << 3) : 0) |
+        (gflags & XEN_DOMCTL_VMSI_X86_DM_MASK ? (1U << 2) : 0);
+
+    *msi_data = (gvec & 0xff) |
+        (uint32_t)(((gflags & XEN_DOMCTL_VMSI_X86_DELIV_MASK) >>
+                    (/* shift of XEN_DOMCTL_VMSI_X86_DELIV_MASK */ 12 -
+                     /* MSI data delivery shift */ 8))) |
+        (gflags & XEN_DOMCTL_VMSI_X86_TRIG_MASK ? (1U << 15) : 0);
+}
+
 int xc_domain_update_msi_irq(
     xc_interface *xch,
     uint32_t domid,
@@ -1685,22 +1700,14 @@ int xc_domain_update_msi_irq(
     uint32_t gflags,
     uint64_t gtable)
 {
-    int rc;
-    struct xen_domctl_bind_pt_irq *bind;
-    struct xen_domctl domctl = {};
-
-    domctl.cmd = XEN_DOMCTL_bind_pt_irq;
-    domctl.domain = domid;
+    uint64_t msi_addr;
+    uint32_t msi_data;
 
-    bind = &(domctl.u.bind_pt_irq);
-    bind->irq_type = PT_IRQ_TYPE_MSI;
-    bind->machine_irq = pirq;
-    bind->u.msi.gvec = gvec;
-    bind->u.msi.gflags = gflags;
-    bind->u.msi.gtable = gtable;
+    xc_msi_gflags_to_addr_data(gvec, gflags, &msi_addr, &msi_data);
 
-    rc = do_domctl(xch, &domctl);
-    return rc;
+    return xendevicemodel_bind_pt_msi_irq(xch->dmod, domid, pirq,
+                                          msi_addr, msi_data, gtable,
+                                          gflags & 
XEN_DOMCTL_VMSI_X86_UNMASKED);
 }
 
 int xc_domain_unbind_msi_irq(
@@ -1710,21 +1717,7 @@ int xc_domain_unbind_msi_irq(
     uint32_t pirq,
     uint32_t gflags)
 {
-    int rc;
-    struct xen_domctl_bind_pt_irq *bind;
-    struct xen_domctl domctl = {};
-
-    domctl.cmd = XEN_DOMCTL_unbind_pt_irq;
-    domctl.domain = domid;
-
-    bind = &(domctl.u.bind_pt_irq);
-    bind->irq_type = PT_IRQ_TYPE_MSI;
-    bind->machine_irq = pirq;
-    bind->u.msi.gvec = gvec;
-    bind->u.msi.gflags = gflags;
-
-    rc = do_domctl(xch, &domctl);
-    return rc;
+    return xendevicemodel_unbind_pt_msi_irq(xch->dmod, domid, pirq);
 }
 
 /* Pass-through: binds machine irq to guests irq */
diff --git a/tools/libs/devicemodel/Makefile b/tools/libs/devicemodel/Makefile
index 20d1d112e7..270bb6c89f 100644
--- a/tools/libs/devicemodel/Makefile
+++ b/tools/libs/devicemodel/Makefile
@@ -2,7 +2,7 @@ XEN_ROOT = $(CURDIR)/../../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 MAJOR    = 1
-MINOR    = 4
+MINOR    = 5
 version-script := libxendevicemodel.map
 
 include Makefile.common
diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
index 8e619eeb0a..274a8eb28b 100644
--- a/tools/libs/devicemodel/core.c
+++ b/tools/libs/devicemodel/core.c
@@ -645,6 +645,44 @@ int xendevicemodel_nr_vcpus(
     return 0;
 }
 
+int xendevicemodel_bind_pt_msi_irq(
+    xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq,
+    uint64_t msg_addr, uint32_t msg_data, uint64_t gtable, int unmasked)
+{
+    struct xen_dm_op op;
+    struct xen_dm_op_bind_pt_msi_irq *data;
+
+    memset(&op, 0, sizeof(op));
+
+    op.op = XEN_DMOP_bind_pt_msi_irq;
+    data = &op.u.bind_pt_msi_irq;
+
+    data->pirq = pirq;
+    data->msg_data = msg_data;
+    data->msg_addr = msg_addr;
+    data->gtable = gtable;
+    if ( unmasked )
+        data->flags |= XEN_DMOP_MSI_BIND_UNMASKED;
+
+    return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op));
+}
+
+int xendevicemodel_unbind_pt_msi_irq(
+    xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq)
+{
+    struct xen_dm_op op;
+    struct xen_dm_op_unbind_pt_msi_irq *data;
+
+    memset(&op, 0, sizeof(op));
+
+    op.op = XEN_DMOP_unbind_pt_msi_irq;
+    data = &op.u.unbind_pt_msi_irq;
+
+    data->pirq = pirq;
+
+    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/tools/libs/devicemodel/libxendevicemodel.map 
b/tools/libs/devicemodel/libxendevicemodel.map
index f7f9e3d932..c34b66004e 100644
--- a/tools/libs/devicemodel/libxendevicemodel.map
+++ b/tools/libs/devicemodel/libxendevicemodel.map
@@ -44,3 +44,9 @@ VERS_1.4 {
                xendevicemodel_set_irq_level;
                xendevicemodel_nr_vcpus;
 } VERS_1.3;
+
+VERS_1.5 {
+       global:
+               xendevicemodel_bind_pt_msi_irq;
+               xendevicemodel_unbind_pt_msi_irq;
+} VERS_1.4;
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 51d62617bb..9846df4f88 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -622,6 +622,15 @@ long arch_do_domctl(
         if ( !is_hvm_domain(d) )
             break;
 
+        /*
+         * PT_IRQ_TYPE_MSI is no longer supported here: it can only convey an
+         * 8-bit destination ID. Emulators must use XEN_DMOP_bind_pt_msi_irq,
+         * which passes the raw MSI message so Xen can decode it (extended
+         * destination IDs included).
+         */
+        if ( bind->irq_type == PT_IRQ_TYPE_MSI )
+            break;
+
         ret = xsm_bind_pt_irq(XSM_DM_PRIV, d, bind);
         if ( ret )
             break;
@@ -657,7 +666,7 @@ long arch_do_domctl(
         int irq = domain_pirq_to_irq(d, bind->machine_irq);
 
         ret = -EINVAL;
-        if ( !is_hvm_domain(d) )
+        if ( !is_hvm_domain(d) || bind->irq_type == PT_IRQ_TYPE_MSI )
             break;
 
         ret = xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind);
diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index 91f6ca669b..9a6347e873 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -7,6 +7,8 @@
 #include <xen/guest_access.h>
 #include <xen/dm.h>
 #include <xen/hypercall.h>
+#include <xen/iocap.h>
+#include <xen/iommu.h>
 #include <xen/ioreq.h>
 #include <xen/nospec.h>
 #include <xen/sched.h>
@@ -350,6 +352,8 @@ int dm_op(const struct dmop_args *op_args)
         [XEN_DMOP_relocate_memory]                  = sizeof(struct 
xen_dm_op_relocate_memory),
         [XEN_DMOP_pin_memory_cacheattr]             = sizeof(struct 
xen_dm_op_pin_memory_cacheattr),
         [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_unbind_pt_msi_irq),
     };
 
     rc = rcu_lock_remote_domain_by_id(op_args->domid, &d);
@@ -617,6 +621,66 @@ int dm_op(const struct dmop_args *op_args)
         break;
     }
 
+    case XEN_DMOP_bind_pt_msi_irq:
+    {
+        const struct xen_dm_op_bind_pt_msi_irq *data = &op.u.bind_pt_msi_irq;
+        int irq = domain_pirq_to_irq(d, data->pirq);
+
+        rc = -EINVAL;
+        if ( data->pad || (data->flags & ~XEN_DMOP_MSI_BIND_UNMASKED) )
+            break;
+
+        /* Access is otherwise gated by xsm_dm_op() at the top of dm_op(). */
+        rc = -EPERM;
+        if ( irq <= 0 || !irq_access_permitted(current->domain, irq) )
+            break;
+
+        rc = -ESRCH;
+        if ( is_iommu_enabled(d) )
+        {
+            read_lock(&d->pci_lock);
+            rc = pt_irq_bind_msi(d, data->pirq, data->msg_addr, data->msg_data,
+                                 data->gtable,
+                                 data->flags & XEN_DMOP_MSI_BIND_UNMASKED);
+            read_unlock(&d->pci_lock);
+        }
+        if ( rc < 0 )
+            printk(XENLOG_G_ERR "%pd: pt_irq_bind_msi() failed: %ld\n", d, rc);
+        break;
+    }
+
+    case XEN_DMOP_unbind_pt_msi_irq:
+    {
+        const struct xen_dm_op_unbind_pt_msi_irq *data =
+            &op.u.unbind_pt_msi_irq;
+        struct xen_domctl_bind_pt_irq bind = {
+            .machine_irq = data->pirq,
+            .irq_type = PT_IRQ_TYPE_MSI,
+        };
+        int irq = domain_pirq_to_irq(d, data->pirq);
+
+        /*
+         * Only require a valid pirq mapping, not current permission over it:
+         * the emulator must be able to tear the binding down even after the
+         * device (and its IRQ) has been deassigned.
+         */
+        rc = -EPERM;
+        if ( irq <= 0 )
+            break;
+
+        rc = -ESRCH;
+        if ( is_iommu_enabled(d) )
+        {
+            read_lock(&d->pci_lock);
+            rc = pt_irq_destroy_bind(d, &bind);
+            read_unlock(&d->pci_lock);
+        }
+        if ( rc < 0 )
+            printk(XENLOG_G_ERR "%pd: pt_irq_destroy_bind() failed: %ld\n",
+                   d, rc);
+        break;
+    }
+
     default:
         rc = ioreq_server_dm_op(&op, d, &const_op);
         break;
@@ -653,6 +717,8 @@ CHECK_dm_op_remote_shutdown;
 CHECK_dm_op_relocate_memory;
 CHECK_dm_op_pin_memory_cacheattr;
 CHECK_dm_op_nr_vcpus;
+CHECK_dm_op_bind_pt_msi_irq;
+CHECK_dm_op_unbind_pt_msi_irq;
 
 int compat_dm_op(
     domid_t domid, unsigned int nr_bufs, XEN_GUEST_HANDLE_PARAM(void) bufs)
diff --git a/xen/drivers/passthrough/x86/hvm.c 
b/xen/drivers/passthrough/x86/hvm.c
index a13dd86610..c5d74fcebf 100644
--- a/xen/drivers/passthrough/x86/hvm.c
+++ b/xen/drivers/passthrough/x86/hvm.c
@@ -449,37 +449,6 @@ int pt_irq_create_bind(
 
     switch ( pt_irq_bind->irq_type )
     {
-    case PT_IRQ_TYPE_MSI:
-    {
-        unsigned int gflags = pt_irq_bind->u.msi.gflags;
-        uint64_t msi_addr;
-        uint32_t msi_data;
-
-        /*
-         * Rebuild a raw MSI message from the pre-decoded domctl gflags so the
-         * canonical bind path can decode it uniformly. This legacy path never
-         * carries extended destination ID bits.
-         */
-        msi_addr = MSI_ADDR_HEADER |
-                   MASK_INSR(MASK_EXTR(gflags, 
XEN_DOMCTL_VMSI_X86_DEST_ID_MASK),
-                             MSI_ADDR_DEST_ID_MASK) |
-                   (gflags & XEN_DOMCTL_VMSI_X86_RH_MASK
-                    ? MSI_ADDR_REDIRECTION_LOWPRI
-                    : MSI_ADDR_REDIRECTION_CPU) |
-                   (gflags & XEN_DOMCTL_VMSI_X86_DM_MASK
-                    ? MSI_ADDR_DESTMODE_LOGIC
-                    : MSI_ADDR_DESTMODE_PHYS);
-        msi_data = MASK_INSR(pt_irq_bind->u.msi.gvec, MSI_DATA_VECTOR_MASK) |
-                   MASK_INSR(MASK_EXTR(gflags, XEN_DOMCTL_VMSI_X86_DELIV_MASK),
-                             MSI_DATA_DELIVERY_MODE_MASK) |
-                   (gflags & XEN_DOMCTL_VMSI_X86_TRIG_MASK
-                    ? MSI_DATA_TRIGGER_LEVEL : 0);
-
-        return pt_irq_bind_msi(d, pt_irq_bind->machine_irq, msi_addr, msi_data,
-                               pt_irq_bind->u.msi.gtable,
-                               gflags & XEN_DOMCTL_VMSI_X86_UNMASKED);
-    }
-
     case PT_IRQ_TYPE_PCI:
     case PT_IRQ_TYPE_MSI_TRANSLATE:
     {
@@ -767,8 +736,8 @@ int pt_irq_destroy_bind(
         msixtbl_pt_unregister(d, pirq);
         pirq_dpci->flags = 0;
         /*
-         * See comment in pt_irq_create_bind's PT_IRQ_TYPE_MSI before the
-         * call to pt_pirq_softirq_reset.
+         * See the comment in pt_irq_bind_msi() before its call to
+         * pt_pirq_softirq_reset.
          */
         pt_pirq_softirq_reset(pirq_dpci);
 
diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
index 2bf0fdc1ae..d76777f71f 100644
--- a/xen/include/public/hvm/dm_op.h
+++ b/xen/include/public/hvm/dm_op.h
@@ -444,6 +444,42 @@ struct xen_dm_op_nr_vcpus {
 };
 typedef struct xen_dm_op_nr_vcpus xen_dm_op_nr_vcpus_t;
 
+/*
+ * XEN_DMOP_bind_pt_msi_irq: bind a passthrough interrupt to a guest MSI,
+ * described by the raw MSI message (address and data) the guest programmed.
+ * Xen decodes the message itself, so the emulator does not need to know the
+ * MSI layout and, in particular, extended destination IDs are handled
+ * transparently.
+ */
+#define XEN_DMOP_bind_pt_msi_irq   21
+
+struct xen_dm_op_bind_pt_msi_irq {
+    /* IN - pirq */
+    uint32_t pirq;
+    /* IN - MSI message data word */
+    uint32_t msg_data;
+    /* IN - bind flags */
+    uint32_t flags;
+#define XEN_DMOP_MSI_BIND_UNMASKED (1u << 0)
+    uint32_t pad;
+    /* IN - MSI message address */
+    uint64_aligned_t msg_addr;
+    /* IN - MSI-X table base address (guest physical), 0 for plain MSI */
+    uint64_aligned_t gtable;
+};
+typedef struct xen_dm_op_bind_pt_msi_irq xen_dm_op_bind_pt_msi_irq_t;
+
+/*
+ * XEN_DMOP_unbind_pt_msi_irq: undo a previous XEN_DMOP_bind_pt_msi_irq.
+ */
+#define XEN_DMOP_unbind_pt_msi_irq 22
+
+struct xen_dm_op_unbind_pt_msi_irq {
+    /* IN - pirq */
+    uint32_t pirq;
+};
+typedef struct xen_dm_op_unbind_pt_msi_irq xen_dm_op_unbind_pt_msi_irq_t;
+
 struct xen_dm_op {
     uint32_t op;
     uint32_t pad;
@@ -468,6 +504,8 @@ struct xen_dm_op {
         xen_dm_op_relocate_memory_t relocate_memory;
         xen_dm_op_pin_memory_cacheattr_t pin_memory_cacheattr;
         xen_dm_op_nr_vcpus_t nr_vcpus;
+        xen_dm_op_bind_pt_msi_irq_t bind_pt_msi_irq;
+        xen_dm_op_unbind_pt_msi_irq_t unbind_pt_msi_irq;
     } u;
 };
 
diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst
index 33dc8e2b2a..7255f4c65d 100644
--- a/xen/include/xlat.lst
+++ b/xen/include/xlat.lst
@@ -98,6 +98,7 @@
 ?      grant_entry_v2                  grant_table.h
 
 !      dm_op_buf                       hvm/dm_op.h
+?      dm_op_bind_pt_msi_irq           hvm/dm_op.h
 ?      dm_op_create_ioreq_server       hvm/dm_op.h
 ?      dm_op_destroy_ioreq_server      hvm/dm_op.h
 ?      dm_op_get_ioreq_server_info     hvm/dm_op.h
@@ -116,6 +117,7 @@
 ?      dm_op_set_pci_intx_level        hvm/dm_op.h
 ?      dm_op_set_pci_link_route        hvm/dm_op.h
 ?      dm_op_track_dirty_vram          hvm/dm_op.h
+?      dm_op_unbind_pt_msi_irq         hvm/dm_op.h
 
 !      hvm_altp2m_set_mem_access_multi hvm/hvm_op.h
 
-- 
2.53.0



--
Julian Vetter | Vates Hypervisor & Kernel Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

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