ia64/xen-unstable

changeset 5194:1e610bdd54fc

bitkeeper revision 1.1585 (42988c63d2BDHoRycJzKDjIR50X5Sw)

[PATCH] [PATCH] VMX world switch does not handle all cases

The latest world switch modification does not handle all cases. Specifically,
when a partition enables CR0.PG|CR0.PE and performs a world switch at the
the same time. The patch below handles this case.

Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
author leendert@watson.ibm.com[kaf24]
date Sat May 28 15:21:07 2005 +0000 (2005-05-28)
parents 94a63704b6c4
children 4c63d91b687f
files xen/arch/x86/vmx.c
line diff
     1.1 --- a/xen/arch/x86/vmx.c	Sat May 28 11:00:01 2005 +0000
     1.2 +++ b/xen/arch/x86/vmx.c	Sat May 28 15:21:07 2005 +0000
     1.3 @@ -744,8 +744,8 @@ static int vmx_set_cr0(unsigned long val
     1.4      __vmwrite(CR0_READ_SHADOW, value);
     1.5  
     1.6      VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
     1.7 -    if ((value & X86_CR0_PE) && (value & X86_CR0_PG) 
     1.8 -        && !paging_enabled) {
     1.9 +
    1.10 +    if ((value & X86_CR0_PE) && (value & X86_CR0_PG) && !paging_enabled) {
    1.11          /*
    1.12           * The guest CR3 must be pointing to the guest physical.
    1.13           */
    1.14 @@ -775,33 +775,39 @@ static int vmx_set_cr0(unsigned long val
    1.15           */
    1.16          VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx", 
    1.17                  d->arch.arch_vmx.cpu_cr3, mfn);
    1.18 -    } else {
    1.19 -        if ((value & X86_CR0_PE) == 0) {
    1.20 -            __vmread(GUEST_EIP, &eip);
    1.21 -            VMX_DBG_LOG(DBG_LEVEL_1, "Disabling CR0.PE at %%eip 0x%lx\n", eip);
    1.22 -	    if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
    1.23 -		set_bit(VMX_CPU_STATE_ASSIST_ENABLED,
    1.24 -					&d->arch.arch_vmx.cpu_state);
    1.25 -		__vmread(GUEST_EIP, &eip);
    1.26 -		VMX_DBG_LOG(DBG_LEVEL_1,
    1.27 -		    "Transfering control to vmxassist %%eip 0x%lx", eip);
    1.28 -		return 0; /* do not update eip! */
    1.29 -	    }
    1.30 -	} else if (test_bit(VMX_CPU_STATE_ASSIST_ENABLED,
    1.31 -					&d->arch.arch_vmx.cpu_state)) {
    1.32 +    }
    1.33 +
    1.34 +    /*
    1.35 +     * VMX does not implement real-mode virtualization. We emulate
    1.36 +     * real-mode by performing a world switch to VMXAssist whenever
    1.37 +     * a partition disables the CR0.PE bit.
    1.38 +     */
    1.39 +    if ((value & X86_CR0_PE) == 0) {
    1.40 +	__vmread(GUEST_EIP, &eip);
    1.41 +	VMX_DBG_LOG(DBG_LEVEL_1,
    1.42 +	    "Disabling CR0.PE at %%eip 0x%lx\n", eip);
    1.43 +	if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
    1.44 +	    set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &d->arch.arch_vmx.cpu_state);
    1.45  	    __vmread(GUEST_EIP, &eip);
    1.46  	    VMX_DBG_LOG(DBG_LEVEL_1,
    1.47 -		"Enabling CR0.PE at %%eip 0x%lx", eip);
    1.48 -	    if (vmx_assist(d, VMX_ASSIST_RESTORE)) {
    1.49 -		clear_bit(VMX_CPU_STATE_ASSIST_ENABLED,
    1.50 +		"Transfering control to vmxassist %%eip 0x%lx\n", eip);
    1.51 +	    return 0; /* do not update eip! */
    1.52 +	}
    1.53 +    } else if (test_bit(VMX_CPU_STATE_ASSIST_ENABLED,
    1.54 +					&d->arch.arch_vmx.cpu_state)) {
    1.55 +	__vmread(GUEST_EIP, &eip);
    1.56 +	VMX_DBG_LOG(DBG_LEVEL_1,
    1.57 +	    "Enabling CR0.PE at %%eip 0x%lx\n", eip);
    1.58 +	if (vmx_assist(d, VMX_ASSIST_RESTORE)) {
    1.59 +	    clear_bit(VMX_CPU_STATE_ASSIST_ENABLED,
    1.60  					&d->arch.arch_vmx.cpu_state);
    1.61 -		__vmread(GUEST_EIP, &eip);
    1.62 -		VMX_DBG_LOG(DBG_LEVEL_1,
    1.63 -		    "Restoring to %%eip 0x%lx", eip);
    1.64 -		return 0; /* do not update eip! */
    1.65 -	    }
    1.66 +	    __vmread(GUEST_EIP, &eip);
    1.67 +	    VMX_DBG_LOG(DBG_LEVEL_1,
    1.68 +		"Restoring to %%eip 0x%lx\n", eip);
    1.69 +	    return 0; /* do not update eip! */
    1.70  	}
    1.71      }
    1.72 +
    1.73      return 1;
    1.74  }
    1.75