WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] Xen: enhanced PV on HVM

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] Xen: enhanced PV on HVM
From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Date: Tue, 2 Mar 2010 18:30:02 +0000
Delivery-date: Tue, 02 Mar 2010 10:28:11 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Alpine 2.00 (DEB 1167 2008-08-23)
Hi all,
this patch is for Xen and it is derived from an earlier patch by Shen.
The changes introduced by this patch include:

- add support to some vcpuops and physdevops for HVM domains;

- introduce a new interrupt callback method for HVM domains;

- allow HVM guests to map emulated interrupts to pirqs;

in particular the last point is new and it isn't present in the
corresponding patch from Shen.
This patch doesn't introduce an "enable_pv" hypercall and resets the tsc
offset when the guest binds the VIRQ_TIMER.


Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Signed-off-by: Sheng Yang <sheng@xxxxxxxxxxxxxxx>

---


diff -r 3bb163b74673 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/arch/x86/domain.c     Tue Mar 02 17:20:42 2010 +0000
@@ -495,6 +495,16 @@
         for ( i = 1; platform_legacy_irq(i); ++i )
             if ( !IO_APIC_IRQ(i) )
                 d->arch.irq_pirq[i] = d->arch.pirq_irq[i] = i;
+
+        d->arch.pirq_emuirq = xmalloc_array(int, d->nr_pirqs);
+        d->arch.emuirq_pirq = xmalloc_array(int, d->nr_pirqs);
+        if ( !d->arch.pirq_emuirq || !d->arch.emuirq_pirq )
+            goto fail;
+        memset(d->arch.pirq_emuirq, -1,
+               d->nr_pirqs * sizeof(*d->arch.pirq_emuirq));
+        memset(d->arch.emuirq_pirq, -1,
+               d->nr_pirqs * sizeof(*d->arch.emuirq_pirq));
+
 
         if ( (rc = iommu_domain_init(d)) != 0 )
             goto fail;
diff -r 3bb163b74673 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Tue Mar 02 17:20:42 2010 +0000
@@ -2231,6 +2231,21 @@
     return rc;
 }
 
+static long hvm_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+{
+    switch ( cmd )
+    {
+        case PHYSDEVOP_setup_gsi:
+        case PHYSDEVOP_map_pirq:
+        case PHYSDEVOP_unmap_pirq:
+        case PHYSDEVOP_eoi:
+        case PHYSDEVOP_irq_status_query:
+            return do_physdev_op(cmd, arg);
+        default:
+            return -ENOSYS;
+    }
+}
+
 static long hvm_vcpu_op(
     int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
 {
@@ -2240,6 +2255,14 @@
     {
     case VCPUOP_register_runstate_memory_area:
     case VCPUOP_get_runstate_info:
+    case VCPUOP_initialise:
+    case VCPUOP_up:
+    case VCPUOP_is_up:
+    case VCPUOP_set_periodic_timer:
+    case VCPUOP_stop_periodic_timer:
+    case VCPUOP_set_singleshot_timer:
+    case VCPUOP_stop_singleshot_timer:
+    case VCPUOP_register_vcpu_time_memory_area:
         rc = do_vcpu_op(cmd, vcpuid, arg);
         break;
     default:
@@ -2262,9 +2285,11 @@
     [ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op,
     [ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,
     [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op,
+    [ __HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op,
     HYPERCALL(xen_version),
     HYPERCALL(event_channel_op),
     HYPERCALL(sched_op),
+    HYPERCALL(set_timer_op),
     HYPERCALL(hvm_op)
 };
 
@@ -2296,6 +2321,14 @@
     {
     case VCPUOP_register_runstate_memory_area:
     case VCPUOP_get_runstate_info:
+    case VCPUOP_initialise:
+    case VCPUOP_up:
+    case VCPUOP_is_up:
+    case VCPUOP_set_periodic_timer:
+    case VCPUOP_stop_periodic_timer:
+    case VCPUOP_set_singleshot_timer:
+    case VCPUOP_stop_singleshot_timer:
+    case VCPUOP_register_vcpu_time_memory_area:
         rc = compat_vcpu_op(cmd, vcpuid, arg);
         break;
     default:
@@ -2306,13 +2339,33 @@
     return rc;
 }
 
+static long hvm_physdev_op_compat32(
+    int cmd, XEN_GUEST_HANDLE(void) arg)
+{
+    switch ( cmd )
+    {
+        case PHYSDEVOP_setup_gsi:
+        case PHYSDEVOP_map_pirq:
+        case PHYSDEVOP_unmap_pirq:
+        case PHYSDEVOP_eoi:
+        case PHYSDEVOP_irq_status_query:
+            return compat_physdev_op(cmd, arg);
+        break;
+    default:
+            return -ENOSYS;
+        break;
+    }
+}
+
 static hvm_hypercall_t *hvm_hypercall64_table[NR_hypercalls] = {
     [ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op,
     [ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,
     [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op,
+    [ __HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op,
     HYPERCALL(xen_version),
     HYPERCALL(event_channel_op),
     HYPERCALL(sched_op),
+    HYPERCALL(set_timer_op),
     HYPERCALL(hvm_op)
 };
 
@@ -2320,9 +2373,11 @@
     [ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op_compat32,
     [ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t 
*)hvm_grant_table_op_compat32,
     [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op_compat32,
+    [ __HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op_compat32,
     HYPERCALL(xen_version),
     HYPERCALL(event_channel_op),
     HYPERCALL(sched_op),
+    HYPERCALL(set_timer_op),
     HYPERCALL(hvm_op)
 };
 
diff -r 3bb163b74673 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/arch/x86/hvm/irq.c    Tue Mar 02 17:20:42 2010 +0000
@@ -23,8 +23,29 @@
 #include <xen/types.h>
 #include <xen/event.h>
 #include <xen/sched.h>
+#include <xen/irq.h>
 #include <asm/hvm/domain.h>
 #include <asm/hvm/support.h>
+
+/* Must be called with hvm_domain->irq_lock hold */
+static void assert_irq(struct domain *d, unsigned ioapic_gsi, unsigned pic_irq)
+{
+    int pirq = domain_emuirq_to_pirq(d, ioapic_gsi);
+    if ( pirq >= 0 )
+    {
+        send_guest_pirq(d, pirq);
+        return;
+    }
+    vioapic_irq_positive_edge(d, ioapic_gsi);
+    vpic_irq_positive_edge(d, pic_irq);
+}
+
+/* Must be called with hvm_domain->irq_lock hold */
+static void deassert_irq(struct domain *d, unsigned isa_irq)
+{
+    if ( domain_emuirq_to_pirq(d, isa_irq) <= 0 )
+        vpic_irq_negative_edge(d, isa_irq);
+}
 
 static void __hvm_pci_intx_assert(
     struct domain *d, unsigned int device, unsigned int intx)
@@ -45,10 +66,7 @@
     isa_irq = hvm_irq->pci_link.route[link];
     if ( (hvm_irq->pci_link_assert_count[link]++ == 0) && isa_irq &&
          (hvm_irq->gsi_assert_count[isa_irq]++ == 0) )
-    {
-        vioapic_irq_positive_edge(d, isa_irq);
-        vpic_irq_positive_edge(d, isa_irq);
-    }
+        assert_irq(d, isa_irq, isa_irq);
 }
 
 void hvm_pci_intx_assert(
@@ -77,7 +95,7 @@
     isa_irq = hvm_irq->pci_link.route[link];
     if ( (--hvm_irq->pci_link_assert_count[link] == 0) && isa_irq &&
          (--hvm_irq->gsi_assert_count[isa_irq] == 0) )
-        vpic_irq_negative_edge(d, isa_irq);
+        deassert_irq(d, isa_irq);
 }
 
 void hvm_pci_intx_deassert(
@@ -100,10 +118,7 @@
 
     if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq.i) &&
          (hvm_irq->gsi_assert_count[gsi]++ == 0) )
-    {
-        vioapic_irq_positive_edge(d, gsi);
-        vpic_irq_positive_edge(d, isa_irq);
-    }
+        assert_irq(d, gsi, isa_irq);
 
     spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
@@ -120,7 +135,7 @@
 
     if ( __test_and_clear_bit(isa_irq, &hvm_irq->isa_irq.i) &&
          (--hvm_irq->gsi_assert_count[gsi] == 0) )
-        vpic_irq_negative_edge(d, isa_irq);
+        deassert_irq(d, isa_irq);
 
     spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
@@ -185,16 +200,16 @@
 
 void hvm_assert_evtchn_irq(struct vcpu *v)
 {
-    if ( v->vcpu_id != 0 )
-        return;
-
     if ( unlikely(in_irq() || !local_irq_is_enabled()) )
     {
         tasklet_schedule(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet);
         return;
     }
 
-    hvm_set_callback_irq_level(v);
+    if (is_hvm_pv_evtchn_vcpu(v))
+        vcpu_kick(v);
+    else
+        hvm_set_callback_irq_level(v);
 }
 
 void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq)
@@ -251,7 +266,7 @@
 
     via_type = (uint8_t)(via >> 56) + 1;
     if ( ((via_type == HVMIRQ_callback_gsi) && (via == 0)) ||
-         (via_type > HVMIRQ_callback_pci_intx) )
+         (via_type > HVMIRQ_callback_vector) )
         via_type = HVMIRQ_callback_none;
 
     spin_lock(&d->arch.hvm_domain.irq_lock);
@@ -297,6 +312,9 @@
         if ( hvm_irq->callback_via_asserted )
              __hvm_pci_intx_assert(d, pdev, pintx);
         break;
+    case HVMIRQ_callback_vector:
+        hvm_irq->callback_via.vector = (uint8_t)via;
+        break;
     default:
         break;
     }
@@ -312,6 +330,10 @@
     case HVMIRQ_callback_pci_intx:
         printk("PCI INTx Dev 0x%02x Int%c\n", pdev, 'A' + pintx);
         break;
+    case HVMIRQ_callback_vector:
+        printk("Set HVMIRQ_callback_vector to %u\n",
+               hvm_irq->callback_via.vector);
+        break;
     default:
         printk("None\n");
         break;
@@ -323,6 +345,10 @@
     struct hvm_domain *plat = &v->domain->arch.hvm_domain;
     int vector;
 
+    if (plat->irq.callback_via_type == HVMIRQ_callback_vector &&
+            vcpu_info(v, evtchn_upcall_pending))
+        return hvm_intack_vector(plat->irq.callback_via.vector);
+ 
     if ( unlikely(v->nmi_pending) )
         return hvm_intack_nmi;
 
@@ -363,6 +389,8 @@
     case hvm_intsrc_lapic:
         if ( !vlapic_ack_pending_irq(v, intack.vector) )
             intack = hvm_intack_none;
+        break;
+    case hvm_intsrc_vector:
         break;
     default:
         intack = hvm_intack_none;
diff -r 3bb163b74673 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/arch/x86/hvm/vmx/intr.c       Tue Mar 02 17:20:42 2010 +0000
@@ -164,7 +164,8 @@
     {
         HVMTRACE_2D(INJ_VIRQ, intack.vector, /*fake=*/ 0);
         vmx_inject_extint(intack.vector);
-        pt_intr_post(v, intack);
+        if (intack.source != hvm_intsrc_vector)
+             pt_intr_post(v, intack);
     }
 
     /* Is there another IRQ to queue up behind this one? */
diff -r 3bb163b74673 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/arch/x86/irq.c        Tue Mar 02 17:20:42 2010 +0000
@@ -1733,3 +1733,71 @@
         peoi[sp].ready = 1;
     flush_ready_eoi();
 }
+
+int map_domain_emuirq_pirq(
+    struct domain *d, int pirq, int emuirq, int type, void *data)
+{
+    int old_emuirq, old_pirq, ret = 0;
+
+    ASSERT(spin_is_locked(&d->event_lock));
+
+    if ( !is_hvm_domain(d) )
+        return -EINVAL;
+
+    if ( pirq < 0 || pirq >= d->nr_pirqs || emuirq < 0 || emuirq >= nr_irqs )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or irq %d\n",
+                d->domain_id, pirq, emuirq);
+        return -EINVAL;
+    }
+
+    old_emuirq = domain_pirq_to_emuirq(d, pirq);
+    old_pirq = domain_emuirq_to_pirq(d, emuirq);
+
+    if ( (old_emuirq > 0 && (old_emuirq != emuirq) ) ||
+         (old_pirq > 0 && (old_pirq != pirq)) )
+    {
+        dprintk(XENLOG_G_WARNING, "dom%d: pirq %d or emuirq %d already 
mapped\n",
+                d->domain_id, pirq, emuirq);
+        return 0;
+    }
+
+    if ( type == MAP_PIRQ_TYPE_GSI )
+    {
+        d->arch.pirq_emuirq[pirq] = emuirq;
+        d->arch.emuirq_pirq[emuirq] = pirq;
+    } else {
+        ret = -EINVAL;
+    }
+
+    return ret;
+}
+
+/* The pirq should have been unbound before this call. */
+int unmap_domain_pirq_emuirq(struct domain *d, int pirq)
+{
+    int emuirq, ret = 0;
+
+    if ( !is_hvm_domain(d) )
+        return -EINVAL;
+
+    if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
+        return -EINVAL;
+
+    ASSERT(spin_is_locked(&d->event_lock));
+
+    emuirq = domain_pirq_to_emuirq(d, pirq);
+    if ( emuirq <= 0 )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: pirq %d not mapped\n",
+                d->domain_id, pirq);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    d->arch.pirq_emuirq[pirq] = -1;
+    d->arch.emuirq_pirq[emuirq] = -1;
+
+ done:
+    return ret;
+}
diff -r 3bb163b74673 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/arch/x86/physdev.c    Tue Mar 02 17:20:42 2010 +0000
@@ -44,6 +44,23 @@
 
     if ( d == NULL )
         return -ESRCH;
+   
+    if ( map->domid == DOMID_SELF && is_hvm_domain(d) )
+    {
+        spin_lock(&d->event_lock);
+        switch ( map->type )
+        {
+            case MAP_PIRQ_TYPE_GSI :
+                ret = map_domain_emuirq_pirq(d, map->pirq, map->index, 
map->type, NULL);
+                break;
+            default :
+                ret = -EINVAL;
+                dprintk(XENLOG_G_WARNING, "map type %d not supported yet\n", 
map->type);
+                break;
+        }
+        spin_unlock(&d->event_lock);
+        return ret;
+    }
 
     if ( !IS_PRIV_FOR(current->domain, d) )
     {
@@ -173,6 +190,14 @@
     if ( d == NULL )
         return -ESRCH;
 
+    if ( is_hvm_domain(d) )
+    {
+        spin_lock(&d->event_lock);
+        ret = unmap_domain_pirq_emuirq(d, unmap->pirq);
+        spin_unlock(&d->event_lock);
+        goto free_domain;
+    }
+
     ret = -EPERM;
     if ( !IS_PRIV_FOR(current->domain, d) )
         goto free_domain;
@@ -206,7 +231,10 @@
             break;
         if ( v->domain->arch.pirq_eoi_map )
             evtchn_unmask(v->domain->pirq_to_evtchn[eoi.irq]);
-        ret = pirq_guest_eoi(v->domain, eoi.irq);
+        if ( !is_hvm_domain(v->domain) )
+            ret = pirq_guest_eoi(v->domain, eoi.irq);
+        else
+            ret = 0;
         break;
     }
 
@@ -261,6 +289,12 @@
         if ( (irq < 0) || (irq >= v->domain->nr_pirqs) )
             break;
         irq_status_query.flags = 0;
+        if ( is_hvm_domain(v->domain) )
+        {
+            ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
+            break;
+        }
+
         /*
          * Even edge-triggered or message-based IRQs can need masking from
          * time to time. If teh guest is not dynamically checking for this
@@ -465,6 +499,11 @@
     case PHYSDEVOP_setup_gsi: {
         struct physdev_setup_gsi setup_gsi;
 
+        /* In the HVM case we are setting up an emulated GSI, therefore
+         * there is no need to do anything here */
+        if ( is_hvm_domain(v->domain) )
+            return 0;
+
         ret = -EPERM;
         if ( !IS_PRIV(v->domain) )
             break;
diff -r 3bb163b74673 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/common/event_channel.c        Tue Mar 02 17:20:42 2010 +0000
@@ -305,7 +305,7 @@
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
 
-    if ( !irq_access_permitted(d, pirq) )
+    if ( !is_hvm_domain(d) && !irq_access_permitted(d, pirq) )
         return -EPERM;
 
     spin_lock(&d->event_lock);
@@ -319,12 +319,14 @@
     chn = evtchn_from_port(d, port);
 
     d->pirq_to_evtchn[pirq] = port;
-    rc = pirq_guest_bind(d->vcpu[0], pirq, 
-                         !!(bind->flags & BIND_PIRQ__WILL_SHARE));
-    if ( rc != 0 )
-    {
-        d->pirq_to_evtchn[pirq] = 0;
-        goto out;
+    if ( !is_hvm_domain(d) ) {
+        rc = pirq_guest_bind(d->vcpu[0], pirq, 
+                !!(bind->flags & BIND_PIRQ__WILL_SHARE));
+        if ( rc != 0 )
+        {
+            d->pirq_to_evtchn[pirq] = 0;
+            goto out;
+        }
     }
 
     chn->state  = ECS_PIRQ;
@@ -376,7 +378,8 @@
         break;
 
     case ECS_PIRQ:
-        pirq_guest_unbind(d1, chn1->u.pirq);
+        if ( !is_hvm_domain(d1) )
+            pirq_guest_unbind(d1, chn1->u.pirq);
         d1->pirq_to_evtchn[chn1->u.pirq] = 0;
         break;
 
@@ -636,8 +639,17 @@
     /*
      * It should not be possible to race with __evtchn_close():
      * The caller of this function must synchronise with pirq_guest_unbind().
+     *
+     * In the HVM case port is 0 when the guest disable the
+     * emulated interrupt\evtchn.
      */
-    ASSERT(port != 0);
+    if (!port)
+    {
+        if ( is_hvm_domain(d) && domain_pirq_to_emuirq(d, pirq) >= 0)
+            return 0;
+        else
+            return -EINVAL;
+    }
 
     chn = evtchn_from_port(d, port);
     return evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
@@ -824,6 +836,7 @@
 long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
     long rc;
+    struct domain *d = current->domain;
 
     switch ( cmd )
     {
@@ -852,6 +865,10 @@
         if ( copy_from_guest(&bind_virq, arg, 1) != 0 )
             return -EFAULT;
         rc = evtchn_bind_virq(&bind_virq);
+        if ( is_hvm_domain(d) && bind_virq.virq == VIRQ_TIMER) {
+            update_domain_wallclock_time(d);
+            hvm_funcs.set_tsc_offset(d->vcpu[0], 0);
+        }
         if ( (rc == 0) && (copy_to_guest(arg, &bind_virq, 1) != 0) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
diff -r 3bb163b74673 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/include/asm-x86/domain.h      Tue Mar 02 17:20:42 2010 +0000
@@ -278,6 +278,9 @@
     /* NB. protected by d->event_lock and by irq_desc[irq].lock */
     int *irq_pirq;
     int *pirq_irq;
+    /* pirq to emulated irq and vice versa */
+    int *emuirq_pirq;
+    int *pirq_emuirq;
 
     /* Shared page for notifying that explicit PIRQ EOI is required. */
     unsigned long *pirq_eoi_map;
diff -r 3bb163b74673 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h     Tue Mar 02 17:20:42 2010 +0000
@@ -33,7 +33,8 @@
     hvm_intsrc_pic,
     hvm_intsrc_lapic,
     hvm_intsrc_nmi,
-    hvm_intsrc_mce
+    hvm_intsrc_mce,
+    hvm_intsrc_vector
 };
 struct hvm_intack {
     uint8_t source; /* enum hvm_intsrc */
@@ -44,6 +45,7 @@
 #define hvm_intack_lapic(vec) ( (struct hvm_intack) { hvm_intsrc_lapic, vec } )
 #define hvm_intack_nmi        ( (struct hvm_intack) { hvm_intsrc_nmi,   2 } )
 #define hvm_intack_mce        ( (struct hvm_intack) { hvm_intsrc_mce,   18 } )
+#define hvm_intack_vector(vec)( (struct hvm_intack) { hvm_intsrc_vector, vec } 
)
 enum hvm_intblk {
     hvm_intblk_none,      /* not blocked (deliverable) */
     hvm_intblk_shadow,    /* MOV-SS or STI shadow */
diff -r 3bb163b74673 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/include/asm-x86/hvm/irq.h     Tue Mar 02 17:20:42 2010 +0000
@@ -54,12 +54,14 @@
         enum {
             HVMIRQ_callback_none,
             HVMIRQ_callback_gsi,
-            HVMIRQ_callback_pci_intx
+            HVMIRQ_callback_pci_intx,
+            HVMIRQ_callback_vector
         } callback_via_type;
     };
     union {
         uint32_t gsi;
         struct { uint8_t dev, intx; } pci;
+        uint32_t vector;
     } callback_via;
 
     /* Number of INTx wires asserting each PCI-ISA link. */
diff -r 3bb163b74673 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/include/asm-x86/irq.h Tue Mar 02 17:20:42 2010 +0000
@@ -112,6 +112,9 @@
 int map_domain_pirq(struct domain *d, int pirq, int irq, int type,
                            void *data);
 int unmap_domain_pirq(struct domain *d, int pirq);
+int map_domain_emuirq_pirq(struct domain *d, int pirq, int irq, int type,
+                           void *data);
+int unmap_domain_pirq_emuirq(struct domain *d, int pirq);
 int get_free_pirq(struct domain *d, int type, int index);
 void free_domain_pirqs(struct domain *d);
 
@@ -147,5 +150,7 @@
 
 #define domain_pirq_to_irq(d, pirq) ((d)->arch.pirq_irq[pirq])
 #define domain_irq_to_pirq(d, irq) ((d)->arch.irq_pirq[irq])
+#define domain_pirq_to_emuirq(d, pirq) ((d)->arch.pirq_emuirq[pirq])
+#define domain_emuirq_to_pirq(d, emuirq) ((d)->arch.emuirq_pirq[emuirq])
 
 #endif /* _ASM_HW_IRQ_H */
diff -r 3bb163b74673 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Fri Feb 12 09:24:18 2010 +0000
+++ b/xen/include/xen/sched.h   Tue Mar 02 17:20:42 2010 +0000
@@ -592,6 +592,9 @@
 #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
 
 #define is_hvm_domain(d) ((d)->is_hvm)
+#define is_hvm_pv_evtchn_domain(d) (is_hvm_domain(d) && \
+           d->arch.hvm_domain.irq.callback_via_type == HVMIRQ_callback_vector)
+#define is_hvm_pv_evtchn_vcpu(v) (is_hvm_pv_evtchn_domain(v->domain))
 #define is_hvm_vcpu(v)   (is_hvm_domain(v->domain))
 #define need_iommu(d)    ((d)->need_iommu)
 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>