[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 14/19] arch/x86: Add missing mem_sharing XSM hooks
This patch adds splits up the mem_sharing and mem_event XSM hooks to better cover what the code is doing. It also changes the utility function get_mem_event_op_target to rcu_lock_live_remote_domain_by_id because there is no mm-specific logic in there. Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx> Acked-by: Tim Deegan <tim@xxxxxxx> Cc: Keir Fraser <keir@xxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> --- tools/flask/policy/policy/flask/access_vectors | 1 + xen/arch/x86/domctl.c | 8 ++--- xen/arch/x86/mm/mem_event.c | 41 ++++++++------------------ xen/arch/x86/mm/mem_sharing.c | 25 +++++++++++++--- xen/common/domain.c | 15 ++++++++++ xen/include/asm-x86/mem_event.h | 1 - xen/include/xen/sched.h | 6 ++++ xen/include/xsm/dummy.h | 23 ++++++++++++++- xen/include/xsm/xsm.h | 24 +++++++++++++-- xen/xsm/dummy.c | 5 +++- xen/xsm/flask/hooks.c | 25 ++++++++++++++-- xen/xsm/flask/include/av_perm_to_string.h | 1 + xen/xsm/flask/include/av_permissions.h | 1 + 13 files changed, 130 insertions(+), 46 deletions(-) diff --git a/tools/flask/policy/policy/flask/access_vectors b/tools/flask/policy/policy/flask/access_vectors index ea65e45..45ac437 100644 --- a/tools/flask/policy/policy/flask/access_vectors +++ b/tools/flask/policy/policy/flask/access_vectors @@ -102,6 +102,7 @@ class hvm mem_sharing audit_p2m send_irq + share_mem } class event diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 30518aa..34e6223 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -1503,10 +1503,8 @@ long arch_do_domctl( d = rcu_lock_domain_by_id(domctl->domain); if ( d != NULL ) { - ret = xsm_mem_event(d); - if ( !ret ) - ret = mem_event_domctl(d, &domctl->u.mem_event_op, - guest_handle_cast(u_domctl, void)); + ret = mem_event_domctl(d, &domctl->u.mem_event_op, + guest_handle_cast(u_domctl, void)); rcu_unlock_domain(d); copy_to_guest(u_domctl, domctl, 1); } @@ -1562,7 +1560,7 @@ long arch_do_domctl( d = rcu_lock_domain_by_id(domctl->domain); if ( d != NULL ) { - ret = xsm_mem_event(d); + ret = xsm_mem_event_setup(d); if ( !ret ) { p2m = p2m_get_hostp2m(d); p2m->access_required = domctl->u.access_required.access_required; diff --git a/xen/arch/x86/mm/mem_event.c b/xen/arch/x86/mm/mem_event.c index 27d1cf4..c2b3670 100644 --- a/xen/arch/x86/mm/mem_event.c +++ b/xen/arch/x86/mm/mem_event.c @@ -29,6 +29,7 @@ #include <asm/mem_paging.h> #include <asm/mem_access.h> #include <asm/mem_sharing.h> +#include <xsm/xsm.h> /* for public/io/ring.h macros */ #define xen_mb() mb() @@ -439,35 +440,19 @@ static void mem_sharing_notification(struct vcpu *v, unsigned int port) mem_sharing_sharing_resume(v->domain); } -struct domain *get_mem_event_op_target(uint32_t domain, int *rc) -{ - struct domain *d; - - /* Get the target domain */ - *rc = rcu_lock_remote_target_domain_by_id(domain, &d); - if ( *rc != 0 ) - return NULL; - - /* Not dying? */ - if ( d->is_dying ) - { - rcu_unlock_domain(d); - *rc = -EINVAL; - return NULL; - } - - return d; -} - int do_mem_event_op(int op, uint32_t domain, void *arg) { int ret; struct domain *d; - d = get_mem_event_op_target(domain, &ret); - if ( !d ) + ret = rcu_lock_live_remote_domain_by_id(domain, &d); + if ( ret ) return ret; + ret = xsm_mem_event_op(d, op); + if ( ret ) + goto out; + switch (op) { case XENMEM_paging_op: @@ -483,6 +468,7 @@ int do_mem_event_op(int op, uint32_t domain, void *arg) ret = -ENOSYS; } + out: rcu_unlock_domain(d); return ret; } @@ -516,6 +502,10 @@ int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, { int rc; + rc = xsm_mem_event_control(d, mec->mode, mec->op); + if ( rc ) + return rc; + if ( unlikely(d == current->domain) ) { gdprintk(XENLOG_INFO, "Tried to do a memory event op on itself.\n"); @@ -537,13 +527,6 @@ int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, return -EINVAL; } - /* TODO: XSM hook */ -#if 0 - rc = xsm_mem_event_control(d, mec->op); - if ( rc ) - return rc; -#endif - rc = -ENOSYS; switch ( mec->mode ) diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index 5103285..9229b83 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -34,6 +34,7 @@ #include <asm/atomic.h> #include <xen/rcupdate.h> #include <asm/event.h> +#include <xsm/xsm.h> #include "mm-locks.h" @@ -1345,10 +1346,18 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( !mem_sharing_enabled(d) ) return -EINVAL; - cd = get_mem_event_op_target(mec->u.share.client_domain, &rc); - if ( !cd ) + rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + &cd); + if ( rc ) return rc; + rc = xsm_mem_sharing_op(d, cd, mec->op); + if ( rc ) + { + rcu_unlock_domain(cd); + return rc; + } + if ( !mem_sharing_enabled(cd) ) { rcu_unlock_domain(cd); @@ -1401,10 +1410,18 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( !mem_sharing_enabled(d) ) return -EINVAL; - cd = get_mem_event_op_target(mec->u.share.client_domain, &rc); - if ( !cd ) + rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + &cd); + if ( rc ) return rc; + rc = xsm_mem_sharing_op(d, cd, mec->op); + if ( rc ) + { + rcu_unlock_domain(cd); + return rc; + } + if ( !mem_sharing_enabled(cd) ) { rcu_unlock_domain(cd); diff --git a/xen/common/domain.c b/xen/common/domain.c index 12c8e24..fcf24e2 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -475,6 +475,21 @@ int rcu_lock_remote_domain_by_id(domid_t dom, struct domain **d) return 0; } +int rcu_lock_live_remote_domain_by_id(domid_t dom, struct domain **d) +{ + int rv; + rv = rcu_lock_remote_domain_by_id(dom, d); + if ( rv ) + return rv; + if ( (*d)->is_dying ) + { + rcu_unlock_domain(*d); + return -EINVAL; + } + + return 0; +} + int domain_kill(struct domain *d) { int rc = 0; diff --git a/xen/include/asm-x86/mem_event.h b/xen/include/asm-x86/mem_event.h index e17f36b..5959621 100644 --- a/xen/include/asm-x86/mem_event.h +++ b/xen/include/asm-x86/mem_event.h @@ -62,7 +62,6 @@ void mem_event_put_request(struct domain *d, struct mem_event_domain *med, int mem_event_get_response(struct domain *d, struct mem_event_domain *med, mem_event_response_t *rsp); -struct domain *get_mem_event_op_target(uint32_t domain, int *rc); int do_mem_event_op(int op, uint32_t domain, void *arg); int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, XEN_GUEST_HANDLE_PARAM(void) u_domctl); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 6c55039..90a6537 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -484,6 +484,12 @@ int rcu_lock_remote_target_domain_by_id(domid_t dom, struct domain **d); */ int rcu_lock_remote_domain_by_id(domid_t dom, struct domain **d); +/* + * As rcu_lock_remote_domain_by_id() but will fail EINVAL if the domain is + * dying. + */ +int rcu_lock_live_remote_domain_by_id(domid_t dom, struct domain **d); + /* Finish a RCU critical region started by rcu_lock_domain_by_id(). */ static inline void rcu_unlock_domain(struct domain *d) { diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 073217a..ee381a8 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -551,16 +551,37 @@ static XSM_DEFAULT(int, hvm_inject_msi) (struct domain *d) return 0; } -static XSM_DEFAULT(int, mem_event) (struct domain *d) +static XSM_DEFAULT(int, mem_event_setup) (struct domain *d) { return 0; } +static XSM_DEFAULT(int, mem_event_control) (struct domain *d, int mode, int op) +{ + if ( !IS_PRIV(current->domain) ) + return -EPERM; + return 0; +} + +static XSM_DEFAULT(int, mem_event_op) (struct domain *d, int op) +{ + if ( !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; + return 0; +} + static XSM_DEFAULT(int, mem_sharing) (struct domain *d) { return 0; } +static XSM_DEFAULT(int, mem_sharing_op) (struct domain *d, struct domain *cd, int op) +{ + if ( !IS_PRIV_FOR(current->domain, cd) ) + return -EPERM; + return 0; +} + static XSM_DEFAULT(int, apic) (struct domain *d, int cmd) { if ( !IS_PRIV(d) ) diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 4900d1f..1b9f939 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -151,8 +151,11 @@ struct xsm_operations { int (*hvm_set_isa_irq_level) (struct domain *d); int (*hvm_set_pci_link_route) (struct domain *d); int (*hvm_inject_msi) (struct domain *d); - int (*mem_event) (struct domain *d); + int (*mem_event_setup) (struct domain *d); + int (*mem_event_control) (struct domain *d, int mode, int op); + int (*mem_event_op) (struct domain *d, int op); int (*mem_sharing) (struct domain *d); + int (*mem_sharing_op) (struct domain *d, struct domain *cd, int op); int (*apic) (struct domain *d, int cmd); int (*xen_settime) (void); int (*memtype) (uint32_t access); @@ -663,9 +666,19 @@ static inline int xsm_hvm_inject_msi (struct domain *d) return xsm_ops->hvm_inject_msi(d); } -static inline int xsm_mem_event (struct domain *d) +static inline int xsm_mem_event_setup (struct domain *d) { - return xsm_ops->mem_event(d); + return xsm_ops->mem_event_setup(d); +} + +static inline int xsm_mem_event_control (struct domain *d, int mode, int op) +{ + return xsm_ops->mem_event_control(d, mode, op); +} + +static inline int xsm_mem_event_op (struct domain *d, int op) +{ + return xsm_ops->mem_event_op(d, op); } static inline int xsm_mem_sharing (struct domain *d) @@ -673,6 +686,11 @@ static inline int xsm_mem_sharing (struct domain *d) return xsm_ops->mem_sharing(d); } +static inline int xsm_mem_sharing_op (struct domain *d, struct domain *cd, int op) +{ + return xsm_ops->mem_sharing_op(d, cd, op); +} + static inline int xsm_apic (struct domain *d, int cmd) { return xsm_ops->apic(d, cmd); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 43e8617..3926b2b 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -135,8 +135,11 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, hvm_set_isa_irq_level); set_to_dummy_if_null(ops, hvm_set_pci_link_route); set_to_dummy_if_null(ops, hvm_inject_msi); - set_to_dummy_if_null(ops, mem_event); + set_to_dummy_if_null(ops, mem_event_setup); + set_to_dummy_if_null(ops, mem_event_control); + set_to_dummy_if_null(ops, mem_event_op); set_to_dummy_if_null(ops, mem_sharing); + set_to_dummy_if_null(ops, mem_sharing_op); set_to_dummy_if_null(ops, apic); set_to_dummy_if_null(ops, xen_settime); set_to_dummy_if_null(ops, memtype); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index a8475ea..99d3e21 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1277,7 +1277,17 @@ static int flask_hvm_inject_msi(struct domain *d) return current_has_perm(d, SECCLASS_HVM, HVM__SEND_IRQ); } -static int flask_mem_event(struct domain *d) +static int flask_mem_event_setup(struct domain *d) +{ + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); +} + +static int flask_mem_event_control(struct domain *d, int mode, int op) +{ + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); +} + +static int flask_mem_event_op(struct domain *d, int op) { return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); } @@ -1287,6 +1297,14 @@ static int flask_mem_sharing(struct domain *d) return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING); } +static int flask_mem_sharing_op(struct domain *d, struct domain *cd, int op) +{ + int rc = current_has_perm(cd, SECCLASS_HVM, HVM__MEM_SHARING); + if ( rc ) + return rc; + return domain_has_perm(d, cd, SECCLASS_HVM, HVM__SHARE_MEM); +} + static int flask_apic(struct domain *d, int cmd) { u32 perm; @@ -1736,8 +1754,11 @@ static struct xsm_operations flask_ops = { .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level, .hvm_set_pci_link_route = flask_hvm_set_pci_link_route, .hvm_inject_msi = flask_hvm_inject_msi, - .mem_event = flask_mem_event, + .mem_event_setup = flask_mem_event_setup, + .mem_event_control = flask_mem_event_control, + .mem_event_op = flask_mem_event_op, .mem_sharing = flask_mem_sharing, + .mem_sharing_op = flask_mem_sharing_op, .apic = flask_apic, .xen_settime = flask_xen_settime, .memtype = flask_memtype, diff --git a/xen/xsm/flask/include/av_perm_to_string.h b/xen/xsm/flask/include/av_perm_to_string.h index 894910c..186f1fa 100644 --- a/xen/xsm/flask/include/av_perm_to_string.h +++ b/xen/xsm/flask/include/av_perm_to_string.h @@ -84,6 +84,7 @@ S_(SECCLASS_HVM, HVM__MEM_SHARING, "mem_sharing") S_(SECCLASS_HVM, HVM__AUDIT_P2M, "audit_p2m") S_(SECCLASS_HVM, HVM__SEND_IRQ, "send_irq") + S_(SECCLASS_HVM, HVM__SHARE_MEM, "share_mem") S_(SECCLASS_EVENT, EVENT__BIND, "bind") S_(SECCLASS_EVENT, EVENT__SEND, "send") S_(SECCLASS_EVENT, EVENT__STATUS, "status") diff --git a/xen/xsm/flask/include/av_permissions.h b/xen/xsm/flask/include/av_permissions.h index 1bdb515..b3831f6 100644 --- a/xen/xsm/flask/include/av_permissions.h +++ b/xen/xsm/flask/include/av_permissions.h @@ -87,6 +87,7 @@ #define HVM__MEM_SHARING 0x00001000UL #define HVM__AUDIT_P2M 0x00002000UL #define HVM__SEND_IRQ 0x00004000UL +#define HVM__SHARE_MEM 0x00008000UL #define EVENT__BIND 0x00000001UL #define EVENT__SEND 0x00000002UL -- 1.7.11.7 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |