[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Ping: [PATCH 4/6] VMX: correct PDPTE load checks
>>> On 19.07.18 at 12:49, wrote: > Checking the low 5 bits of CR3 is not the job of vmx_load_pdptrs(). > Instead it should #GP upon bad PDPTE values, rather than causing a VM > entry failure. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > > --- a/xen/arch/x86/hvm/vmx/vmx.c > +++ b/xen/arch/x86/hvm/vmx/vmx.c > @@ -1361,20 +1361,18 @@ static void vmx_set_interrupt_shadow(str > __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); > } > > -static void vmx_load_pdptrs(struct vcpu *v) > +static bool vmx_load_pdptrs(struct vcpu *v) > { > unsigned long cr3 = v->arch.hvm_vcpu.guest_cr[3]; > - uint64_t *guest_pdptes; > + uint64_t *guest_pdptes, valid_mask; > struct page_info *page; > p2m_type_t p2mt; > char *p; > + unsigned int i; > > /* EPT needs to load PDPTRS into VMCS for PAE. */ > if ( !hvm_pae_enabled(v) || (v->arch.hvm_vcpu.guest_efer & EFER_LMA) ) > - return; > - > - if ( (cr3 & 0x1fUL) && !hvm_pcid_enabled(v) ) > - goto crash; > + return true; > > page = get_page_from_gfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt, > P2M_UNSHARE); > if ( !page ) > @@ -1385,34 +1383,47 @@ static void vmx_load_pdptrs(struct vcpu > gdprintk(XENLOG_ERR, > "Bad cr3 on load pdptrs gfn %lx type %d\n", > cr3 >> PAGE_SHIFT, (int) p2mt); > - goto crash; > + domain_crash(v->domain); > + return false; > } > > p = __map_domain_page(page); > > - guest_pdptes = (uint64_t *)(p + (cr3 & ~PAGE_MASK)); > + guest_pdptes = (uint64_t *)(p + (cr3 & 0xfe0)); > > - /* > - * We do not check the PDPTRs for validity. The CPU will do this during > - * vm entry, and we can handle the failure there and crash the guest. > - * The only thing we could do better here is #GP instead. > - */ > + valid_mask = ((1ULL << v->domain->arch.cpuid->extd.maxphysaddr) - 1) & > + (PAGE_MASK | _PAGE_AVAIL | _PAGE_PRESENT); > + for ( i = 0; i < 4; ++i ) > + if ( (guest_pdptes[i] & _PAGE_PRESENT) && > + (guest_pdptes[i] & ~valid_mask) ) > + { > + if ( v == current ) > + hvm_inject_hw_exception(TRAP_gp_fault, 0); > + else > + { > + printk(XENLOG_G_ERR "%pv: bad PDPTE%u: %"PRIx64"\n", > + v, i, guest_pdptes[i]); > + domain_crash(v->domain); > + } > + break; > + } > > - vmx_vmcs_enter(v); > + if ( i == 4 ) > + { > + vmx_vmcs_enter(v); > > - __vmwrite(GUEST_PDPTE(0), guest_pdptes[0]); > - __vmwrite(GUEST_PDPTE(1), guest_pdptes[1]); > - __vmwrite(GUEST_PDPTE(2), guest_pdptes[2]); > - __vmwrite(GUEST_PDPTE(3), guest_pdptes[3]); > + __vmwrite(GUEST_PDPTE(0), guest_pdptes[0]); > + __vmwrite(GUEST_PDPTE(1), guest_pdptes[1]); > + __vmwrite(GUEST_PDPTE(2), guest_pdptes[2]); > + __vmwrite(GUEST_PDPTE(3), guest_pdptes[3]); > > - vmx_vmcs_exit(v); > + vmx_vmcs_exit(v); > + } > > unmap_domain_page(p); > put_page(page); > - return; > > - crash: > - domain_crash(v->domain); > + return i == 4; > } > > static void vmx_update_host_cr3(struct vcpu *v) > @@ -1621,7 +1632,8 @@ static void vmx_update_guest_cr(struct v > if ( !hvm_paging_enabled(v) && !vmx_unrestricted_guest(v) ) > v->arch.hvm_vcpu.hw_cr[3] = > v->domain->arch.hvm_domain.params[HVM_PARAM_IDENT_PT]; > - vmx_load_pdptrs(v); > + if ( !vmx_load_pdptrs(v) ) > + break; > } > > __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr[3]); > > > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |