[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2] x86/altp2m: Allow setting the #VE info page for an arbitrary VCPU
On Mon, Sep 3, 2018 at 10:59 PM Adrian Pop <apop@xxxxxxxxxxxxxxx> wrote: > > In a classic HVI + Xen setup, the introspection engine would monitor > legacy guest page-tables by marking them read-only inside the EPT; this > way any modification explicitly made by the guest or implicitly made by > the CPU page walker would trigger an EPT violation, which would be > forwarded by Xen to the SVA and thus the HVI agent. The HVI agent would > analyse the modification, and act upon it - for example, a virtual page > may be remapped (its guest physical address changed inside the > page-table), in which case the introspection logic would update the > protection accordingly (remove EPT hook on the old gpa, and place a new > EPT hook on the new gpa). In other cases, the modification may be of no > interest to the introspection engine - for example, the accessed/dirty > bits may be cleared by the operating system or the accessed/dirty bits > may be set by the CPU page walker. > > In our tests we discovered that the vast majority of guest page-table > modifications fall in the second category (especially on Windows 10 RS4 > x64 - more than 95% of ALL the page-table modifications are irrelevant to > us) - they are of no interest to the introspection logic, but they > trigger a very costly EPT violation nonetheless. Therefore, we decided > to make use of the new #VE & VMFUNC features in recent Intel CPUs to > accelerate the guest page-tables monitoring in the following way: > > 1. Each monitored page-table would be flagged as being convertible > inside the EPT, thus enabling the CPU to deliver a virtualization > exception to he guest instead of generating a traditional EPT > violation. > 2. We inject a small filtering driver inside the protected guest VM, > which would intercept the virtualization exception in order to handle > guest page-table modifications. > 3. We create a dedicated EPT view (altp2m) for the in-guest agent, which > would isolate the agent from the rest of the operating system; the > agent will switch in and out of the protected EPT view via the VMFUNC > instruction placed inside a trampoline page, thus making the agent > immune to malicious code inside the guest. > > This way, all the page-table accesses would generate a > virtualization-exception inside the guest instead of a costly EPT > violation; the #VE agent would emulate and analyse the modification, and > decide whether it is relevant for the main introspection logic; if it is > relevant, it would do a VMCALL and notify the introspection engine > about the modification; otherwise, it would resume normal instruction > execution, thus avoiding a very costly VM exit. > > Signed-off-by: Adrian Pop <apop@xxxxxxxxxxxxxxx> > --- > Changes in v2: > - remove the "__get_vcpu()" helper > --- > tools/libxc/xc_altp2m.c | 1 - > xen/arch/x86/hvm/hvm.c | 19 ++++++++++--------- > 2 files changed, 10 insertions(+), 10 deletions(-) > > diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c > index ce4a1e4d60..528e929d7a 100644 > --- a/tools/libxc/xc_altp2m.c > +++ b/tools/libxc/xc_altp2m.c > @@ -68,7 +68,6 @@ int xc_altp2m_set_domain_state(xc_interface *handle, > uint32_t dom, bool state) > return rc; > } > > -/* This is a bit odd to me that it acts on current.. */ > int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, uint32_t domid, > uint32_t vcpuid, xen_pfn_t gfn) > { > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c > index 72c51faecb..49c3bbee94 100644 > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -4533,8 +4533,7 @@ static int do_altp2m_op( > return -EOPNOTSUPP; > } > > - d = ( a.cmd != HVMOP_altp2m_vcpu_enable_notify ) ? > - rcu_lock_domain_by_any_id(a.domain) : rcu_lock_current_domain(); > + d = rcu_lock_domain_by_any_id(a.domain); Does rcu_lock_domain_by_any_id work if its from the current domain? If not, doesn't that change this function's accessibility to be from exclusively usable only by the outside agent? > > if ( d == NULL ) > return -ESRCH; > @@ -4605,26 +4604,28 @@ static int do_altp2m_op( > > case HVMOP_altp2m_vcpu_enable_notify: > { > - struct vcpu *curr = current; > + struct vcpu *v; > p2m_type_t p2mt; > > - if ( a.u.enable_notify.pad || a.domain != DOMID_SELF || > - a.u.enable_notify.vcpu_id != curr->vcpu_id ) > + if ( a.u.enable_notify.pad || > + a.u.enable_notify.vcpu_id >= d->max_vcpus ) > { > rc = -EINVAL; > break; > } > > - if ( !gfn_eq(vcpu_altp2m(curr).veinfo_gfn, INVALID_GFN) || > - mfn_eq(get_gfn_query_unlocked(curr->domain, > + v = d->vcpu[a.u.enable_notify.vcpu_id]; > + > + if ( !gfn_eq(vcpu_altp2m(v).veinfo_gfn, INVALID_GFN) || > + mfn_eq(get_gfn_query_unlocked(v->domain, > a.u.enable_notify.gfn, &p2mt), INVALID_MFN) ) > { > rc = -EINVAL; > break; > } > > - vcpu_altp2m(curr).veinfo_gfn = _gfn(a.u.enable_notify.gfn); > - altp2m_vcpu_update_vmfunc_ve(curr); > + vcpu_altp2m(v).veinfo_gfn = _gfn(a.u.enable_notify.gfn); > + altp2m_vcpu_update_vmfunc_ve(v); > break; > } > > -- > 2.18.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |