Gleb Natapov <gleb@xxxxxxxxxx> wrote on 18/04/2013 09:38:43 AM: > On Wed, Apr 17, 2013 at 08:07:40PM +0300, Abel Gordon wrote: > > 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 | 12 ++++++++++++ > > 1 file changed, 12 insertions(+) > > > > --- .before/arch/x86/kvm/vmx.c 2013-04-17 19:58:32.000000000 +0300 > > +++ .after/arch/x86/kvm/vmx.c 2013-04-17 19:58:32.000000000 +0300 > > @@ -355,6 +355,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; > > @@ -5517,6 +5518,7 @@ static int handle_vmon(struct kvm_vcpu * > > { > > struct kvm_segment cs; > > struct vcpu_vmx *vmx = to_vmx(vcpu); > > + struct vmcs *shadow_vmcs; > > > > /* The Intel VMX Instruction Reference lists a bunch of bits that > > * are prerequisite to running VMXON, most notably cr4.VMXE must be > > @@ -5540,6 +5542,16 @@ static int handle_vmon(struct kvm_vcpu * > > kvm_inject_gp(vcpu, 0); > > return 1; > > } > > + if (enable_shadow_vmcs) { > > + shadow_vmcs = alloc_vmcs(); > > + if (!shadow_vmcs) > > + return -ENOMEM; > > + /* mark vmcs as shadow */ > > + shadow_vmcs->revision_id |= (1u << 31); > > + /* init shadow vmcs */ > > + vmcs_clear(shadow_vmcs); > > + vmx->nested.current_shadow_vmcs = shadow_vmcs; > > + } > > > Guest can ddos host by calling vmxon repeatedly causing host to leak > memory. This point to a bug in vmxon implementation. vmxon should call > nested_vmx_failInvalid() if (vmx->nested.vmxon). Good point. I just checked the spec (VMXON pseudo-code) to verify the right emulation: According to the pseudo-code we should: ELSE VMfail(“VMXON executed in VMX root operation”) which means: VMfail(ErrorNumber): IF VMCS pointer is valid THEN VMfailValid(ErrorNumber); ELSE VMfailInvalid; FI; So, I'll call nested_vmx_failValid if nested.current_vmptr != -1ull Otherwise, I'll call nested_vmx_failInvalid. ��.n��������+%������w��{.n�����o�^n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�