[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Ping: [PATCH v2] x86/mm: Suppresses vm_events caused by page-walks
Any thoughts are appreciated. > This patch is adding a way to enable/disable nested pagefault > events. It introduces the xc_monitor_nested_pagefault function > and adds the nested_pagefault_disabled in the monitor structure. > This is needed by the introspection so it will only get gla > faults and not get spammed with other faults. > In p2m_set_ad_bits the v->arch.sse_pg_dirty.eip and > v->arch.sse_pg_dirty.gla are used to mark that this is the > second time a fault occurs and the dirty bit is set. > > Signed-off-by: Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx> > > --- > Changes since V1: > - Rb V1 > - Add comment in domctl.h > --- > tools/libxc/include/xenctrl.h | 2 ++ > tools/libxc/xc_monitor.c | 14 ++++++++++++++ > xen/arch/x86/mm/mem_access.c | 27 +++++++++++++++++++++++++++ > xen/arch/x86/monitor.c | 13 +++++++++++++ > xen/include/asm-x86/domain.h | 6 ++++++ > xen/include/asm-x86/monitor.h | 3 ++- > xen/include/public/domctl.h | 2 ++ > 7 files changed, 66 insertions(+), 1 deletion(-) > > diff --git a/tools/libxc/include/xenctrl.h > b/tools/libxc/include/xenctrl.h > index 09e1363..112c974 100644 > --- a/tools/libxc/include/xenctrl.h > +++ b/tools/libxc/include/xenctrl.h > @@ -2056,6 +2056,8 @@ int xc_monitor_descriptor_access(xc_interface > *xch, uint32_t domain_id, > bool enable); > int xc_monitor_guest_request(xc_interface *xch, uint32_t domain_id, > bool enable, bool sync, bool > allow_userspace); > +int xc_monitor_nested_pagefault(xc_interface *xch, uint32_t > domain_id, > + bool disable); > int xc_monitor_debug_exceptions(xc_interface *xch, uint32_t > domain_id, > bool enable, bool sync); > int xc_monitor_cpuid(xc_interface *xch, uint32_t domain_id, bool > enable); > diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c > index 0233b87..e96c56d 100644 > --- a/tools/libxc/xc_monitor.c > +++ b/tools/libxc/xc_monitor.c > @@ -163,6 +163,20 @@ int xc_monitor_guest_request(xc_interface *xch, > uint32_t domain_id, bool enable, > return do_domctl(xch, &domctl); > } > > +int xc_monitor_nested_pagefault(xc_interface *xch, uint32_t > domain_id, > + bool disable) > +{ > + DECLARE_DOMCTL; > + > + domctl.cmd = XEN_DOMCTL_monitor_op; > + domctl.domain = domain_id; > + domctl.u.monitor_op.op = disable ? XEN_DOMCTL_MONITOR_OP_ENABLE > + : XEN_DOMCTL_MONITOR_OP_DISABLE; > + domctl.u.monitor_op.event = > XEN_DOMCTL_MONITOR_EVENT_NESTED_PAGEFAULT; > + > + return do_domctl(xch, &domctl); > +} > + > int xc_monitor_emulate_each_rep(xc_interface *xch, uint32_t > domain_id, > bool enable) > { > diff --git a/xen/arch/x86/mm/mem_access.c > b/xen/arch/x86/mm/mem_access.c > index c0cd017..07a334b 100644 > --- a/xen/arch/x86/mm/mem_access.c > +++ b/xen/arch/x86/mm/mem_access.c > @@ -137,6 +137,23 @@ bool p2m_mem_access_emulate_check(struct vcpu > *v, > return violation; > } > > +static void p2m_set_ad_bits(struct vcpu *v, paddr_t ga) > +{ > + struct hvm_hw_cpu ctxt; > + uint32_t pfec = 0; > + > + hvm_funcs.save_cpu_ctxt(v, &ctxt); > + > + if ( guest_cpu_user_regs()->eip == v->arch.pg_dirty.eip > + && ga == v->arch.pg_dirty.gla ) > + pfec = PFEC_write_access; > + > + paging_ga_to_gfn_cr3(v, ctxt.cr3, ga, &pfec, NULL); > + > + v->arch.pg_dirty.eip = guest_cpu_user_regs()->eip; > + v->arch.pg_dirty.gla = ga; > +} > + > bool p2m_mem_access_check(paddr_t gpa, unsigned long gla, > struct npfec npfec, > vm_event_request_t **req_ptr) > @@ -208,6 +225,16 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned > long gla, > } > } > > + if ( vm_event_check_ring(d->vm_event_monitor) && > + d->arch.monitor.nested_pagefault_disabled && > + npfec.kind != npfec_kind_with_gla ) /* don't send a > mem_event */ > + { > + v->arch.vm_event->emulate_flags = 0; > + p2m_set_ad_bits(v, gla); > + > + return true; > + } > + > *req_ptr = NULL; > req = xzalloc(vm_event_request_t); > if ( req ) > diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c > index f229e69..e35b619 100644 > --- a/xen/arch/x86/monitor.c > +++ b/xen/arch/x86/monitor.c > @@ -241,6 +241,19 @@ int arch_monitor_domctl_event(struct domain *d, > break; > } > > + case XEN_DOMCTL_MONITOR_EVENT_NESTED_PAGEFAULT: > + { > + bool old_status = ad->monitor.nested_pagefault_disabled; > + > + if ( unlikely(old_status == requested_status) ) > + return -EEXIST; > + > + domain_pause(d); > + ad->monitor.nested_pagefault_disabled = requested_status; > + domain_unpause(d); > + break; > + } > + > case XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS: > { > bool old_status = ad->monitor.descriptor_access_enabled; > diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm- > x86/domain.h > index 4679d54..099af7c 100644 > --- a/xen/include/asm-x86/domain.h > +++ b/xen/include/asm-x86/domain.h > @@ -412,6 +412,7 @@ struct arch_domain > unsigned int > descriptor_access_enabled : 1; > unsigned int > guest_request_userspace_enabled : 1; > unsigned int > emul_unimplemented_enabled : 1; > + unsigned int > nested_pagefault_disabled : 1; > struct monitor_msr_bitmap *msr_bitmap; > uint64_t write_ctrlreg_mask[4]; > } monitor; > @@ -579,6 +580,11 @@ struct arch_vcpu > /* A secondary copy of the vcpu time info. */ > XEN_GUEST_HANDLE(vcpu_time_info_t) time_info_guest; > > + struct { > + unsigned long eip; > + unsigned long gla; > + } pg_dirty; > + > struct arch_vm_event *vm_event; > > struct msr_vcpu_policy *msr; > diff --git a/xen/include/asm-x86/monitor.h b/xen/include/asm- > x86/monitor.h > index a0444d1..a7a0b56 100644 > --- a/xen/include/asm-x86/monitor.h > +++ b/xen/include/asm-x86/monitor.h > @@ -84,7 +84,8 @@ static inline uint32_t > arch_monitor_get_capabilities(struct domain *d) > (1U << XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION) > | > (1U << XEN_DOMCTL_MONITOR_EVENT_CPUID) | > (1U << XEN_DOMCTL_MONITOR_EVENT_INTERRUPT) | > - (1U << > XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED); > + (1U << > XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED) | > + (1U << > XEN_DOMCTL_MONITOR_EVENT_NESTED_PAGEFAULT); > > /* Since we know this is on VMX, we can just call the hvm func > */ > if ( hvm_is_singlestep_supported() ) > diff --git a/xen/include/public/domctl.h > b/xen/include/public/domctl.h > index 9ae72959..706c6ea 100644 > --- a/xen/include/public/domctl.h > +++ b/xen/include/public/domctl.h > @@ -1014,6 +1014,8 @@ struct xen_domctl_psr_cmt_op { > #define XEN_DOMCTL_MONITOR_EVENT_INTERRUPT 8 > #define XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS 9 > #define XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED 10 > +/* Enabled by default */ > +#define XEN_DOMCTL_MONITOR_EVENT_NESTED_PAGEFAULT 11 > > struct xen_domctl_monitor_op { > uint32_t op; /* XEN_DOMCTL_MONITOR_OP_* */ ________________________ This email was scanned by Bitdefender _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |