|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v6 04/19] xen/arm: Implement hypercall DOMCTL_{, un}bind_pt_pirq
From: Julien Grall <julien.grall@xxxxxxxxxx>
On x86, an IRQ is assigned in 2 steps to an HVM guest:
- The toolstack is calling PHYSDEVOP_map_pirq in order to create a
guest PIRQ (IRQ bound to an event channel)
- The emulator (QEMU) is calling DOMCTL_bind_pt_irq in order to
bind the IRQ
On ARM, there is no concept of PIRQ as the IRQ can be assigned to a
virtual IRQ using the interrupt controller.
It's not clear if we will need 2 different hypercalls on ARM to assign
IRQ and, for now, only the toolstack will manage IRQ.
In order to avoid re-using a fixed ABI hypercall (PHYSDEVOP_*) for a
different purpose and allow us more time to figure out the right out,
only DOMCTL_{,un}bind_pt_pirq is implemented on ARM.
The DOMCTL is extended with a new type PT_IRQ_TYPE_SPI and only IRQ ==
vIRQ (i.e machine_irq == spi) is supported.
In order to keep the same XSM checks done by the 2 hypercalls on x86,
call both xsm_map_domain_irq & xsm_bind_pt_irq in the ARM implementation.
Note: The toolstack changes for routing an IRQ to a guest will be done
in a separate patch.
Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
Acked-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Cc: Jan Beulich <jbeulich@xxxxxxxx>
---
Contrawise PHYSDEV, DOMCTL interface is not fixed. This version is
using a DOMCTL in order to let us more to to see if we need a new
PHYSDEV op for vIRQ assignation.
DOMCTL_unbind_pt_irq has been implemented, although I haven't test
it. I'm not sure if we want to keep it.
xc_domain_{,un}bind_pt_irq are left unchanged because QEMU upstream
& traditional are using them. I will send a follow-up series to drop this 2
functions in order to avoid defering this series while awaiting
changes pushed for QEMU upstream.
Changes in v6:
- Rebase on the latest staging (conflict in xsm/flask/hooks.c
with memaccess changes)
- Remove obsolete paragraph in the commit message
- Fix indentation in libxc
- Don't rely on vspi == spi in xc_domain_{,un}bind_pt_spi_irq
- Typoes in comment
- Add Daniel's ack (XSM part)
Changes in v5:
- Do the check of XSM PHYSDEVOP_map_pirq in the ARM implementation
- Left xc_domain_{,un}bind_pt_irq unchanged
- Introduce xc_domain_{,un}bind_pt_spi_irq
Changes in v4:
- Move the implementation from PHYSDEV to DOMCTL. Reuse
DOMCTL_{,un}bind_pt_irq for this purpose.
Changes in v3:
- Functions to allocate/release/reserved a VIRQ has been moved
in a separate patch
- Make clear that only MAP_PIRQ_GSI is only supported for now
Changes in v2:
- Add PHYSDEVOP_unmap_pirq
- Rework commit message
- Add functions to allocate/release a VIRQ
- is_routable_irq has been renamed into is_assignable_irq
---
tools/libxc/include/xenctrl.h | 10 ++++++
tools/libxc/xc_domain.c | 60 +++++++++++++++++++++++++++++++--
xen/arch/arm/domctl.c | 78 +++++++++++++++++++++++++++++++++++++++++++
xen/include/public/domctl.h | 4 +++
xen/include/xsm/dummy.h | 24 ++++++-------
xen/include/xsm/xsm.h | 28 ++++++++--------
xen/xsm/dummy.c | 4 +--
xen/xsm/flask/hooks.c | 70 +++++++++++++++++++-------------------
8 files changed, 213 insertions(+), 65 deletions(-)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 6994c51..517a25f 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2115,6 +2115,16 @@ int xc_domain_bind_pt_isa_irq(xc_interface *xch,
uint32_t domid,
uint8_t machine_irq);
+int xc_domain_bind_pt_spi_irq(xc_interface *xch,
+ uint32_t domid,
+ uint16_t vspi,
+ uint16_t spi);
+
+int xc_domain_unbind_pt_spi_irq(xc_interface *xch,
+ uint32_t domid,
+ uint16_t vspi,
+ uint16_t spi);
+
int xc_domain_set_machine_address_size(xc_interface *xch,
uint32_t domid,
unsigned int width);
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index d1dec6c..3ca9215 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1797,7 +1797,7 @@ int xc_domain_unbind_msi_irq(
}
/* Pass-through: binds machine irq to guests irq */
-int xc_domain_bind_pt_irq(
+static int xc_domain_bind_pt_irq_int(
xc_interface *xch,
uint32_t domid,
uint8_t machine_irq,
@@ -1805,7 +1805,8 @@ int xc_domain_bind_pt_irq(
uint8_t bus,
uint8_t device,
uint8_t intx,
- uint8_t isa_irq)
+ uint8_t isa_irq,
+ uint16_t spi)
{
int rc;
xen_domctl_bind_pt_irq_t * bind;
@@ -1829,6 +1830,9 @@ int xc_domain_bind_pt_irq(
case PT_IRQ_TYPE_ISA:
bind->u.isa.isa_irq = isa_irq;
break;
+ case PT_IRQ_TYPE_SPI:
+ bind->u.spi.spi = spi;
+ break;
default:
errno = EINVAL;
return -1;
@@ -1838,7 +1842,7 @@ int xc_domain_bind_pt_irq(
return rc;
}
-int xc_domain_unbind_pt_irq(
+int xc_domain_bind_pt_irq(
xc_interface *xch,
uint32_t domid,
uint8_t machine_irq,
@@ -1848,6 +1852,21 @@ int xc_domain_unbind_pt_irq(
uint8_t intx,
uint8_t isa_irq)
{
+ return xc_domain_bind_pt_irq_int(xch, domid, machine_irq, irq_type,
+ bus, device, intx, isa_irq, 0);
+}
+
+static int xc_domain_unbind_pt_irq_int(
+ xc_interface *xch,
+ uint32_t domid,
+ uint8_t machine_irq,
+ uint8_t irq_type,
+ uint8_t bus,
+ uint8_t device,
+ uint8_t intx,
+ uint8_t isa_irq,
+ uint8_t spi)
+{
int rc;
xen_domctl_bind_pt_irq_t * bind;
DECLARE_DOMCTL;
@@ -1870,6 +1889,8 @@ int xc_domain_unbind_pt_irq(
case PT_IRQ_TYPE_ISA:
bind->u.isa.isa_irq = isa_irq;
break;
+ case PT_IRQ_TYPE_SPI:
+ bind->u.spi.spi = spi;
default:
errno = EINVAL;
return -1;
@@ -1879,6 +1900,20 @@ int xc_domain_unbind_pt_irq(
return rc;
}
+int xc_domain_unbind_pt_irq(
+ xc_interface *xch,
+ uint32_t domid,
+ uint8_t machine_irq,
+ uint8_t irq_type,
+ uint8_t bus,
+ uint8_t device,
+ uint8_t intx,
+ uint8_t isa_irq)
+{
+ return xc_domain_unbind_pt_irq_int(xch, domid, machine_irq, irq_type,
+ bus, device, intx, isa_irq, 0);
+}
+
int xc_domain_bind_pt_pci_irq(
xc_interface *xch,
uint32_t domid,
@@ -1902,6 +1937,25 @@ int xc_domain_bind_pt_isa_irq(
PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq));
}
+int xc_domain_bind_pt_spi_irq(
+ xc_interface *xch,
+ uint32_t domid,
+ uint16_t vspi,
+ uint16_t spi)
+{
+ return (xc_domain_bind_pt_irq_int(xch, domid, vspi,
+ PT_IRQ_TYPE_SPI, 0, 0, 0, 0, spi));
+}
+
+int xc_domain_unbind_pt_spi_irq(xc_interface *xch,
+ uint32_t domid,
+ uint16_t vspi,
+ uint16_t spi)
+{
+ return (xc_domain_unbind_pt_irq_int(xch, domid, vspi,
+ PT_IRQ_TYPE_SPI, 0, 0, 0, 0, spi));
+}
+
int xc_unmap_domain_meminfo(xc_interface *xch, struct xc_domain_meminfo *minfo)
{
struct domain_info_context _di = { .guest_width = minfo->guest_width,
diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index 6f30af7..4600019 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -10,6 +10,8 @@
#include <xen/errno.h>
#include <xen/sched.h>
#include <xen/hypercall.h>
+#include <xen/iocap.h>
+#include <xsm/xsm.h>
#include <public/domctl.h>
long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
@@ -30,6 +32,82 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain
*d,
return p2m_cache_flush(d, s, e);
}
+ case XEN_DOMCTL_bind_pt_irq:
+ {
+ int rc;
+ xen_domctl_bind_pt_irq_t *bind = &domctl->u.bind_pt_irq;
+ uint32_t irq = bind->u.spi.spi;
+ uint32_t virq = bind->machine_irq;
+
+ /* We only support PT_IRQ_TYPE_SPI */
+ if ( bind->irq_type != PT_IRQ_TYPE_SPI )
+ return -EOPNOTSUPP;
+
+ /*
+ * XXX: For now map the interrupt 1:1. Other support will require to
+ * modify domain_pirq_to_irq macro.
+ */
+ if ( irq != virq )
+ return -EINVAL;
+
+ /*
+ * ARM doesn't require separating IRQ assignation into 2
+ * hypercalls (PHYSDEVOP_map_pirq and DOMCTL_bind_pt_irq).
+ *
+ * Call xsm_map_domain_irq in order to keep the same XSM checks
+ * done by the 2 hypercalls for consistency with other
+ * architectures.
+ */
+ rc = xsm_map_domain_irq(XSM_HOOK, d, irq, NULL);
+ if ( rc )
+ return rc;
+
+ rc = xsm_bind_pt_irq(XSM_HOOK, d, bind);
+ if ( rc )
+ return rc;
+
+ if ( !irq_access_permitted(current->domain, irq) )
+ return -EPERM;
+
+ if ( !vgic_reserve_virq(d, virq) )
+ return -EBUSY;
+
+ rc = route_irq_to_guest(d, virq, irq, "routed IRQ");
+ if ( rc )
+ vgic_free_virq(d, virq);
+
+ return rc;
+ }
+ case XEN_DOMCTL_unbind_pt_irq:
+ {
+ int rc;
+ xen_domctl_bind_pt_irq_t *bind = &domctl->u.bind_pt_irq;
+ uint32_t irq = bind->u.spi.spi;
+ uint32_t virq = bind->machine_irq;
+
+ /* We only support PT_IRQ_TYPE_SPI */
+ if ( bind->irq_type != PT_IRQ_TYPE_SPI )
+ return -EOPNOTSUPP;
+
+ /* For now map the interrupt 1:1 */
+ if ( irq != virq )
+ return -EINVAL;
+
+ rc = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
+ if ( rc )
+ return rc;
+
+ if ( !irq_access_permitted(current->domain, irq) )
+ return -EPERM;
+
+ rc = release_guest_irq(d, virq);
+ if ( rc )
+ return rc;
+
+ vgic_free_virq(d, virq);
+
+ return 0;
+ }
default:
return subarch_do_domctl(domctl, d, u_domctl);
}
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 10b51ef..35ed4f2 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -504,6 +504,7 @@ typedef enum pt_irq_type_e {
PT_IRQ_TYPE_ISA,
PT_IRQ_TYPE_MSI,
PT_IRQ_TYPE_MSI_TRANSLATE,
+ PT_IRQ_TYPE_SPI, /* ARM: valid range 32-1019 */
} pt_irq_type_t;
struct xen_domctl_bind_pt_irq {
uint32_t machine_irq;
@@ -524,6 +525,9 @@ struct xen_domctl_bind_pt_irq {
uint32_t gflags;
uint64_aligned_t gtable;
} msi;
+ struct {
+ uint16_t spi;
+ } spi;
} u;
};
typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t;
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 16967ed..faeb096 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -445,6 +445,18 @@ static XSM_INLINE int
xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
return xsm_default_action(action, current->domain, d);
}
+static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct
xen_domctl_bind_pt_irq *bind)
+{
+ XSM_ASSERT_ACTION(XSM_HOOK);
+ return xsm_default_action(action, current->domain, d);
+}
+
+static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d,
struct xen_domctl_bind_pt_irq *bind)
+{
+ XSM_ASSERT_ACTION(XSM_HOOK);
+ return xsm_default_action(action, current->domain, d);
+}
+
static XSM_INLINE int xsm_unmap_domain_irq(XSM_DEFAULT_ARG struct domain *d,
int irq, void *data)
{
XSM_ASSERT_ACTION(XSM_HOOK);
@@ -647,18 +659,6 @@ static XSM_INLINE int xsm_priv_mapping(XSM_DEFAULT_ARG
struct domain *d, struct
return xsm_default_action(action, d, t);
}
-static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct
xen_domctl_bind_pt_irq *bind)
-{
- XSM_ASSERT_ACTION(XSM_HOOK);
- return xsm_default_action(action, current->domain, d);
-}
-
-static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d,
struct xen_domctl_bind_pt_irq *bind)
-{
- XSM_ASSERT_ACTION(XSM_HOOK);
- return xsm_default_action(action, current->domain, d);
-}
-
static XSM_INLINE int xsm_ioport_permission(XSM_DEFAULT_ARG struct domain *d,
uint32_t s, uint32_t e, uint8_t allow)
{
XSM_ASSERT_ACTION(XSM_HOOK);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 49f06c9..bbd4a18 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -107,6 +107,8 @@ struct xsm_operations {
int (*map_domain_irq) (struct domain *d, int irq, void *data);
int (*unmap_domain_pirq) (struct domain *d);
int (*unmap_domain_irq) (struct domain *d, int irq, void *data);
+ int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind);
+ int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq
*bind);
int (*irq_permission) (struct domain *d, int pirq, uint8_t allow);
int (*iomem_permission) (struct domain *d, uint64_t s, uint64_t e, uint8_t
allow);
int (*iomem_mapping) (struct domain *d, uint64_t s, uint64_t e, uint8_t
allow);
@@ -178,8 +180,6 @@ struct xsm_operations {
int (*mmuext_op) (struct domain *d, struct domain *f);
int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t
pte);
int (*priv_mapping) (struct domain *d, struct domain *t);
- int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind);
- int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq
*bind);
int (*ioport_permission) (struct domain *d, uint32_t s, uint32_t e,
uint8_t allow);
int (*ioport_mapping) (struct domain *d, uint32_t s, uint32_t e, uint8_t
allow);
#endif
@@ -428,6 +428,18 @@ static inline int xsm_unmap_domain_irq (xsm_default_t def,
struct domain *d, int
return xsm_ops->unmap_domain_irq(d, irq, data);
}
+static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d,
+ struct xen_domctl_bind_pt_irq *bind)
+{
+ return xsm_ops->bind_pt_irq(d, bind);
+}
+
+static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d,
+ struct xen_domctl_bind_pt_irq *bind)
+{
+ return xsm_ops->unbind_pt_irq(d, bind);
+}
+
static inline int xsm_irq_permission (xsm_default_t def, struct domain *d, int
pirq, uint8_t allow)
{
return xsm_ops->irq_permission(d, pirq, allow);
@@ -666,18 +678,6 @@ static inline int xsm_priv_mapping(xsm_default_t def,
struct domain *d, struct d
return xsm_ops->priv_mapping(d, t);
}
-static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d,
- struct xen_domctl_bind_pt_irq
*bind)
-{
- return xsm_ops->bind_pt_irq(d, bind);
-}
-
-static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d,
- struct xen_domctl_bind_pt_irq
*bind)
-{
- return xsm_ops->unbind_pt_irq(d, bind);
-}
-
static inline int xsm_ioport_permission (xsm_default_t def, struct domain *d,
uint32_t s, uint32_t e, uint8_t allow)
{
return xsm_ops->ioport_permission(d, s, e, allow);
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 3ddb4f6..041ccf9 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -81,6 +81,8 @@ void xsm_fixup_ops (struct xsm_operations *ops)
set_to_dummy_if_null(ops, map_domain_irq);
set_to_dummy_if_null(ops, unmap_domain_pirq);
set_to_dummy_if_null(ops, unmap_domain_irq);
+ set_to_dummy_if_null(ops, bind_pt_irq);
+ set_to_dummy_if_null(ops, unbind_pt_irq);
set_to_dummy_if_null(ops, irq_permission);
set_to_dummy_if_null(ops, iomem_permission);
set_to_dummy_if_null(ops, iomem_mapping);
@@ -149,8 +151,6 @@ void xsm_fixup_ops (struct xsm_operations *ops)
set_to_dummy_if_null(ops, mmuext_op);
set_to_dummy_if_null(ops, update_va_mapping);
set_to_dummy_if_null(ops, priv_mapping);
- set_to_dummy_if_null(ops, bind_pt_irq);
- set_to_dummy_if_null(ops, unbind_pt_irq);
set_to_dummy_if_null(ops, ioport_permission);
set_to_dummy_if_null(ops, ioport_mapping);
#endif
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 6215001..29865d2 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -578,12 +578,14 @@ static int flask_domctl(struct domain *d, int cmd)
case XEN_DOMCTL_memory_mapping:
case XEN_DOMCTL_set_target:
case XEN_DOMCTL_vm_event_op:
+
+ /* These have individual XSM hooks (arch/../domctl.c) */
+ case XEN_DOMCTL_bind_pt_irq:
+ case XEN_DOMCTL_unbind_pt_irq:
#ifdef CONFIG_X86
/* These have individual XSM hooks (arch/x86/domctl.c) */
case XEN_DOMCTL_shadow_op:
case XEN_DOMCTL_ioport_permission:
- case XEN_DOMCTL_bind_pt_irq:
- case XEN_DOMCTL_unbind_pt_irq:
case XEN_DOMCTL_ioport_mapping:
/* These have individual XSM hooks (drivers/passthrough/iommu.c) */
case XEN_DOMCTL_get_device_group:
@@ -912,6 +914,36 @@ static int flask_unmap_domain_irq (struct domain *d, int
irq, void *data)
return rc;
}
+static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq
*bind)
+{
+ u32 dsid, rsid;
+ int rc = -EPERM;
+ int irq;
+ struct avc_audit_data ad;
+
+ rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
+ if ( rc )
+ return rc;
+
+ irq = domain_pirq_to_irq(d, bind->machine_irq);
+
+ rc = get_irq_sid(irq, &rsid, &ad);
+ if ( rc )
+ return rc;
+
+ rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad);
+ if ( rc )
+ return rc;
+
+ dsid = domain_sid(d);
+ return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
+}
+
+static int flask_unbind_pt_irq (struct domain *d, struct
xen_domctl_bind_pt_irq *bind)
+{
+ return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
+}
+
static int flask_irq_permission (struct domain *d, int pirq, uint8_t access)
{
/* the PIRQ number is not useful; real IRQ is checked during mapping */
@@ -1483,36 +1515,6 @@ static int flask_priv_mapping(struct domain *d, struct
domain *t)
{
return domain_has_perm(d, t, SECCLASS_MMU, MMU__TARGET_HACK);
}
-
-static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq
*bind)
-{
- u32 dsid, rsid;
- int rc = -EPERM;
- int irq;
- struct avc_audit_data ad;
-
- rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
- if ( rc )
- return rc;
-
- irq = domain_pirq_to_irq(d, bind->machine_irq);
-
- rc = get_irq_sid(irq, &rsid, &ad);
- if ( rc )
- return rc;
-
- rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad);
- if ( rc )
- return rc;
-
- dsid = domain_sid(d);
- return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
-}
-
-static int flask_unbind_pt_irq (struct domain *d, struct
xen_domctl_bind_pt_irq *bind)
-{
- return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
-}
#endif /* CONFIG_X86 */
long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op);
@@ -1571,6 +1573,8 @@ static struct xsm_operations flask_ops = {
.map_domain_irq = flask_map_domain_irq,
.unmap_domain_pirq = flask_unmap_domain_pirq,
.unmap_domain_irq = flask_unmap_domain_irq,
+ .bind_pt_irq = flask_bind_pt_irq,
+ .unbind_pt_irq = flask_unbind_pt_irq,
.irq_permission = flask_irq_permission,
.iomem_permission = flask_iomem_permission,
.iomem_mapping = flask_iomem_mapping,
@@ -1640,8 +1644,6 @@ static struct xsm_operations flask_ops = {
.mmuext_op = flask_mmuext_op,
.update_va_mapping = flask_update_va_mapping,
.priv_mapping = flask_priv_mapping,
- .bind_pt_irq = flask_bind_pt_irq,
- .unbind_pt_irq = flask_unbind_pt_irq,
.ioport_permission = flask_ioport_permission,
.ioport_mapping = flask_ioport_mapping,
#endif
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |