aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_misc.c
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-11-21 19:22:25 +0000
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-11-21 19:22:25 +0000
commitd46c9ce0d7b805e6b4bbf54b381728a391e23e45 (patch)
treeea5cbf1372bb5d4f2dbc953eb70a84a90f4cc7d0 /tools/libxc/xc_misc.c
parent3b724073d6a410b5a967a6827d2f8c50693aadfb (diff)
downloadxen-d46c9ce0d7b805e6b4bbf54b381728a391e23e45.tar.gz
xen-d46c9ce0d7b805e6b4bbf54b381728a391e23e45.tar.bz2
xen-d46c9ce0d7b805e6b4bbf54b381728a391e23e45.zip
[HVM] Reworked interrupt distribution logic.
TODO: 1. Fix IO-APIC ID to not conflict with LAPIC IDS. 2. Fix i8259 device model (seems to work already though!). 3. Add INTSRC overrides in MPBIOS and ACPI tables so that PCI legacy IRQ routing always ends up at an IO-APIC input with level trigger. Restricting link routing to {5,6,10,11} and setting overrides for all four of those would work. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'tools/libxc/xc_misc.c')
-rw-r--r--tools/libxc/xc_misc.c76
1 files changed, 70 insertions, 6 deletions
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index b1924611c3..216dff94f8 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -90,19 +90,83 @@ int xc_perfc_control(int xc_handle,
return rc;
}
-int xc_hvm_set_irq_level(int xc_handle, domid_t dom, int irq, int level)
+int xc_hvm_set_pci_intx_level(
+ int xc_handle, domid_t dom,
+ uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
+ unsigned int level)
{
DECLARE_HYPERCALL;
- struct xen_hvm_set_irq_level arg;
+ struct xen_hvm_set_pci_intx_level arg;
int rc;
hypercall.op = __HYPERVISOR_hvm_op;
- hypercall.arg[0] = HVMOP_set_irq_level;
+ hypercall.arg[0] = HVMOP_set_pci_intx_level;
hypercall.arg[1] = (unsigned long)&arg;
- arg.domid = dom;
- arg.irq = irq;
- arg.level = level;
+ arg.domid = dom;
+ arg.domain = domain;
+ arg.bus = bus;
+ arg.device = device;
+ arg.intx = intx;
+ arg.level = level;
+
+ if ( mlock(&arg, sizeof(arg)) != 0 )
+ {
+ PERROR("Could not lock memory");
+ return -1;
+ }
+
+ rc = do_xen_hypercall(xc_handle, &hypercall);
+
+ safe_munlock(&arg, sizeof(arg));
+
+ return rc;
+}
+
+int xc_hvm_set_isa_irq_level(
+ int xc_handle, domid_t dom,
+ uint8_t isa_irq,
+ unsigned int level)
+{
+ DECLARE_HYPERCALL;
+ struct xen_hvm_set_isa_irq_level arg;
+ int rc;
+
+ hypercall.op = __HYPERVISOR_hvm_op;
+ hypercall.arg[0] = HVMOP_set_isa_irq_level;
+ hypercall.arg[1] = (unsigned long)&arg;
+
+ arg.domid = dom;
+ arg.isa_irq = isa_irq;
+ arg.level = level;
+
+ if ( mlock(&arg, sizeof(arg)) != 0 )
+ {
+ PERROR("Could not lock memory");
+ return -1;
+ }
+
+ rc = do_xen_hypercall(xc_handle, &hypercall);
+
+ safe_munlock(&arg, sizeof(arg));
+
+ return rc;
+}
+
+int xc_hvm_set_pci_link_route(
+ int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq)
+{
+ DECLARE_HYPERCALL;
+ struct xen_hvm_set_pci_link_route arg;
+ int rc;
+
+ hypercall.op = __HYPERVISOR_hvm_op;
+ hypercall.arg[0] = HVMOP_set_pci_link_route;
+ hypercall.arg[1] = (unsigned long)&arg;
+
+ arg.domid = dom;
+ arg.link = link;
+ arg.isa_irq = isa_irq;
if ( mlock(&arg, sizeof(arg)) != 0 )
{