Allocate a shadow vmcs used by the processor to shadow part of the fields stored in the software defined VMCS12 (let L1 access fields without causing exits). Note we keep a shadow vmcs only for the current vmcs12. Once a vmcs12 becomes non-current, its shadow vmcs is released. Signed-off-by: Abel Gordon <abelg@xxxxxxxxxx> --- arch/x86/kvm/vmx.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) --- .before/arch/x86/kvm/vmx.c 2013-03-10 18:00:55.000000000 +0200 +++ .after/arch/x86/kvm/vmx.c 2013-03-10 18:00:55.000000000 +0200 @@ -353,6 +353,7 @@ struct nested_vmx { /* The host-usable pointer to the above */ struct page *current_vmcs12_page; struct vmcs12 *current_vmcs12; + struct vmcs *current_shadow_vmcs; /* vmcs02_list cache of VMCSs recently used to run L2 guests */ struct list_head vmcs02_pool; @@ -5889,6 +5890,7 @@ static int handle_vmptrld(struct kvm_vcp gva_t gva; gpa_t vmptr; struct x86_exception e; + struct vmcs *shadow_vmcs; ++vcpu->stat.nvmx_vmptrlds; if (!nested_vmx_check_permission(vcpu)) @@ -5936,6 +5938,19 @@ static int handle_vmptrld(struct kvm_vcp vmx->nested.current_vmptr = vmptr; vmx->nested.current_vmcs12 = new_vmcs12; vmx->nested.current_vmcs12_page = page; + if (enable_shadow_vmcs) { + shadow_vmcs = alloc_vmcs(); + if (!shadow_vmcs) { + nested_vmx_failInvalid(vcpu); + skip_emulated_instruction(vcpu); + return 1; + } + /* mark vmcs as shadow */ + shadow_vmcs->revision_id |= (1u << 31); + /* init shadow vmcs */ + vmcs_clear(shadow_vmcs); + vmx->nested.current_shadow_vmcs = shadow_vmcs; + } } nested_vmx_succeed(vcpu); -- 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