On 11/10/2011 12:01 PM, Nadav Har'El wrote: > If we let L1 use EPT, we should probably also support the INVEPT instruction. > > + case VMX_EPT_EXTENT_CONTEXT: > + if (!(nested_vmx_ept_caps & VMX_EPT_EXTENT_CONTEXT_BIT)) > + nested_vmx_failValid(vcpu, > + VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); > + else { > + /* > + * We efficiently handle the common case, of L1 > + * invalidating the last eptp it used to run L2. > + * TODO: Instead of saving one last_eptp02, look up > + * operand.eptp in the shadow EPT table cache, to > + * find its shadow. Then last_eptp02 won't be needed. > + */ > + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); > + struct vcpu_vmx *vmx = to_vmx(vcpu); > + if (vmcs12 && nested_cpu_has_ept(vmcs12) && > + (vmcs12->ept_pointer == operand.eptp) && > + vmx->nested.last_eptp02) > + ept_sync_context(vmx->nested.last_eptp02); > + else > + ept_sync_global(); Are either of these needed? Won't a write to a shadowed EPT table cause them anyway? > + nested_vmx_succeed(vcpu); > + } > + break; > + case VMX_EPT_EXTENT_INDIVIDUAL_ADDR: > + if (!(nested_vmx_ept_caps & VMX_EPT_EXTENT_INDIVIDUAL_BIT)) > + nested_vmx_failValid(vcpu, > + VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); > + else { > + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); > + struct vcpu_vmx *vmx = to_vmx(vcpu); > + if (vmcs12 && nested_cpu_has_ept(vmcs12) && > + (vmcs12->ept_pointer == operand.eptp) && > + vmx->nested.last_eptp02) > + ept_sync_individual_addr( > + vmx->nested.last_eptp02, operand.gpa); Same here. > + else > + ept_sync_global(); > + nested_vmx_succeed(vcpu); > + } > + break; > + default: > + nested_vmx_failValid(vcpu, > + VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); > + } > + > + skip_emulated_instruction(vcpu); > + return 1; > +} > + > -- error compiling committee.c: too many arguments to function -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html