[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.