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] IA64: implement PHYSDEVOP_pirq_eoi_gmfn a

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] IA64: implement PHYSDEVOP_pirq_eoi_gmfn and related stuff.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 06 Dec 2008 04:20:33 -0800
Delivery-date: Sat, 06 Dec 2008 04:22:41 -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 Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1228459388 -32400
# Node ID f0a9a58608a08288f554a18758a19e97a51879f2
# Parent  c15577ad46f21c6db393ebc516ab5ddd36341c58
IA64: implement PHYSDEVOP_pirq_eoi_gmfn and related stuff.

This patch is ia64 counter part of 18844:c820bf73a914.

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/domain.c    |    5 +++
 xen/arch/ia64/xen/hypercall.c |   32 +++++++++++++++++++
 xen/arch/ia64/xen/irq.c       |   69 +++++++++++++++++++++++++++++++++++++-----
 xen/include/asm-ia64/domain.h |    4 ++
 4 files changed, 102 insertions(+), 8 deletions(-)

diff -r c15577ad46f2 -r f0a9a58608a0 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Fri Dec 05 15:43:06 2008 +0900
+++ b/xen/arch/ia64/xen/domain.c        Fri Dec 05 15:43:08 2008 +0900
@@ -1653,6 +1653,11 @@ int domain_relinquish_resources(struct d
                /*fallthrough*/
 
        case RELRES_mm_teardown:
+               if (d->arch.pirq_eoi_map != NULL) {
+                       put_page(virt_to_page(d->arch.pirq_eoi_map));
+                       d->arch.pirq_eoi_map = NULL;
+               }
+
                /* Tear down shadow mode stuff. */
                ret = mm_teardown(d);
                if (ret != 0)
diff -r c15577ad46f2 -r f0a9a58608a0 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Fri Dec 05 15:43:06 2008 +0900
+++ b/xen/arch/ia64/xen/hypercall.c     Fri Dec 05 15:43:08 2008 +0900
@@ -341,7 +341,39 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
         ret = -EFAULT;
         if ( copy_from_guest(&eoi, arg, 1) != 0 )
             break;
+        ret = -EINVAL;
+        if ( eoi.irq < 0 || eoi.irq >= NR_IRQS )
+            break;
+        if ( current->domain->arch.pirq_eoi_map )
+            evtchn_unmask(current->domain->pirq_to_evtchn[eoi.irq]);
         ret = pirq_guest_eoi(current->domain, eoi.irq);
+        break;
+    }
+
+    case PHYSDEVOP_pirq_eoi_gmfn: {
+        struct physdev_pirq_eoi_gmfn info;
+        unsigned long mfn;
+
+        BUILD_BUG_ON(NR_IRQS > (PAGE_SIZE * 8));
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&info, arg, 1) != 0 )
+            break;
+
+        ret = -EINVAL;
+        mfn = gmfn_to_mfn(current->domain, info.gmfn);
+        if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), current->domain) )
+            break;
+
+        if ( cmpxchg(&current->domain->arch.pirq_eoi_map_mfn, 0, mfn) != 0 )
+        {
+            put_page(mfn_to_page(mfn));
+            ret = -EBUSY;
+            break;
+        }
+
+        current->domain->arch.pirq_eoi_map = mfn_to_virt(mfn);
+        ret = 0;
         break;
     }
 
diff -r c15577ad46f2 -r f0a9a58608a0 xen/arch/ia64/xen/irq.c
--- a/xen/arch/ia64/xen/irq.c   Fri Dec 05 15:43:06 2008 +0900
+++ b/xen/arch/ia64/xen/irq.c   Fri Dec 05 15:43:08 2008 +0900
@@ -312,16 +312,41 @@ typedef struct {
     struct domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
 
+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], vector);
+
+    desc->status &= ~(IRQ_INPROGRESS|IRQ_GUEST_EOI_PENDING);
+    desc->handler->enable(vector);
+}
+
 static struct timer irq_guest_eoi_timer[NR_IRQS];
 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);
 }
 
@@ -355,8 +380,22 @@ void __do_IRQ_guest(int irq)
 
        if ( already_pending == action->nr_guests )
        {
+               stop_timer(&irq_guest_eoi_timer[irq]);
                desc->handler->disable(irq);
-               stop_timer(&irq_guest_eoi_timer[irq]);
+        desc->status |= IRQ_GUEST_EOI_PENDING;
+        for ( i = 0; i < already_pending; ++i )
+        {
+            d = action->guest[i];
+            set_pirq_eoi(d, irq);
+            /*
+             * 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[irq],
                                irq_guest_eoi_timer_fn, desc, 
smp_processor_id());
                set_timer(&irq_guest_eoi_timer[irq], NOW() + MILLISECS(1));
@@ -379,16 +418,25 @@ int pirq_guest_eoi(struct domain *d, int
 int pirq_guest_eoi(struct domain *d, int irq)
 {
     irq_desc_t *desc;
+    irq_guest_action_t *action;
 
     if ( (irq < 0) || (irq >= NR_IRQS) )
         return -EINVAL;
 
     desc = &irq_desc[irq];
     spin_lock_irq(&desc->lock);
-    if ( test_and_clear_bit(irq, &d->pirq_mask) &&
-         (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
-    {
-        ASSERT(((irq_guest_action_t*)desc->action)->ack_type == 
ACKTYPE_UNMASK);
+    action = (irq_guest_action_t *)desc->action;
+
+    if ( action->ack_type == ACKTYPE_NONE )
+    {
+        ASSERT(!test_bit(irq, d->pirq_mask));
+        stop_timer(&irq_guest_eoi_timer[irq]);
+        _irq_guest_eoi(desc);
+    }
+
+    if ( test_and_clear_bit(irq, &d->pirq_mask) && (--action->in_flight == 0) )
+    {
+        ASSERT(action->ack_type == ACKTYPE_UNMASK);
         desc->handler->end(irq);
     }
     spin_unlock_irq(&desc->lock);
@@ -488,6 +536,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);
+
  out:
     spin_unlock_irqrestore(&desc->lock, flags);
     return rc;
diff -r c15577ad46f2 -r f0a9a58608a0 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Fri Dec 05 15:43:06 2008 +0900
+++ b/xen/include/asm-ia64/domain.h     Fri Dec 05 15:43:08 2008 +0900
@@ -177,6 +177,10 @@ struct arch_domain {
     /* Address of SAL emulator data  */
     struct xen_sal_data *sal_data;
 
+    /* Shared page for notifying that explicit PIRQ EOI is required. */
+    unsigned long *pirq_eoi_map;
+    unsigned long pirq_eoi_map_mfn;
+
     /* Address of efi_runtime_services_t (placed in domain memory)  */
     void *efi_runtime;
     /* Address of fpswa_interface_t (placed in domain memory)  */

_______________________________________________
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] IA64: implement PHYSDEVOP_pirq_eoi_gmfn and related stuff., Xen patchbot-unstable <=