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@tycho.nsa.gov>
Acked-by: Tim Deegan <tim@xen.org>
Acked-by: Jan Beulich <jbeulich@suse.com>
Committed-by: Keir Fraser <keir@xen.org>
This commit is contained in:
Daniel De Graaf committed 2013-01-11 10:39:20 +00:00
1 parent 9e41e410f6
commit 79cd41ecce
11 files changed
+128 -46

No files matched your search

+3 -5
View File
@@ -1223,10 +1223,8 @@ long arch_do_domctl(
case XEN_DOMCTL_mem_event_op:
{
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));
copyback = 1;
}
break;
@@ -1265,7 +1263,7 @@ long arch_do_domctl(
if ( current->domain == d )
break;
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;
+12 -29
View File
@@ -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 )
+21 -4
View File
@@ -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);
+15
View File
@@ -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;
-1
View File
@@ -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);
+6
View File
@@ -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)
{
+22 -1
View File
@@ -551,16 +551,37 @@ static XSM_INLINE int xsm_hvm_inject_msi(struct domain *d)
return 0;
}
static XSM_INLINE int xsm_mem_event(struct domain *d)
static XSM_INLINE int xsm_mem_event_setup(struct domain *d)
{
return 0;
}
static XSM_INLINE int xsm_mem_event_control(struct domain *d, int mode, int op)
{
if ( !IS_PRIV(current->domain) )
return -EPERM;
return 0;
}
static XSM_INLINE int xsm_mem_event_op(struct domain *d, int op)
{
if ( !IS_PRIV_FOR(current->domain, d) )
return -EPERM;
return 0;
}
static XSM_INLINE int xsm_mem_sharing(struct domain *d)
{
return 0;
}
static XSM_INLINE int xsm_mem_sharing_op(struct domain *d, struct domain *cd, int op)
{
if ( !IS_PRIV_FOR(current->domain, cd) )
return -EPERM;
return 0;
}
static XSM_INLINE int xsm_apic(struct domain *d, int cmd)
{
if ( !IS_PRIV(d) )
+21 -3
View File
@@ -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);
@@ -665,9 +668,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)
@@ -675,6 +688,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);
+4 -1
View File
@@ -136,8 +136,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);
+23 -2
View File
@@ -1278,7 +1278,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);
}
@@ -1288,6 +1298,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;
@@ -1737,8 +1755,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,
+1
View File
@@ -102,6 +102,7 @@ class hvm
mem_sharing
audit_p2m
send_irq
share_mem
}
class event
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.