# HG changeset patch
# User shand@xxxxxxxxxxxxxxxxxxxxxxxx
# Node ID 30fb6ea3a1f7c3b01160fc6f94adeae9a77aafc2
# Parent 4704cd92242e7a7f25f4b88d7a4eaae8d070317a
Heuristic to detect windows shutdown + power down domain.
Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>
Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/svm/svm.c | 22 ++++++++++++++++++++--
xen/arch/x86/hvm/vmx/vmx.c | 29 ++++++++++++++++++++++++++---
2 files changed, 46 insertions(+), 5 deletions(-)
diff -r 4704cd92242e -r 30fb6ea3a1f7 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Wed Aug 16 13:53:10 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Wed Aug 16 14:01:03 2006 +0100
@@ -2150,14 +2150,32 @@ static inline void svm_vmexit_do_hlt(str
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;
+ 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) )
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);
diff -r 4704cd92242e -r 30fb6ea3a1f7 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 16 13:53:10 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 16 14:01:03 2006 +0100
@@ -2054,9 +2054,32 @@ static inline void vmx_do_msr_write(stru
*/
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;
+ 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);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|