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-changelog

[Xen-changelog] [xen-unstable] x86: add a shared page indicating the nee

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: add a shared page indicating the need for an EOI notification
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 01 Dec 2008 03:51:02 -0800
Delivery-date: Mon, 01 Dec 2008 03:55:14 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1227878852 0
# Node ID c820bf73a914f643ab48864629c0559e68ceede1
# Parent  8dbf23c89cc6a4fbd7b9063b14e706c065ba1678
x86: add a shared page indicating the need for an EOI notification

To simplify the interface for the guest, when a guest uses this new
(sub-)hypercall, PHYSDEVOP_eoi behavior changes to unmask the
corresponding event channel at once, avoiding the eventual need for a
second hypercall from the guest.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/domain.c         |    7 ++++
 xen/arch/x86/irq.c            |   62 +++++++++++++++++++++++++++++++++++++-----
 xen/arch/x86/physdev.c        |   34 +++++++++++++++++++++++
 xen/arch/x86/x86_64/physdev.c |    3 ++
 xen/common/event_channel.c    |    5 +--
 xen/include/asm-x86/domain.h  |    4 ++
 xen/include/public/physdev.h  |   15 ++++++++++
 xen/include/xen/event.h       |    3 ++
 xen/include/xen/irq.h         |    1 
 9 files changed, 125 insertions(+), 9 deletions(-)

diff -r 8dbf23c89cc6 -r c820bf73a914 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/arch/x86/domain.c     Fri Nov 28 13:27:32 2008 +0000
@@ -1814,6 +1814,13 @@ int domain_relinquish_resources(struct d
             unmap_vcpu_info(v);
         }
 
+        if ( d->arch.pirq_eoi_map != NULL )
+        {
+            unmap_domain_page_global(d->arch.pirq_eoi_map);
+            put_page_and_type(mfn_to_page(d->arch.pirq_eoi_map_mfn));
+            d->arch.pirq_eoi_map = NULL;
+        }
+
         d->arch.relmem = RELMEM_xen;
         /* fallthrough */
 
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/arch/x86/irq.c        Fri Nov 28 13:27:32 2008 +0000
@@ -18,6 +18,7 @@
 #include <xen/iommu.h>
 #include <asm/msi.h>
 #include <asm/current.h>
+#include <asm/flushtlb.h>
 #include <public/physdev.h>
 
 /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */
@@ -206,16 +207,42 @@ static DEFINE_PER_CPU(struct pending_eoi
 static DEFINE_PER_CPU(struct pending_eoi, pending_eoi[NR_VECTORS]);
 #define pending_eoi_sp(p) ((p)[NR_VECTORS-1].vector)
 
+static inline void set_pirq_eoi(struct domain *d, unsigned int irq)
+{
+    if ( d->arch.pirq_eoi_map )
+        set_bit(irq, d->arch.pirq_eoi_map);
+}
+
+static inline void clear_pirq_eoi(struct domain *d, unsigned int irq)
+{
+    if ( d->arch.pirq_eoi_map )
+        clear_bit(irq, d->arch.pirq_eoi_map);
+}
+
+static void _irq_guest_eoi(irq_desc_t *desc)
+{
+    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
+    unsigned int i, vector = desc - irq_desc;
+
+    if ( !(desc->status & IRQ_GUEST_EOI_PENDING) )
+        return;
+
+    for ( i = 0; i < action->nr_guests; ++i )
+        clear_pirq_eoi(action->guest[i],
+                       domain_vector_to_irq(action->guest[i], vector));
+
+    desc->status &= ~(IRQ_INPROGRESS|IRQ_GUEST_EOI_PENDING);
+    desc->handler->enable(vector);
+}
+
 static struct timer irq_guest_eoi_timer[NR_VECTORS];
 static void irq_guest_eoi_timer_fn(void *data)
 {
     irq_desc_t *desc = data;
-    unsigned vector = desc - irq_desc;
     unsigned long flags;
 
     spin_lock_irqsave(&desc->lock, flags);
-    desc->status &= ~IRQ_INPROGRESS;
-    desc->handler->enable(vector);
+    _irq_guest_eoi(desc);
     spin_unlock_irqrestore(&desc->lock, flags);
 }
 
@@ -272,8 +299,22 @@ static void __do_IRQ_guest(int vector)
 
     if ( already_pending == action->nr_guests )
     {
+        stop_timer(&irq_guest_eoi_timer[vector]);
         desc->handler->disable(vector);
-        stop_timer(&irq_guest_eoi_timer[vector]);
+        desc->status |= IRQ_GUEST_EOI_PENDING;
+        for ( i = 0; i < already_pending; ++i )
+        {
+            d = action->guest[i];
+            set_pirq_eoi(d, domain_vector_to_irq(d, vector));
+            /*
+             * Could check here whether the guest unmasked the event by now
+             * (or perhaps just re-issue the send_guest_pirq()), and if it
+             * can now accept the event,
+             * - clear all the pirq_eoi bits we already set,
+             * - re-enable the vector, and
+             * - skip the timer setup below.
+             */
+        }
         init_timer(&irq_guest_eoi_timer[vector],
                    irq_guest_eoi_timer_fn, desc, smp_processor_id());
         set_timer(&irq_guest_eoi_timer[vector], NOW() + MILLISECS(1));
@@ -382,8 +423,12 @@ static void __pirq_guest_eoi(struct doma
     action = (irq_guest_action_t *)desc->action;
     vector = desc - irq_desc;
 
-    ASSERT(!test_bit(irq, d->pirq_mask) ||
-           (action->ack_type != ACKTYPE_NONE));
+    if ( action->ack_type == ACKTYPE_NONE )
+    {
+        ASSERT(!test_bit(irq, d->pirq_mask));
+        stop_timer(&irq_guest_eoi_timer[vector]);
+        _irq_guest_eoi(desc);
+    }
 
     if ( unlikely(!test_and_clear_bit(irq, d->pirq_mask)) ||
          unlikely(--action->in_flight != 0) )
@@ -606,6 +651,11 @@ int pirq_guest_bind(struct vcpu *v, int 
     }
 
     action->guest[action->nr_guests++] = v->domain;
+
+    if ( action->ack_type != ACKTYPE_NONE )
+        set_pirq_eoi(v->domain, irq);
+    else
+        clear_pirq_eoi(v->domain, irq);
 
  unlock_out:
     spin_unlock_irq(&desc->lock);
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/arch/x86/physdev.c    Fri Nov 28 13:27:32 2008 +0000
@@ -191,7 +191,41 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EFAULT;
         if ( copy_from_guest(&eoi, arg, 1) != 0 )
             break;
+        ret = -EINVAL;
+        if ( eoi.irq < 0 || eoi.irq >= NR_IRQS )
+            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);
+        break;
+    }
+
+    case PHYSDEVOP_pirq_eoi_mfn: {
+        struct physdev_pirq_eoi_mfn info;
+        unsigned long *p;
+
+        BUILD_BUG_ON(NR_IRQS > (PAGE_SIZE * 8));
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&info, arg, 1) != 0 )
+            break;
+
+        ret = -EINVAL;
+        if ( !mfn_valid(info.mfn) ||
+             !get_page_and_type(mfn_to_page(info.mfn), v->domain,
+                                PGT_writable_page) )
+            break;
+
+        ret = -ENOSPC;
+        if ( (p = map_domain_page_global(info.mfn)) == NULL )
+            break;
+
+        ret = -EBUSY;
+        if ( cmpxchg(&v->domain->arch.pirq_eoi_map, NULL, p) != NULL )
+            unmap_domain_page_global(p);
+        else
+            v->domain->arch.pirq_eoi_map_mfn = info.mfn;
+
         break;
     }
 
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/arch/x86/x86_64/physdev.c
--- a/xen/arch/x86/x86_64/physdev.c     Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/arch/x86/x86_64/physdev.c     Fri Nov 28 13:27:32 2008 +0000
@@ -17,6 +17,9 @@
 
 #define physdev_eoi                compat_physdev_eoi
 #define physdev_eoi_t              physdev_eoi_compat_t
+
+#define physdev_pirq_eoi_mfn       compat_physdev_pirq_eoi_mfn
+#define physdev_pirq_eoi_mfn_t     physdev_pirq_eoi_mfn_compat_t
 
 #define physdev_set_iobitmap       compat_physdev_set_iobitmap
 #define physdev_set_iobitmap_t     physdev_set_iobitmap_compat_t
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/common/event_channel.c        Fri Nov 28 13:27:32 2008 +0000
@@ -762,10 +762,9 @@ long evtchn_bind_vcpu(unsigned int port,
 }
 
 
-static long evtchn_unmask(evtchn_unmask_t *unmask)
+int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
-    int            port = unmask->port;
     struct vcpu   *v;
 
     spin_lock(&d->event_lock);
@@ -916,7 +915,7 @@ long do_event_channel_op(int cmd, XEN_GU
         struct evtchn_unmask unmask;
         if ( copy_from_guest(&unmask, arg, 1) != 0 )
             return -EFAULT;
-        rc = evtchn_unmask(&unmask);
+        rc = evtchn_unmask(unmask.port);
         break;
     }
 
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/include/asm-x86/domain.h      Fri Nov 28 13:27:32 2008 +0000
@@ -237,6 +237,10 @@ struct arch_domain
     /* NB. protected by d->event_lock and by irq_desc[vector].lock */
     int vector_pirq[NR_VECTORS];
     s16 pirq_vector[NR_IRQS];
+
+    /* Shared page for notifying that explicit PIRQ EOI is required. */
+    unsigned long *pirq_eoi_map;
+    unsigned long pirq_eoi_map_mfn;
 
     /* Pseudophysical e820 map (XENMEM_memory_map).  */
     struct e820entry e820[3];
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/include/public/physdev.h
--- a/xen/include/public/physdev.h      Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/include/public/physdev.h      Fri Nov 28 13:27:32 2008 +0000
@@ -41,6 +41,21 @@ DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
 DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
 
 /*
+ * Register a shared page for the hypervisor to indicate whether the guest
+ * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
+ * once the guest used this function in that the associated event channel
+ * will automatically get unmasked. The page registered is used as a bit
+ * array indexed by Xen's PIRQ value.
+ */
+#define PHYSDEVOP_pirq_eoi_mfn          17
+struct physdev_pirq_eoi_mfn {
+    /* IN */
+    xen_pfn_t mfn;
+};
+typedef struct physdev_pirq_eoi_mfn physdev_pirq_eoi_mfn_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_mfn_t);
+
+/*
  * Query the status of an IRQ line.
  * @arg == pointer to physdev_irq_status_query structure.
  */
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/include/xen/event.h
--- a/xen/include/xen/event.h   Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/include/xen/event.h   Fri Nov 28 13:27:32 2008 +0000
@@ -44,6 +44,9 @@ int evtchn_send(struct domain *d, unsign
 /* Bind a local event-channel port to the specified VCPU. */
 long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
 
+/* Unmask a local event-channel port. */
+int evtchn_unmask(unsigned int port);
+
 /* Allocate/free a Xen-attached event channel port. */
 int alloc_unbound_xen_event_channel(
     struct vcpu *local_vcpu, domid_t remote_domid);
diff -r 8dbf23c89cc6 -r c820bf73a914 xen/include/xen/irq.h
--- a/xen/include/xen/irq.h     Fri Nov 28 13:05:58 2008 +0000
+++ b/xen/include/xen/irq.h     Fri Nov 28 13:27:32 2008 +0000
@@ -22,6 +22,7 @@ struct irqaction
 #define IRQ_PENDING    4       /* IRQ pending - replay on enable */
 #define IRQ_REPLAY     8       /* IRQ has been replayed but not acked yet */
 #define IRQ_GUEST       16      /* IRQ is handled by guest OS(es) */
+#define IRQ_GUEST_EOI_PENDING 32 /* IRQ was disabled, pending a guest EOI */
 #define IRQ_PER_CPU     256     /* IRQ is per CPU */
 
 /*

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: add a shared page indicating the need for an EOI notification, Xen patchbot-unstable <=