# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1172756753 0
# Node ID 035d41b6c94c9449e97a066fa756d0f2e172f76b
# Parent bdebca505d8e608c58ada65c25d925e620ebb77c
acm: Fix the traversal of the event channel buckets and use the active
grant table entries instead of the shared ones. I had to move some
functions from grant_table.c into grant_table.h to make them usable by
the ACM module.
Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
---
xen/acm/acm_simple_type_enforcement_hooks.c | 81 +++++++++++++++-------------
xen/common/grant_table.c | 21 -------
xen/include/xen/grant_table.h | 22 +++++++
3 files changed, 68 insertions(+), 56 deletions(-)
diff -r bdebca505d8e -r 035d41b6c94c xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c Thu Mar 01 12:23:44
2007 +0000
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c Thu Mar 01 13:45:53
2007 +0000
@@ -177,7 +177,7 @@ ste_init_state(struct acm_ste_policy_buf
ssidref_t ste_ssidref, ste_rssidref;
struct domain *d, *rdom;
domid_t rdomid;
- struct grant_entry sha_copy;
+ struct active_grant_entry *act;
int port, i;
rcu_read_lock(&domlist_read_lock);
@@ -185,64 +185,75 @@ ste_init_state(struct acm_ste_policy_buf
/* go through all domains and adjust policy as if this domain was started
now */
for_each_domain ( d )
{
+ struct evtchn *ports;
+ unsigned int bucket;
ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
(struct acm_ssid_domain *)d->ssid);
ste_ssidref = ste_ssid->ste_ssidref;
traceprintk("%s: validating policy for eventch domain %x
(ste-Ref=%x).\n",
__func__, d->domain_id, ste_ssidref);
/* a) check for event channel conflicts */
- for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
+ for (bucket = 0; bucket < NR_EVTCHN_BUCKETS; bucket++) {
spin_lock(&d->evtchn_lock);
- if (d->evtchn[port] == NULL ||
- d->evtchn[port]->state == ECS_UNBOUND) {
+ ports = d->evtchn[bucket];
+ if (ports == NULL) {
spin_unlock(&d->evtchn_lock);
- continue;
+ break;
}
- if (d->evtchn[port]->state == ECS_INTERDOMAIN) {
- rdom = d->evtchn[port]->u.interdomain.remote_dom;
- rdomid = rdom->domain_id;
- } else {
- spin_unlock(&d->evtchn_lock);
- continue; /* port unused */
+
+ for (port=0; port < EVTCHNS_PER_BUCKET; port++) {
+ if (ports[port].state == ECS_INTERDOMAIN) {
+ rdom = ports[port].u.interdomain.remote_dom;
+ rdomid = rdom->domain_id;
+ } else {
+ continue; /* port unused */
+ }
+
+ /* rdom now has remote domain */
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(rdom->ssid));
+ ste_rssidref = ste_rssid->ste_ssidref;
+ traceprintk("%s: eventch: domain %x (ssidref %x) --> "
+ "domain %x (rssidref %x) used (port %x).\n",
+ __func__, d->domain_id, ste_ssidref,
+ rdom->domain_id, ste_rssidref, port);
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ if (!have_common_type(ste_ssidref, ste_rssidref)) {
+ printkd("%s: Policy violation in event channel domain "
+ "%x -> domain %x.\n",
+ __func__, d->domain_id, rdomid);
+ spin_unlock(&d->evtchn_lock);
+ goto out;
+ }
}
spin_unlock(&d->evtchn_lock);
-
- /* rdom now has remote domain */
- ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
- (struct acm_ssid_domain *)(rdom->ssid));
- ste_rssidref = ste_rssid->ste_ssidref;
- traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x
(rssidref %x) used (port %x).\n",
- __func__, d->domain_id, ste_ssidref, rdom->domain_id,
ste_rssidref, port);
- /* check whether on subj->ssid, obj->ssid share a common type*/
- if (!have_common_type(ste_ssidref, ste_rssidref)) {
- printkd("%s: Policy violation in event channel domain %x ->
domain %x.\n",
- __func__, d->domain_id, rdomid);
- goto out;
- }
}
+
/* b) check for grant table conflicts on shared pages */
spin_lock(&d->grant_table->lock);
- for ( i = 0; i < nr_grant_entries(d->grant_table); i++ ) {
-#define SPP (PAGE_SIZE / sizeof(struct grant_entry))
- sha_copy = d->grant_table->shared[i/SPP][i%SPP];
- if ( sha_copy.flags ) {
- printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu)
frame:(%lx)\n",
- __func__, d->domain_id, i, sha_copy.flags,
sha_copy.domid,
- (unsigned long)sha_copy.frame);
- rdomid = sha_copy.domid;
+ for ( i = 0; i < nr_active_grant_frames(d->grant_table); i++ ) {
+#define APP (PAGE_SIZE / sizeof(struct active_grant_entry))
+ act = &d->grant_table->active[i/APP][i%APP];
+ if ( act->pin != 0 ) {
+ printkd("%s: grant dom (%hu) SHARED (%d) pin (%d) "
+ "dom:(%hu) frame:(%lx)\n",
+ __func__, d->domain_id, i, act->pin,
+ act->domid, (unsigned long)act->frame);
+ rdomid = act->domid;
if ((rdom = rcu_lock_domain_by_id(rdomid)) == NULL) {
spin_unlock(&d->grant_table->lock);
printkd("%s: domain not found ERROR!\n", __func__);
goto out;
- };
+ }
/* rdom now has remote domain */
- ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
(struct acm_ssid_domain *)(rdom->ssid));
ste_rssidref = ste_rssid->ste_ssidref;
rcu_unlock_domain(rdom);
if (!have_common_type(ste_ssidref, ste_rssidref)) {
spin_unlock(&d->grant_table->lock);
- printkd("%s: Policy violation in grant table sharing
domain %x -> domain %x.\n",
+ printkd("%s: Policy violation in grant table "
+ "sharing domain %x -> domain %x.\n",
__func__, d->domain_id, rdomid);
goto out;
}
diff -r bdebca505d8e -r 035d41b6c94c xen/common/grant_table.c
--- a/xen/common/grant_table.c Thu Mar 01 12:23:44 2007 +0000
+++ b/xen/common/grant_table.c Thu Mar 01 13:45:53 2007 +0000
@@ -78,27 +78,6 @@ static unsigned inline int max_nr_maptra
return (max_nr_grant_frames * MAX_MAPTRACK_TO_GRANTS_RATIO);
}
-static inline unsigned int
-num_act_frames_from_sha_frames(const unsigned int num)
-{
- /* How many frames are needed for the active grant table,
- * given the size of the shared grant table?
- *
- * act_per_page = PAGE_SIZE / sizeof(active_grant_entry_t);
- * sha_per_page = PAGE_SIZE / sizeof(grant_entry_t);
- * num_sha_entries = num * sha_per_page;
- * num_act_frames = (num_sha_entries + (act_per_page-1)) / act_per_page;
- */
- return ((num * (PAGE_SIZE / sizeof(grant_entry_t))) +
- ((PAGE_SIZE / sizeof(struct active_grant_entry))-1))
- / (PAGE_SIZE / sizeof(struct active_grant_entry));
-}
-
-static inline unsigned int
-nr_active_grant_frames(struct grant_table *gt)
-{
- return num_act_frames_from_sha_frames(nr_grant_frames(gt));
-}
#define SHGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_t))
#define shared_entry(t, e) \
diff -r bdebca505d8e -r 035d41b6c94c xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h Thu Mar 01 12:23:44 2007 +0000
+++ b/xen/include/xen/grant_table.h Thu Mar 01 13:45:53 2007 +0000
@@ -120,4 +120,26 @@ static inline unsigned int nr_grant_entr
return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_t);
}
+static inline unsigned int
+num_act_frames_from_sha_frames(const unsigned int num)
+{
+ /* How many frames are needed for the active grant table,
+ * given the size of the shared grant table?
+ *
+ * act_per_page = PAGE_SIZE / sizeof(active_grant_entry_t);
+ * sha_per_page = PAGE_SIZE / sizeof(grant_entry_t);
+ * num_sha_entries = num * sha_per_page;
+ * num_act_frames = (num_sha_entries + (act_per_page-1)) / act_per_page;
+ */
+ return ((num * (PAGE_SIZE / sizeof(grant_entry_t))) +
+ ((PAGE_SIZE / sizeof(struct active_grant_entry))-1))
+ / (PAGE_SIZE / sizeof(struct active_grant_entry));
+}
+
+static inline unsigned int
+nr_active_grant_frames(struct grant_table *gt)
+{
+ return num_act_frames_from_sha_frames(nr_grant_frames(gt));
+}
+
#endif /* __XEN_GRANT_TABLE_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|