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, hvm: Move return-to-guest timer and

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86, hvm: Move return-to-guest timer and interrupt cranking logic
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 23 Oct 2008 10:50:11 -0700
Delivery-date: Thu, 23 Oct 2008 10:50:16 -0700
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 1224758459 -3600
# Node ID 4941c5a1459839c9923f7dafe6fe7705f90ca436
# Parent  50fc79012db7b393e67cf88fda026f67990623cf
x86, hvm: Move return-to-guest timer and interrupt cranking logic
outside of IRQ-safe context. This allows us to safely take
non-IRQ-safe spinlocks.

The drawback is that {vmx,svm}_intr_assist() now races new event
notifications delivered by IRQ or IPI. We close down this race by
having vcpu_kick() send a dummy softirq -- this gets picked up in
IRQ-sage context and will cause retry of *_intr_assist(). We avoid
delivering the softirq where possible by avoiding it when we are
running in the non-IRQ context of the VCPU to be kicked.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/domain.c         |   48 ++++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/hvm/svm/entry.S  |    3 +-
 xen/arch/x86/hvm/vmx/entry.S  |    6 +++--
 xen/include/asm-x86/event.h   |   32 +---------------------------
 xen/include/asm-x86/softirq.h |    3 +-
 5 files changed, 58 insertions(+), 34 deletions(-)

diff -r 50fc79012db7 -r 4941c5a14598 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Oct 23 11:20:44 2008 +0100
+++ b/xen/arch/x86/domain.c     Thu Oct 23 11:40:59 2008 +0100
@@ -1892,6 +1892,54 @@ void domain_cpuid(
     *eax = *ebx = *ecx = *edx = 0;
 }
 
+void vcpu_kick(struct vcpu *v)
+{
+    /*
+     * NB1. 'pause_flags' and 'processor' must be checked /after/ update of
+     * pending flag. These values may fluctuate (after all, we hold no
+     * locks) but the key insight is that each change will cause
+     * evtchn_upcall_pending to be polled.
+     * 
+     * NB2. We save the running flag across the unblock to avoid a needless
+     * IPI for domains that we IPI'd to unblock.
+     */
+    bool_t running = v->is_running;
+    vcpu_unblock(v);
+    if ( running && (in_irq() || (v != current)) )
+        cpu_raise_softirq(v->processor, VCPU_KICK_SOFTIRQ);
+}
+
+void vcpu_mark_events_pending(struct vcpu *v)
+{
+    int already_pending = test_and_set_bit(
+        0, (unsigned long *)&vcpu_info(v, evtchn_upcall_pending));
+
+    if ( already_pending )
+        return;
+
+    if ( is_hvm_vcpu(v) )
+        hvm_assert_evtchn_irq(v);
+    else
+        vcpu_kick(v);
+}
+
+static void vcpu_kick_softirq(void)
+{
+    /*
+     * Nothing to do here: we merely prevent notifiers from racing with checks
+     * executed on return to guest context with interrupts enabled. See, for
+     * example, xxx_intr_assist() executed on return to HVM guest context.
+     */
+}
+
+static int __init init_vcpu_kick_softirq(void)
+{
+    open_softirq(VCPU_KICK_SOFTIRQ, vcpu_kick_softirq);
+    return 0;
+}
+__initcall(init_vcpu_kick_softirq);
+
+
 /*
  * Local variables:
  * mode: C
diff -r 50fc79012db7 -r 4941c5a14598 xen/arch/x86/hvm/svm/entry.S
--- a/xen/arch/x86/hvm/svm/entry.S      Thu Oct 23 11:20:44 2008 +0100
+++ b/xen/arch/x86/hvm/svm/entry.S      Thu Oct 23 11:40:59 2008 +0100
@@ -57,6 +57,8 @@
 #endif
 
 ENTRY(svm_asm_do_resume)
+        call svm_intr_assist
+
         get_current(bx)
         CLGI
 
@@ -67,7 +69,6 @@ ENTRY(svm_asm_do_resume)
         jnz  .Lsvm_process_softirqs
 
         call svm_asid_handle_vmrun
-        call svm_intr_assist
 
         cmpb $0,addr_of(tb_init_done)
         jnz  .Lsvm_trace
diff -r 50fc79012db7 -r 4941c5a14598 xen/arch/x86/hvm/vmx/entry.S
--- a/xen/arch/x86/hvm/vmx/entry.S      Thu Oct 23 11:20:44 2008 +0100
+++ b/xen/arch/x86/hvm/vmx/entry.S      Thu Oct 23 11:40:59 2008 +0100
@@ -122,6 +122,8 @@ vmx_asm_vmexit_handler:
 
 .globl vmx_asm_do_vmentry
 vmx_asm_do_vmentry:
+        call vmx_intr_assist
+
         get_current(bx)
         cli
 
@@ -130,8 +132,6 @@ vmx_asm_do_vmentry:
         lea  addr_of(irq_stat),r(dx)
         cmpl $0,(r(dx),r(ax),1)
         jnz  .Lvmx_process_softirqs
-
-        call vmx_intr_assist
 
         testb $0xff,VCPU_vmx_emul(r(bx))
         jnz  .Lvmx_goto_realmode
@@ -179,11 +179,13 @@ vmx_asm_do_vmentry:
 
 /*.Lvmx_resume:*/
         VMRESUME
+        sti
         call vm_resume_fail
         ud2
 
 .Lvmx_launch:
         VMLAUNCH
+        sti
         call vm_launch_fail
         ud2
 
diff -r 50fc79012db7 -r 4941c5a14598 xen/include/asm-x86/event.h
--- a/xen/include/asm-x86/event.h       Thu Oct 23 11:20:44 2008 +0100
+++ b/xen/include/asm-x86/event.h       Thu Oct 23 11:40:59 2008 +0100
@@ -11,36 +11,8 @@
 
 #include <xen/shared.h>
 
-static inline void vcpu_kick(struct vcpu *v)
-{
-    /*
-     * NB1. 'pause_flags' and 'processor' must be checked /after/ update of
-     * pending flag. These values may fluctuate (after all, we hold no
-     * locks) but the key insight is that each change will cause
-     * evtchn_upcall_pending to be polled.
-     * 
-     * NB2. We save the running flag across the unblock to avoid a needless
-     * IPI for domains that we IPI'd to unblock.
-     */
-    int running = v->is_running;
-    vcpu_unblock(v);
-    if ( running )
-        smp_send_event_check_cpu(v->processor);
-}
-
-static inline void vcpu_mark_events_pending(struct vcpu *v)
-{
-    int already_pending = test_and_set_bit(
-        0, (unsigned long *)&vcpu_info(v, evtchn_upcall_pending));
-
-    if ( already_pending )
-        return;
-
-    if ( is_hvm_vcpu(v) )
-        hvm_assert_evtchn_irq(v);
-    else
-        vcpu_kick(v);
-}
+void vcpu_kick(struct vcpu *v);
+void vcpu_mark_events_pending(struct vcpu *v);
 
 int hvm_local_events_need_delivery(struct vcpu *v);
 static inline int local_events_need_delivery(void)
diff -r 50fc79012db7 -r 4941c5a14598 xen/include/asm-x86/softirq.h
--- a/xen/include/asm-x86/softirq.h     Thu Oct 23 11:20:44 2008 +0100
+++ b/xen/include/asm-x86/softirq.h     Thu Oct 23 11:40:59 2008 +0100
@@ -3,7 +3,8 @@
 
 #define NMI_MCE_SOFTIRQ        (NR_COMMON_SOFTIRQS + 0)
 #define TIME_CALIBRATE_SOFTIRQ (NR_COMMON_SOFTIRQS + 1)
+#define VCPU_KICK_SOFTIRQ      (NR_COMMON_SOFTIRQS + 2)
 
-#define NR_ARCH_SOFTIRQS       2
+#define NR_ARCH_SOFTIRQS       3
 
 #endif /* __ASM_SOFTIRQ_H__ */

_______________________________________________
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, hvm: Move return-to-guest timer and interrupt cranking logic, Xen patchbot-unstable <=