Clarify lazy FPU management in VMX domains.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2006-02-14 20:17:26 +01:00
1 parent 84e877b233
commit 58d5afee7b
2 files changed
+31 -13

No files matched your search

+17 -7
View File
@@ -617,12 +617,17 @@ static void vmx_do_no_device_fault(void)
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 @@ static int vmx_set_cr0(unsigned long value)
*/
__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))
{
clts();
setup_fpu(v);
}
/*
* 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);
}
__vmwrite(GUEST_CR0, value | X86_CR0_PE | X86_CR0_PG | X86_CR0_NE);
__vmwrite(CR0_READ_SHADOW, value);
@@ -1510,6 +1518,8 @@ static int vmx_cr_access(unsigned long exit_qualification, struct cpu_user_regs
break;
case TYPE_CLTS:
TRACE_VMEXIT(1,TYPE_CLTS);
/* We initialise the FPU now, to avoid needing another vmexit. */
clts();
setup_fpu(current);
+14 -6
View File
@@ -382,14 +382,22 @@ static inline void vmx_stts(void)
unsigned long cr0;
struct vcpu *v = current;
__vmread_vcpu(v, GUEST_CR0, &cr0);
if (!(cr0 & X86_CR0_TS)) {
__vmwrite(GUEST_CR0, 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))
__vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
if ( !(cr0 & X86_CR0_TS) )
{
__vmwrite(GUEST_CR0, cr0 | X86_CR0_TS);
__vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
}
}
/* Works only for vcpu == current */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.