[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Clarify lazy FPU management in VMX domains.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 70024ebbdf55585230fa7656ea79ecb2960779c5 # Parent 39b392a220025993cfb9dfa6ae5554ac3c88a340 Clarify lazy FPU management in VMX domains. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 39b392a22002 -r 70024ebbdf55 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Feb 14 18:43:45 2006 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Feb 14 19:17:26 2006 @@ -617,12 +617,17 @@ clts(); setup_fpu(current); + + /* Disable TS in guest CR0 unless the guest wants the exception too. */ __vmread_vcpu(v, CR0_READ_SHADOW, &cr0); - if (!(cr0 & X86_CR0_TS)) { + if ( !(cr0 & X86_CR0_TS) ) + { __vmread_vcpu(v, GUEST_CR0, &cr0); cr0 &= ~X86_CR0_TS; __vmwrite(GUEST_CR0, cr0); } + + /* Xen itself doesn't need another exception. */ __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM); } @@ -1152,13 +1157,16 @@ */ __vmread_vcpu(v, CR0_READ_SHADOW, &old_cr0); paging_enabled = (old_cr0 & X86_CR0_PE) && (old_cr0 & X86_CR0_PG); - /* If OS don't use clts to clear TS bit...*/ - if((old_cr0 & X86_CR0_TS) && !(value & X86_CR0_TS)) + + /* + * Disable TS? Then we do so at the same time, and initialise FPU. + * This avoids needing another vmexit. + */ + if ( (old_cr0 & ~value & X86_CR0_TS) != 0 ) { - clts(); - setup_fpu(v); - } - + clts(); + setup_fpu(v); + } __vmwrite(GUEST_CR0, value | X86_CR0_PE | X86_CR0_PG | X86_CR0_NE); __vmwrite(CR0_READ_SHADOW, value); @@ -1510,6 +1518,8 @@ break; case TYPE_CLTS: TRACE_VMEXIT(1,TYPE_CLTS); + + /* We initialise the FPU now, to avoid needing another vmexit. */ clts(); setup_fpu(current); diff -r 39b392a22002 -r 70024ebbdf55 xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Tue Feb 14 18:43:45 2006 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Tue Feb 14 19:17:26 2006 @@ -382,14 +382,22 @@ unsigned long cr0; struct vcpu *v = current; - __vmread_vcpu(v, GUEST_CR0, &cr0); - if (!(cr0 & X86_CR0_TS)) { + /* FPU state already dirty? Then no need to setup_fpu() lazily. */ + if ( test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) ) + return; + + /* + * If the guest does not have TS enabled then we must cause and handle an + * exception on first use of the FPU. If the guest *does* have TS enabled + * then this is not necessary: no FPU activity can occur until the guest + * clears CR0.TS, and we will initialise the FPU when that happens. + */ + __vmread_vcpu(v, CR0_READ_SHADOW, &cr0); + if ( !(cr0 & X86_CR0_TS) ) + { __vmwrite(GUEST_CR0, cr0 | X86_CR0_TS); - } - - __vmread_vcpu(v, CR0_READ_SHADOW, &cr0); - if (!(cr0 & X86_CR0_TS)) - __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM); + __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM); + } } /* Works only for vcpu == current */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |