[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6] x86/mm: Suppresses vm_events caused by page-walks
On Mon, May 7, 2018 at 7:40 AM, Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx> wrote: > This patch is adding a way to enable/disable inguest pagefault > events. It introduces the xc_monitor_inguest_pagefault function > and adds the inguest_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_mem_access_check() we emulate so no event will get sent. Thanks for the changes! Acked-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx> > Signed-off-by: Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx> > > --- > Changes since V5: > - Add comment for the xc_monitor_inguest_pagefault() func. > - Add altp2m_write_no_gpt test in xen_access > --- > tools/libxc/include/xenctrl.h | 7 +++++++ > tools/libxc/xc_monitor.c | 14 ++++++++++++++ > tools/tests/xen-access/xen-access.c | 36 +++++++++++++++++++++++++++++++++++- > xen/arch/x86/mm/mem_access.c | 9 +++++++++ > xen/arch/x86/monitor.c | 13 +++++++++++++ > xen/include/asm-x86/domain.h | 5 +++++ > xen/include/asm-x86/monitor.h | 3 ++- > xen/include/public/domctl.h | 2 ++ > 8 files changed, 87 insertions(+), 2 deletions(-) > > diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h > index 09e1363..6f9070d 100644 > --- a/tools/libxc/include/xenctrl.h > +++ b/tools/libxc/include/xenctrl.h > @@ -2056,6 +2056,13 @@ 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); > +/* > + * Disables page-walk mem_access events by emulating. If the > + * emulation can not be performed then a VM_EVENT_REASON_EMUL_UNIMPLEMENTED > + * event will be issued. > + */ > +int xc_monitor_inguest_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..4ac823e 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_inguest_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_INGUEST_PAGEFAULT; > + > + return do_domctl(xch, &domctl); > +} > + > int xc_monitor_emulate_each_rep(xc_interface *xch, uint32_t domain_id, > bool enable) > { > diff --git a/tools/tests/xen-access/xen-access.c > b/tools/tests/xen-access/xen-access.c > index 9d960e2..e940137 100644 > --- a/tools/tests/xen-access/xen-access.c > +++ b/tools/tests/xen-access/xen-access.c > @@ -362,7 +362,7 @@ void usage(char* progname) > { > fprintf(stderr, "Usage: %s [-m] <domain_id> write|exec", progname); > #if defined(__i386__) || defined(__x86_64__) > - fprintf(stderr, > "|breakpoint|altp2m_write|altp2m_exec|debug|cpuid|desc_access|write_ctrlreg_cr4"); > + fprintf(stderr, > "|breakpoint|altp2m_write|altp2m_exec|debug|cpuid|desc_access|write_ctrlreg_cr4|altp2m_write_no_gpt"); > #elif defined(__arm__) || defined(__aarch64__) > fprintf(stderr, "|privcall"); > #endif > @@ -395,6 +395,7 @@ int main(int argc, char *argv[]) > int cpuid = 0; > int desc_access = 0; > int write_ctrlreg_cr4 = 0; > + int altp2m_write_no_gpt = 0; > uint16_t altp2m_view_id = 0; > > char* progname = argv[0]; > @@ -453,6 +454,13 @@ int main(int argc, char *argv[]) > altp2m = 1; > memaccess = 1; > } > + else if ( !strcmp(argv[0], "altp2m_write_no_gpt") ) > + { > + default_access = XENMEM_access_rw; > + altp2m_write_no_gpt = 1; > + memaccess = 1; > + altp2m = 1; > + } > else if ( !strcmp(argv[0], "debug") ) > { > debug = 1; > @@ -513,6 +521,22 @@ int main(int argc, char *argv[]) > xen_pfn_t gfn = 0; > unsigned long perm_set = 0; > > + if( altp2m_write_no_gpt ) > + { > + rc = xc_monitor_inguest_pagefault(xch, domain_id, 1); > + if ( rc < 0 ) > + { > + ERROR("Error %d setting inguest pagefault\n", rc); > + goto exit; > + } > + rc = xc_monitor_emul_unimplemented(xch, domain_id, 1); > + if ( rc < 0 ) > + { > + ERROR("Error %d failed to enable emul unimplemented\n", rc); > + goto exit; > + } > + } > + > rc = xc_altp2m_set_domain_state( xch, domain_id, 1 ); > if ( rc < 0 ) > { > @@ -857,6 +881,16 @@ int main(int argc, char *argv[]) > req.u.write_ctrlreg.old_value, > req.u.write_ctrlreg.new_value); > break; > + case VM_EVENT_REASON_EMUL_UNIMPLEMENTED: > + if ( altp2m_write_no_gpt && req.flags & > VM_EVENT_FLAG_ALTERNATE_P2M ) > + { > + DPRINTF("\tSwitching back to default view!\n"); > + > + rsp.flags |= (VM_EVENT_FLAG_ALTERNATE_P2M | > + VM_EVENT_FLAG_TOGGLE_SINGLESTEP); > + rsp.altp2m_idx = 0; > + } > + break; > default: > fprintf(stderr, "UNKNOWN REASON CODE %d\n", req.reason); > } > diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c > index c0cd017..febe38d 100644 > --- a/xen/arch/x86/mm/mem_access.c > +++ b/xen/arch/x86/mm/mem_access.c > @@ -28,6 +28,7 @@ > #include <public/vm_event.h> > #include <asm/p2m.h> > #include <asm/altp2m.h> > +#include <asm/hvm/emulate.h> > #include <asm/vm_event.h> > > #include "mm-locks.h" > @@ -207,6 +208,14 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned long gla, > return true; > } > } > + if ( vm_event_check_ring(d->vm_event_monitor) && > + d->arch.monitor.inguest_pagefault_disabled && > + npfec.kind != npfec_kind_with_gla ) /* don't send a mem_event */ > + { > + hvm_emulate_one_vm_event(EMUL_KIND_NORMAL, TRAP_invalid_op, > X86_EVENT_NO_EC); > + > + return true; > + } > > *req_ptr = NULL; > req = xzalloc(vm_event_request_t); > diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c > index f229e69..ce5d1ba 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_INGUEST_PAGEFAULT: > + { > + bool old_status = ad->monitor.inguest_pagefault_disabled; > + > + if ( unlikely(old_status == requested_status) ) > + return -EEXIST; > + > + domain_pause(d); > + ad->monitor.inguest_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..fbdc392 100644 > --- a/xen/include/asm-x86/domain.h > +++ b/xen/include/asm-x86/domain.h > @@ -412,6 +412,11 @@ struct arch_domain > unsigned int descriptor_access_enabled : > 1; > unsigned int guest_request_userspace_enabled : > 1; > unsigned int emul_unimplemented_enabled : > 1; > + /* > + * By default all events are sent. > + * This is used to filter out pagefaults. > + */ > + unsigned int inguest_pagefault_disabled : > 1; > struct monitor_msr_bitmap *msr_bitmap; > uint64_t write_ctrlreg_mask[4]; > } monitor; > diff --git a/xen/include/asm-x86/monitor.h b/xen/include/asm-x86/monitor.h > index a0444d1..647df4a 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_INGUEST_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..ab89f35 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_INGUEST_PAGEFAULT 11 > > struct xen_domctl_monitor_op { > uint32_t op; /* XEN_DOMCTL_MONITOR_OP_* */ > -- > 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |