[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/mm: suppress vm_events caused by page-walks
commit c5387c4d75602dbb2f0d3d961a5c4b8faf3873db Author: Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx> AuthorDate: Thu Jul 5 15:25:20 2018 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Jul 5 15:25:20 2018 +0200 x86/mm: suppress vm_events caused by page-walks 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. Signed-off-by: Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx> Acked-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx> Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- 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 e8285dbb5f..580d2cdb06 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -2047,6 +2047,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 0233b87b3f..4ac823e775 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 8c32bfbc3f..6aaee16d67 100644 --- a/tools/tests/xen-access/xen-access.c +++ b/tools/tests/xen-access/xen-access.c @@ -360,7 +360,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 @@ -393,6 +393,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]; @@ -451,6 +452,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; @@ -511,6 +519,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 c0cd0174cf..febe38d8df 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 3fb6531f6e..3c42e21906 100644 --- a/xen/arch/x86/monitor.c +++ b/xen/arch/x86/monitor.c @@ -242,6 +242,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 e0d413c7de..5a6332c2b7 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -417,6 +417,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 4f1c7ffe0a..49889033f4 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_CPUID) | (1U << XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION) | (1U << XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG) | - (1U << XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED)); + (1U << XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED) | + (1U << XEN_DOMCTL_MONITOR_EVENT_INGUEST_PAGEFAULT)); if ( hvm_is_singlestep_supported() ) capabilities |= (1U << XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP); diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 0535da81c6..5c3916caaf 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -998,6 +998,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_* */ -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |