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-ia64-devel

[Xen-ia64-devel] [PATCH] implement PHYSDEVOP_pirq_eoi_gmfn and related s

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [PATCH] implement PHYSDEVOP_pirq_eoi_gmfn and related stuff.
From: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Date: Thu, 4 Dec 2008 14:38:16 +0900
Delivery-date: Wed, 03 Dec 2008 21:38:23 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.6i
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>

diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c
+++ b/xen/arch/ia64/xen/domain.c
@@ -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 --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c
+++ b/xen/arch/ia64/xen/hypercall.c
@@ -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 --git a/xen/arch/ia64/xen/irq.c b/xen/arch/ia64/xen/irq.c
--- a/xen/arch/ia64/xen/irq.c
+++ b/xen/arch/ia64/xen/irq.c
@@ -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) )
+    action = (irq_guest_action_t *)desc->action;
+
+    if ( action->ack_type == ACKTYPE_NONE )
     {
-        ASSERT(((irq_guest_action_t*)desc->action)->ack_type == 
ACKTYPE_UNMASK);
+        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 --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h
+++ b/xen/include/asm-ia64/domain.h
@@ -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)  */


-- 
yamahata

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-ia64-devel] [PATCH] implement PHYSDEVOP_pirq_eoi_gmfn and related stuff., Isaku Yamahata <=