P2M audit rework
PATCH 1/1 P2M audit rework
Bring the p2m audit back from the dead. Tease out -ept and -pt specific code. TUrn it into a domctl.
Signed-off-by Andres Lagar-Cavilla <[email protected]>
xen/arch/x86/domctl.c | 30 +++++++++ xen/arch/x86/mm/p2m-ept.c | 1 + xen/arch/x86/mm/p2m-pod.c | 5 - xen/arch/x86/mm/p2m-pt.c | 137 +++++++------------------------------------ xen/arch/x86/mm/p2m.c | 124 ++++++++++++++++++++++++++++++++++++--- xen/include/asm-x86/p2m.h | 11 ++- xen/include/public/domctl.h | 12 +++ tools/libxc/xc_domain.c | 22 +++++++ tools/libxc/xenctrl.h | 27 ++++++++ 9 files changed, 235 insertions(+), 134 deletions(-)
PATCH 1/1 Rework stale p2m auditing
xen/arch/x86/domctl.c | 30 +++++++++ xen/arch/x86/mm/p2m-ept.c | 1 + xen/arch/x86/mm/p2m-pod.c | 5 - xen/arch/x86/mm/p2m-pt.c | 137 +++++++------------------------------------ xen/arch/x86/mm/p2m.c | 124 ++++++++++++++++++++++++++++++++++++--- xen/include/asm-x86/p2m.h | 11 ++- xen/include/public/domctl.h | 12 +++ 7 files changed, 186 insertions(+), 134 deletions(-)
The p2m audit code doesn't even compile, let alone work. It also partially supports ept. Make it:
- compile
- lay groundwork for eventual ept support
- move out of the way of all calls and turn it into a domctl. It's obviously not being used by anybody presently.
- enable it via said domctl
Signed-off-by Andres Lagar-Cavilla <[email protected]>
xen/arch/x86/domctl.c +30 -0
@@ -1449,6 +1449,36 @@ long arch_do_domctl(break ;#endif /* __x86_64__ */ +case XEN_DOMCTL_audit_p2m: + { +struct domain *d; + + ret = -ESRCH ; + d =rcu_lock_domain_by_id (domctl->domain); +if ( d !=NULL ) + { + ret = -EPERM ; +if ( (domctl->domain !=DOMID_SELF ) && + (d != current->domain) && + (IS_PRIV_FOR (current->domain, d)) ) + { +#if P2M_AUDIT +audit_p2m (d, + &domctl->u.audit_p2m.orphans_debug, + &domctl->u.audit_p2m.orphans_invalid, + &domctl->u.audit_p2m.m2p_bad, + &domctl->u.audit_p2m.p2m_bad); + ret = (copy_to_guest (u_domctl, domctl,1 )) ? + -EFAULT :0 ; +#else + ret = -ENOSYS ; +#endif /* P2M_AUDIT */ + } +rcu_unlock_domain (d); + } + } +break ; +case XEN_DOMCTL_set_access_required: {struct domain *d;
xen/arch/x86/mm/p2m-ept.c +1 -0
@@ -817,6 +817,7 @@ void ept_p2m_init(struct p2m_domain *p2m p2m->set_entry = ept_set_entry; p2m->get_entry = ept_get_entry; p2m->change_entry_type_global = ept_change_entry_type_global; + p2m->audit_p2m =NULL ; }static void ept_dump_p2m_table (unsigned char key)
xen/arch/x86/mm/p2m-pod.c +0 -5
@@ -522,7 +522,6 @@ p2m_pod_decrease_reservation(struct doma steal_for_cache = ( p2m->pod.entry_count > p2m->pod.count );p2m_lock (p2m); -audit_p2m (p2m,1 );if (unlikely (d->is_dying) ) goto out_unlock;
@@ -616,7 +615,6 @@ out_entry_check: } out_unlock: -audit_p2m (p2m,1 );p2m_unlock (p2m); out:
@@ -986,7 +984,6 @@ p2m_pod_demand_populate(struct p2m_domai*/ set_p2m_entry (p2m, gfn_aligned,_mfn (0 ),PAGE_ORDER_2M , p2m_populate_on_demand, p2m->default_access); -audit_p2m (p2m,1 );return 0 ; }
@@ -1108,7 +1105,6 @@ guest_physmap_mark_populate_on_demand(streturn rc;p2m_lock (p2m); -audit_p2m (p2m,1 );P2M_DEBUG ("mark pod gfn=%#lx\n" , gfn);
@@ -1142,7 +1138,6 @@ guest_physmap_mark_populate_on_demand(stBUG_ON (p2m->pod.entry_count <0 ); } -audit_p2m (p2m,1 );p2m_unlock (p2m); out:
xen/arch/x86/mm/p2m-pt.c +23 -114
172 lines not on this page · raw message
xen/arch/x86/mm/p2m.c +113 -11
191 lines not on this page · raw message
xen/include/asm-x86/p2m.h +7 -4
@@ -245,6 +245,7 @@ struct p2m_domain { unsigned long gfn, l1_pgentry_t *p, mfn_t table_mfn, l1_pgentry_t new, unsigned int level); +long (*audit_p2m)(struct p2m_domain *p2m);/* Default P2M access type for each page in the the domain: new pages, * swapped in pages, cleared pages, and pages that are ambiquously
@@ -559,13 +560,15 @@ int set_p2m_entry(struct p2m_domain *p2mextern void p2m_pt_init (struct p2m_domain *p2m);/* Debugging and auditing of the P2M code? */ -#define P2M_AUDIT 0 +#define P2M_AUDIT 1#define P2M_DEBUGGING 0#if P2M_AUDIT -extern void audit_p2m (struct p2m_domain *p2m,int strict_m2p); -#else -# define audit_p2m (_p2m, _m2p) do { (void)(_p2m),(_m2p); } while (0) +extern void audit_p2m (struct domain *d, +uint64_t *orphans_debug, +uint64_t *orphans_invalid, +uint64_t *m2p_bad, +uint64_t *p2m_bad);#endif /* P2M_AUDIT */ /* Printouts */
xen/include/public/domctl.h +12 -0
@@ -800,6 +800,16 @@ struct xen_domctl_mem_sharing_op {typedef struct xen_domctl_mem_sharing_op xen_domctl_mem_sharing_op_t ;DEFINE_XEN_GUEST_HANDLE (xen_domctl_mem_sharing_op_t); +struct xen_domctl_audit_p2m { +/* OUT error counts */ +uint64_t orphans_debug; +uint64_t orphans_invalid; +uint64_t m2p_bad; +uint64_t p2m_bad; +}; +typedef struct xen_domctl_audit_p2m xen_domctl_audit_p2m_t ; +DEFINE_XEN_GUEST_HANDLE (xen_domctl_audit_p2m_t); +#if defined(__i386__) || defined(__x86_64__)/* XEN_DOMCTL_setvcpuextstate */ /* XEN_DOMCTL_getvcpuextstate */
@@ -898,6 +908,7 @@ struct xen_domctl {#define XEN_DOMCTL_setvcpuextstate 62#define XEN_DOMCTL_getvcpuextstate 63#define XEN_DOMCTL_set_access_required 64 +#define XEN_DOMCTL_audit_p2m 65#define XEN_DOMCTL_gdbsx_guestmemio 1000#define XEN_DOMCTL_gdbsx_pausevcpu 1001#define XEN_DOMCTL_gdbsx_unpausevcpu 1002
@@ -951,6 +962,7 @@ struct xen_domctl {struct xen_domctl_vcpuextstate vcpuextstate;#endif struct xen_domctl_set_access_required access_required; +struct xen_domctl_audit_p2m audit_p2m;struct xen_domctl_gdbsx_memio gdbsx_guest_memio;struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;struct xen_domctl_gdbsx_domstatus gdbsx_domstatus;
PATCH 1/1 Add libxc wrapper for p2m audit domctl
In reply to Andres Lagar-Cavillatools/libxc/xc_domain.c | 22 ++++++++++++++++++++++ tools/libxc/xenctrl.h | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 0 deletions(-)
Signed-off-by Andres Lagar-Cavilla <[email protected]>
tools/libxc/xc_domain.c +22 -0
@@ -1472,6 +1472,28 @@ int xc_domain_debug_control(xc_interfacereturn do_domctl (xc, &domctl); } +int xc_domain_p2m_audit (xc_interface *xch, +uint32_t domid, +uint64_t *orphans_debug, +uint64_t *orphans_invalid, +uint64_t *m2p_bad, +uint64_t *p2m_bad) +{ +DECLARE_DOMCTL ; +int rc; + + domctl.cmd = XEN_DOMCTL_audit_p2m; + domctl.domain = domid; + rc =do_domctl (xch, &domctl); + + *orphans_debug = domctl.u.audit_p2m.orphans_debug; + *orphans_invalid = domctl.u.audit_p2m.orphans_invalid; + *m2p_bad = domctl.u.audit_p2m.m2p_bad; + *p2m_bad = domctl.u.audit_p2m.p2m_bad; + +return rc; +} +int xc_domain_set_access_required (xc_interface *xch,uint32_t domid,unsigned int required)
tools/libxc/xenctrl.h +27 -0
@@ -712,6 +712,33 @@ int xc_domain_setdebugging(xc_interface unsigned int enable);/** +* This function audits the (top level) p2m of a domain +* and returns the different error counts, if any. +* +* @parm xch a handle to an open hypervisor interface +* @parm domid the domain id whose top level p2m we +* want to audit +* @parm orphans_debug count of m2p entries for valid +* domain pages containing a debug value +* @parm orphans_invalid count of m2p entries for valid +* domain pages containing an invalid value +* @parm m2p_bad count of m2p entries mismatching the +* associated p2m entry for this domain +* @parm p2m_bad count of p2m entries for this domain +* mismatching the associated m2p entry +* return 0 on success, -1 on failure +* errno values on failure include: +* -ENOSYS: not implemented +* -EFAULT: could not copy results back to guest +*/ +int xc_domain_p2m_audit (xc_interface *xch, +uint32_t domid, +uint64_t *orphans_debug, +uint64_t *orphans_invalid, +uint64_t *m2p_bad, +uint64_t *p2m_bad); + +/** * This function sets or clears the requirement that an access memory * event listener is required on the domain. *