diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index d98e68b..2baeae7 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -416,6 +416,17 @@ int xc_watchdog(xc_interface *xch, return ret; } +int xc_shadow_blow_tables(xc_interface *xch, + uint32_t domid) +{ + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_shadow_op; + domctl.domain = (domid_t)domid; + domctl.u.shadow_op.op = XEN_DOMCTL_SHADOW_OP_BLOW_TABLES; + domctl.u.shadow_op.domid = (domid_t)domid; + return do_domctl(xch, &domctl); +} + int xc_shadow_control(xc_interface *xch, uint32_t domid, diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 3bbc827..b23ccbe 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -652,6 +652,7 @@ int xc_shadow_control(xc_interface *xch, unsigned long *mb, uint32_t mode, xc_shadow_op_stats_t *stats); +int xc_shadow_blow_tables(xc_interface *xch, uint32_t domid); int xc_sedf_domain_set(xc_interface *xch, uint32_t domid, diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 59be993..7d31636 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -3789,6 +3789,7 @@ int shadow_domctl(struct domain *d, XEN_GUEST_HANDLE(void) u_domctl) { int rc, preempted = 0; + struct domain *dom; switch ( sc->op ) { @@ -3833,6 +3834,13 @@ int shadow_domctl(struct domain *d, sc->mb = shadow_get_allocation(d); return rc; + case XEN_DOMCTL_SHADOW_OP_BLOW_TABLES: + dom = rcu_lock_domain_by_id(sc->domid); + shadow_blow_tables_per_domain(dom); + rcu_unlock_domain(dom); + + return 0; + default: SHADOW_ERROR("Bad shadow op %u\n", sc->op); return -EINVAL; diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 240ceb9..8169975 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -189,6 +189,8 @@ struct xen_domctl_getpageframeinfo3 { #define XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION 30 #define XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION 31 +#define XEN_DOMCTL_SHADOW_OP_BLOW_TABLES 33 + /* Legacy enable operations. */ /* Equiv. to ENABLE with no mode flags. */ #define XEN_DOMCTL_SHADOW_OP_ENABLE_TEST 1 @@ -239,6 +241,9 @@ struct xen_domctl_shadow_op { XEN_GUEST_HANDLE_64(uint8) dirty_bitmap; uint64_aligned_t pages; /* Size of buffer. Updated with actual size. */ struct xen_domctl_shadow_op_stats stats; + + /* OP_BLOW_TABLE */ + domid_t domid; }; typedef struct xen_domctl_shadow_op xen_domctl_shadow_op_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_t); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index c93b8d0..6476c6c 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1035,6 +1035,7 @@ static int flask_shadow_control(struct domain *d, uint32_t op) case XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE: case XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION: case XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION: + case XEN_DOMCTL_SHADOW_OP_BLOW_TABLES: perm = SHADOW__ENABLE; break; case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY: