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] [LINUX] Disallow nested event delivery.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [LINUX] Disallow nested event delivery.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 20 Dec 2006 17:15:12 -0800
Delivery-date: Wed, 20 Dec 2006 17:16:13 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1166612996 0
# Node ID 3a28be71b667a336c7589cbb7056841f9e42df6a
# Parent  516e4faac066437af4b41014da831d2ad8ae0493
[LINUX] Disallow nested event delivery.

This eliminates the risk of overflowing the kernel stack and is a
reasonable policy given that we have no concept of priorities among
event sources.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c |   51 +++++++++++++++----------
 1 files changed, 32 insertions(+), 19 deletions(-)

diff -r 516e4faac066 -r 3a28be71b667 
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Wed Dec 20 10:41:33 
2006 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Wed Dec 20 11:09:56 
2006 +0000
@@ -208,38 +208,51 @@ void force_evtchn_callback(void)
 /* Not a GPL symbol: used in ubiquitous macros, so too restrictive. */
 EXPORT_SYMBOL(force_evtchn_callback);
 
+static DEFINE_PER_CPU(unsigned int, upcall_count) = { 0 };
+
 /* NB. Interrupts are disabled on entry. */
 asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
 {
        unsigned long  l1, l2;
-       unsigned int   l1i, l2i, port;
+       unsigned int   l1i, l2i, port, count;
        int            irq, cpu = smp_processor_id();
        shared_info_t *s = HYPERVISOR_shared_info;
        vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
 
-       vcpu_info->evtchn_upcall_pending = 0;
+       do {
+               /* Avoid a callback storm when we reenable delivery. */
+               vcpu_info->evtchn_upcall_pending = 0;
+
+               /* Nested invocations bail immediately. */
+               if (unlikely(per_cpu(upcall_count, cpu)++))
+                       return;
 
 #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
-       /* Clear master pending flag /before/ clearing selector flag. */
-       rmb();
+               /* Clear master flag /before/ clearing selector flag. */
+               rmb();
 #endif
-       l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
-       while (l1 != 0) {
-               l1i = __ffs(l1);
-               l1 &= ~(1UL << l1i);
-
-               while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
-                       l2i = __ffs(l2);
-
-                       port = (l1i * BITS_PER_LONG) + l2i;
-                       if ((irq = evtchn_to_irq[port]) != -1)
-                               do_IRQ(irq, regs);
-                       else {
-                               exit_idle();
-                               evtchn_device_upcall(port);
+               l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
+               while (l1 != 0) {
+                       l1i = __ffs(l1);
+                       l1 &= ~(1UL << l1i);
+
+                       while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
+                               l2i = __ffs(l2);
+
+                               port = (l1i * BITS_PER_LONG) + l2i;
+                               if ((irq = evtchn_to_irq[port]) != -1)
+                                       do_IRQ(irq, regs);
+                               else {
+                                       exit_idle();
+                                       evtchn_device_upcall(port);
+                               }
                        }
                }
-       }
+
+               /* If there were nested callbacks then we have more to do. */
+               count = per_cpu(upcall_count, cpu);
+               per_cpu(upcall_count, cpu) = 0;
+       } while (unlikely(count != 1));
 }
 
 static int find_unbound_irq(void)

_______________________________________________
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] [LINUX] Disallow nested event delivery., Xen patchbot-unstable <=