[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVM] Provide common support function for HLT emulation: hvm_hlt().



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID e2e7f4c17b772c67fe56621f1779051328b8c926
# Parent  ebd289e3d2052799c4355f569a46c83d0e4d6635
[HVM] Provide common support function for HLT emulation: hvm_hlt().
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c             |   30 ++++++++++++++++++++++++
 xen/arch/x86/hvm/svm/svm.c         |   43 ++++-------------------------------
 xen/arch/x86/hvm/svm/vmcb.c        |    3 --
 xen/arch/x86/hvm/vmx/vmcs.c        |    2 -
 xen/arch/x86/hvm/vmx/vmx.c         |   45 ++++---------------------------------
 xen/include/asm-x86/hvm/support.h  |    2 +
 xen/include/asm-x86/hvm/svm/vmcb.h |    1 
 xen/include/asm-x86/hvm/vcpu.h     |    7 ++++-
 xen/include/asm-x86/hvm/vmx/vmcs.h |    1 
 9 files changed, 50 insertions(+), 84 deletions(-)

diff -r ebd289e3d205 -r e2e7f4c17b77 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Wed Aug 16 14:27:30 2006 +0100
@@ -345,6 +345,36 @@ int cpu_get_interrupt(struct vcpu *v, in
     return -1;
 }
 
+void hvm_hlt(unsigned long rflags)
+{
+    struct vcpu *v = current;
+    struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;
+    s_time_t next_pit = -1, next_wakeup;
+
+    /*
+     * Detect machine shutdown.  Only do this for vcpu 0, to avoid potentially 
+     * shutting down the domain early. If we halt with interrupts disabled, 
+     * that's a pretty sure sign that we want to shut down.  In a real 
+     * processor, NMIs are the only way to break out of this.
+     */
+    if ( (v->vcpu_id == 0) && !(rflags & X86_EFLAGS_IF) )
+    {
+        printk("D%d: HLT with interrupts enabled -- shutting down.\n",
+               current->domain->domain_id);
+        domain_shutdown(current->domain, SHUTDOWN_poweroff);
+        return;
+    }
+
+    if ( !v->vcpu_id )
+        next_pit = get_scheduled(v, pt->irq, pt);
+    next_wakeup = get_apictime_scheduled(v);
+    if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
+        next_wakeup = next_pit;
+    if ( next_wakeup != - 1 ) 
+        set_timer(&current->arch.hvm_vcpu.hlt_timer, next_wakeup);
+    do_sched_op_compat(SCHEDOP_block, 0);
+}
+
 /*
  * Copy from/to guest virtual.
  */
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed Aug 16 14:27:30 2006 +0100
@@ -835,7 +835,7 @@ static void svm_relinquish_guest_resourc
 
         destroy_vmcb(&v->arch.hvm_svm);
         free_monitor_pagetable(v);
-        kill_timer(&v->arch.hvm_svm.hlt_timer);
+        kill_timer(&v->arch.hvm_vcpu.hlt_timer);
         if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 
         {
             kill_timer( &(VLAPIC(v)->vlapic_timer) );
@@ -863,7 +863,7 @@ static void svm_migrate_timers(struct vc
 
     if ( pt->enabled ) {
         migrate_timer( &pt->timer, v->processor );
-        migrate_timer( &v->arch.hvm_svm.hlt_timer, v->processor );
+        migrate_timer( &v->arch.hvm_vcpu.hlt_timer, v->processor );
     }
     if ( hvm_apic_support(v->domain) && VLAPIC( v ))
         migrate_timer( &(VLAPIC(v)->vlapic_timer ), v->processor );
@@ -2144,47 +2144,16 @@ done:
 }
 
 
-/*
- * Need to use this exit to reschedule
- */
 static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
 {
-    struct vcpu *v = current;
-    struct periodic_time *pt = 
-        &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
-    s_time_t next_pit = -1, next_wakeup;
-
     __update_guest_eip(vmcb, 1);
 
-    /* check for interrupt not handled or new interrupt */
-    if ( vmcb->vintr.fields.irq || cpu_has_pending_irq(v) )
+    /* Check for interrupt not handled or new interrupt. */
+    if ( (vmcb->rflags & X86_EFLAGS_IF) &&
+         (vmcb->vintr.fields.irq || cpu_has_pending_irq(current)) )
        return;
 
-    /* Detect machine shutdown.  Only do this for vcpu 0, to avoid
-       potentially shutting down the domain early. */
-    if (v->vcpu_id == 0) {
-        unsigned long rflags = vmcb->rflags; 
-        /* If we halt with interrupts disabled, that's a pretty sure
-           sign that we want to shut down.  In a real processor, NMIs
-           are the only way to break out of this.  Our SVM code won't
-           deliver interrupts, but will wake it up whenever one is
-           pending... */
-        if(!(rflags & X86_EFLAGS_IF)) {
-            printk("D%d: HLT with interrupts enabled @0x%lx  Shutting down.\n",
-                   current->domain->domain_id, (unsigned long)vmcb->rip);
-            domain_shutdown(current->domain, SHUTDOWN_poweroff);
-            return;
-        }
-    }
-
-    if ( !v->vcpu_id )
-        next_pit = get_scheduled(v, pt->irq, pt);
-    next_wakeup = get_apictime_scheduled(v);
-    if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
-        next_wakeup = next_pit;
-    if ( next_wakeup != - 1 )
-        set_timer(&current->arch.hvm_svm.hlt_timer, next_wakeup);
-    do_sched_op_compat(SCHEDOP_block, 0);
+    hvm_hlt(vmcb->rflags);
 }
 
 
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Wed Aug 16 14:27:30 2006 +0100
@@ -360,8 +360,7 @@ void svm_do_launch(struct vcpu *v)
 
     if (hvm_apic_support(v->domain))
         vlapic_init(v);
-    init_timer(&v->arch.hvm_svm.hlt_timer,
-                               hlt_timer_fn, v, v->processor);
+    init_timer(&v->arch.hvm_vcpu.hlt_timer, hlt_timer_fn, v, v->processor);
 
     vmcb->ldtr.sel = 0;
     vmcb->ldtr.base = 0;
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Wed Aug 16 14:27:30 2006 +0100
@@ -267,7 +267,7 @@ static void vmx_do_launch(struct vcpu *v
         vlapic_init(v);
 
     vmx_set_host_env(v);
-    init_timer(&v->arch.hvm_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
+    init_timer(&v->arch.hvm_vcpu.hlt_timer, hlt_timer_fn, v, v->processor);
 
     error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
     error |= __vmwrite(GUEST_LDTR_BASE, 0);
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Aug 16 14:27:30 2006 +0100
@@ -134,7 +134,7 @@ static void vmx_relinquish_guest_resourc
         if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
             continue;
         free_monitor_pagetable(v);
-        kill_timer(&v->arch.hvm_vmx.hlt_timer);
+        kill_timer(&v->arch.hvm_vcpu.hlt_timer);
         if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
         {
             kill_timer(&VLAPIC(v)->vlapic_timer);
@@ -496,7 +496,7 @@ void vmx_migrate_timers(struct vcpu *v)
 
     if ( pt->enabled ) {
         migrate_timer(&pt->timer, v->processor);
-        migrate_timer(&v->arch.hvm_vmx.hlt_timer, v->processor);
+        migrate_timer(&v->arch.hvm_vcpu.hlt_timer, v->processor);
     }
     if ( hvm_apic_support(v->domain) && VLAPIC(v))
         migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
@@ -2049,46 +2049,11 @@ static inline void vmx_do_msr_write(stru
                 (unsigned long)regs->edx);
 }
 
-/*
- * Need to use this exit to reschedule
- */
 void vmx_vmexit_do_hlt(void)
 {
-    struct vcpu *v = current;
-    struct periodic_time *pt = 
-        &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
-    s_time_t next_pit = -1, next_wakeup;
-
-
-    /* Detect machine shutdown.  Only do this for vcpu 0, to avoid
-       potentially shutting down the domain early. */
-    if (v->vcpu_id == 0) {
-        unsigned long rflags;
-        
-        __vmread(GUEST_RFLAGS, &rflags);
-        /* If we halt with interrupts disabled, that's a pretty sure
-           sign that we want to shut down.  In a real processor, NMIs
-           are the only way to break out of this.  Our VMX code won't
-           deliver interrupts, but will wake it up whenever one is
-           pending... */
-        if(!(rflags & X86_EFLAGS_IF)) {
-            unsigned long rip;
-            __vmread(GUEST_RIP, &rip);
-            printk("D%d: HLT with interrupts enabled @0x%lx  Shutting down.\n",
-                   current->domain->domain_id, rip);
-            domain_shutdown(current->domain, SHUTDOWN_poweroff);
-            return;
-        }
-    }
-
-    if ( !v->vcpu_id )
-        next_pit = get_scheduled(v, pt->irq, pt);
-    next_wakeup = get_apictime_scheduled(v);
-    if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
-        next_wakeup = next_pit;
-    if ( next_wakeup != - 1 ) 
-        set_timer(&current->arch.hvm_vmx.hlt_timer, next_wakeup);
-    do_sched_op_compat(SCHEDOP_block, 0);
+    unsigned long rflags;
+    __vmread(GUEST_RFLAGS, &rflags);
+    hvm_hlt(rflags);
 }
 
 static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/include/asm-x86/hvm/support.h Wed Aug 16 14:27:30 2006 +0100
@@ -148,4 +148,6 @@ void hvm_do_hypercall(struct cpu_user_re
 
 void hvm_prod_vcpu(struct vcpu *v);
 
+void hvm_hlt(unsigned long rflags);
+
 #endif /* __ASM_X86_HVM_SUPPORT_H__ */
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/include/asm-x86/hvm/svm/vmcb.h
--- a/xen/include/asm-x86/hvm/svm/vmcb.h        Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h        Wed Aug 16 14:27:30 2006 +0100
@@ -448,7 +448,6 @@ struct arch_svm_struct {
     unsigned long       cpu_cr2;
     unsigned long       cpu_cr3;
     unsigned long       cpu_state;
-    struct timer        hlt_timer;  /* hlt ins emulation wakeup timer */
 };
 
 extern struct vmcb_struct *alloc_vmcb(void);
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h    Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/include/asm-x86/hvm/vcpu.h    Wed Aug 16 14:27:30 2006 +0100
@@ -43,15 +43,18 @@ struct hvm_vcpu {
     /* Flags */
     int                 flag_dr_dirty;
 
+    /* hlt ins emulation wakeup timer */
+    struct timer        hlt_timer;
+
     union {
         struct arch_vmx_struct vmx;
         struct arch_svm_struct svm;
     } u;
 };
 
-#define ARCH_HVM_IO_WAIT            1   /* Waiting for I/O completion */
+#define ARCH_HVM_IO_WAIT         1   /* Waiting for I/O completion */
 
-#define HVM_CONTEXT_STACK_BYTES     (offsetof(struct cpu_user_regs, 
error_code))
+#define HVM_CONTEXT_STACK_BYTES  (offsetof(struct cpu_user_regs, error_code))
 
 #endif /* __ASM_X86_HVM_VCPU_H__ */
 
diff -r ebd289e3d205 -r e2e7f4c17b77 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Wed Aug 16 14:26:59 2006 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Wed Aug 16 14:27:30 2006 +0100
@@ -93,7 +93,6 @@ struct arch_vmx_struct {
     unsigned long        cpu_based_exec_control;
     struct vmx_msr_state msr_content;
     void                *io_bitmap_a, *io_bitmap_b;
-    struct timer         hlt_timer;  /* hlt ins emulation wakeup timer */
 };
 
 #define vmx_schedule_tail(next)         \

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.