ia64/xen-unstable

changeset 14911:a99093e602c6

acm: Code restructuring on domain create/destroy.

When a domain is created, the function acm_domain_create() in
domain_create() is called that does what previously the pre- and
post_domain_create functions were doing. Similarly there's a function
acm_domain_destroy() in domain_kill() that reverts changes to state
when destroying a domain. There's no more separate initialization
necessary for domain-0, but domain_create takes one more parameter,
the ssidref. It is usually passed through the hypercall when a domain
is created.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kfraser@localhost.localdomain
date Tue Apr 24 16:52:15 2007 +0100 (2007-04-24)
parents 4bbc509a0b3f
children 9e86260b95a4
files xen/acm/acm_chinesewall_hooks.c xen/acm/acm_null_hooks.c xen/acm/acm_simple_type_enforcement_hooks.c xen/arch/ia64/xen/xensetup.c xen/arch/powerpc/setup.c xen/arch/x86/setup.c xen/common/domain.c xen/common/domctl.c xen/include/acm/acm_hooks.h xen/include/xen/sched.h
line diff
     1.1 --- a/xen/acm/acm_chinesewall_hooks.c	Tue Apr 24 16:28:37 2007 +0100
     1.2 +++ b/xen/acm/acm_chinesewall_hooks.c	Tue Apr 24 16:52:15 2007 +0100
     1.3 @@ -407,26 +407,23 @@ static int chwall_dump_ssid_types(ssidre
     1.4  
     1.5  /* -------- DOMAIN OPERATION HOOKS -----------*/
     1.6  
     1.7 -static int chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
     1.8 +static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
     1.9  {
    1.10      ssidref_t chwall_ssidref;
    1.11      int i, j;
    1.12      traceprintk("%s.\n", __func__);
    1.13  
    1.14 -    read_lock(&acm_bin_pol_rwlock);
    1.15      chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
    1.16      if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)
    1.17      {
    1.18          printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n",
    1.19                 __func__);
    1.20 -        read_unlock(&acm_bin_pol_rwlock);
    1.21          return ACM_ACCESS_DENIED;       /* catching and indicating config error */
    1.22      }
    1.23      if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
    1.24      {
    1.25          printk("%s: ERROR chwall_ssidref > max(%x).\n",
    1.26                 __func__, chwall_bin_pol.max_ssidrefs - 1);
    1.27 -        read_unlock(&acm_bin_pol_rwlock);
    1.28          return ACM_ACCESS_DENIED;
    1.29      }
    1.30      /* A: chinese wall check for conflicts */
    1.31 @@ -436,7 +433,6 @@ static int chwall_pre_domain_create(void
    1.32                                     chwall_bin_pol.max_types + i])
    1.33          {
    1.34              printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
    1.35 -            read_unlock(&acm_bin_pol_rwlock);
    1.36              return ACM_ACCESS_DENIED;
    1.37          }
    1.38  
    1.39 @@ -465,17 +461,16 @@ static int chwall_pre_domain_create(void
    1.40                                             chwall_bin_pol.max_types + j])
    1.41                  chwall_bin_pol.conflict_aggregate_set[j]++;
    1.42      }
    1.43 -    read_unlock(&acm_bin_pol_rwlock);
    1.44      return ACM_ACCESS_PERMITTED;
    1.45  }
    1.46  
    1.47 -static void chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
    1.48 +
    1.49 +static void _chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
    1.50  {
    1.51      int i, j;
    1.52      ssidref_t chwall_ssidref;
    1.53      traceprintk("%s.\n", __func__);
    1.54  
    1.55 -    read_lock(&acm_bin_pol_rwlock);
    1.56      chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
    1.57      /* adjust types ref-count for running domains */
    1.58      for (i = 0; i < chwall_bin_pol.max_types; i++)
    1.59 @@ -484,7 +479,6 @@ static void chwall_post_domain_create(do
    1.60                                     chwall_bin_pol.max_types + i];
    1.61      if (domid)
    1.62      {
    1.63 -        read_unlock(&acm_bin_pol_rwlock);
    1.64          return;
    1.65      }
    1.66      /* Xen does not call pre-create hook for DOM0;
    1.67 @@ -519,48 +513,34 @@ static void chwall_post_domain_create(do
    1.68                                             chwall_bin_pol.max_types + j])
    1.69                  chwall_bin_pol.conflict_aggregate_set[j]++;
    1.70      }
    1.71 -    read_unlock(&acm_bin_pol_rwlock);
    1.72      return;
    1.73  }
    1.74  
    1.75 -static void
    1.76 -chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
    1.77 +
    1.78 +/*
    1.79 + * To be called when creating a domain. If this call is unsuccessful,
    1.80 + * no state changes have occurred (adjustments of counters etc.). If it
    1.81 + * was successful, state was changed and can be undone using
    1.82 + * chwall_domain_destroy.
    1.83 + */
    1.84 +static int chwall_domain_create(void *subject_ssid, ssidref_t ssidref,
    1.85 +                                domid_t domid)
    1.86  {
    1.87 -    int i, j;
    1.88 -    ssidref_t chwall_ssidref;
    1.89 -    traceprintk("%s.\n", __func__);
    1.90 -
    1.91 +    int rc;
    1.92      read_lock(&acm_bin_pol_rwlock);
    1.93 -    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
    1.94 -    /* roll-back: re-adjust conflicting types aggregate */
    1.95 -    for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
    1.96 -    {
    1.97 -        int common = 0;
    1.98 -        /* check if conflict_set_i and ssidref have common types */
    1.99 -        for (j = 0; j < chwall_bin_pol.max_types; j++)
   1.100 -            if (chwall_bin_pol.
   1.101 -                conflict_sets[i * chwall_bin_pol.max_types + j]
   1.102 -                && chwall_bin_pol.ssidrefs[chwall_ssidref *
   1.103 -                                          chwall_bin_pol.max_types + j])
   1.104 -            {
   1.105 -                common = 1;
   1.106 -                break;
   1.107 -            }
   1.108 -        if (common == 0)
   1.109 -            continue;           /* try next conflict set, this one does not include any type of chwall_ssidref */
   1.110 -        /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
   1.111 -        for (j = 0; j < chwall_bin_pol.max_types; j++)
   1.112 -            if (chwall_bin_pol.
   1.113 -                conflict_sets[i * chwall_bin_pol.max_types + j]
   1.114 -                && !chwall_bin_pol.ssidrefs[chwall_ssidref *
   1.115 -                                           chwall_bin_pol.max_types + j])
   1.116 -                chwall_bin_pol.conflict_aggregate_set[j]--;
   1.117 +    rc = _chwall_pre_domain_create(subject_ssid, ssidref);
   1.118 +    if (rc == ACM_ACCESS_PERMITTED) {
   1.119 +        _chwall_post_domain_create(domid, ssidref);
   1.120      }
   1.121      read_unlock(&acm_bin_pol_rwlock);
   1.122 +    return rc;
   1.123  }
   1.124  
   1.125 -
   1.126 -static void chwall_post_domain_destroy(void *object_ssid, domid_t id)
   1.127 +/*
   1.128 + * This function undoes everything a successful call to
   1.129 + * chwall_domain_create has done.
   1.130 + */
   1.131 +static void chwall_domain_destroy(void *object_ssid, struct domain *d)
   1.132  {
   1.133      int i, j;
   1.134      struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
   1.135 @@ -614,10 +594,8 @@ struct acm_operations acm_chinesewall_op
   1.136      .dump_statistics = chwall_dump_stats,
   1.137      .dump_ssid_types = chwall_dump_ssid_types,
   1.138      /* domain management control hooks */
   1.139 -    .pre_domain_create = chwall_pre_domain_create,
   1.140 -    .post_domain_create = chwall_post_domain_create,
   1.141 -    .fail_domain_create = chwall_fail_domain_create,
   1.142 -    .post_domain_destroy = chwall_post_domain_destroy,
   1.143 +    .domain_create = chwall_domain_create,
   1.144 +    .domain_destroy = chwall_domain_destroy,
   1.145      /* event channel control hooks */
   1.146      .pre_eventchannel_unbound = NULL,
   1.147      .fail_eventchannel_unbound = NULL,
     2.1 --- a/xen/acm/acm_null_hooks.c	Tue Apr 24 16:28:37 2007 +0100
     2.2 +++ b/xen/acm/acm_null_hooks.c	Tue Apr 24 16:52:15 2007 +0100
     2.3 @@ -62,10 +62,8 @@ struct acm_operations acm_null_ops = {
     2.4      .dump_statistics = null_dump_stats,
     2.5      .dump_ssid_types = null_dump_ssid_types,
     2.6      /* domain management control hooks */
     2.7 -    .pre_domain_create = NULL,
     2.8 -    .post_domain_create = NULL,
     2.9 -    .fail_domain_create = NULL,
    2.10 -    .post_domain_destroy = NULL,
    2.11 +    .domain_create = NULL,
    2.12 +    .domain_destroy = NULL,
    2.13      /* event channel control hooks */
    2.14      .pre_eventchannel_unbound = NULL,
    2.15      .fail_eventchannel_unbound = NULL,
     3.1 --- a/xen/acm/acm_simple_type_enforcement_hooks.c	Tue Apr 24 16:28:37 2007 +0100
     3.2 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c	Tue Apr 24 16:52:15 2007 +0100
     3.3 @@ -500,11 +500,18 @@ ste_pre_domain_create(void *subject_ssid
     3.4      return ACM_ACCESS_PERMITTED;
     3.5  }
     3.6  
     3.7 +static int
     3.8 +ste_domain_create(void *subject_ssid, ssidref_t ssidref, domid_t  domid)
     3.9 +{
    3.10 +    return ste_pre_domain_create(subject_ssid, ssidref);
    3.11 +}
    3.12 +
    3.13 +
    3.14  static void 
    3.15 -ste_post_domain_destroy(void *subject_ssid, domid_t id)
    3.16 +ste_domain_destroy(void *subject_ssid, struct domain *d)
    3.17  {
    3.18      /* clean all cache entries for destroyed domain (might be re-used) */
    3.19 -    clean_id_from_cache(id);
    3.20 +    clean_id_from_cache(d->domain_id);
    3.21  }
    3.22  
    3.23  /* -------- EVENTCHANNEL OPERATIONS -----------*/
    3.24 @@ -685,10 +692,8 @@ struct acm_operations acm_simple_type_en
    3.25      .dump_ssid_types        = ste_dump_ssid_types,
    3.26  
    3.27      /* domain management control hooks */
    3.28 -    .pre_domain_create       = ste_pre_domain_create,
    3.29 -    .post_domain_create     = NULL,
    3.30 -    .fail_domain_create     = NULL,
    3.31 -    .post_domain_destroy    = ste_post_domain_destroy,
    3.32 +    .domain_create = ste_domain_create,
    3.33 +    .domain_destroy    = ste_domain_destroy,
    3.34  
    3.35      /* event channel control hooks */
    3.36      .pre_eventchannel_unbound   = ste_pre_eventchannel_unbound,
     4.1 --- a/xen/arch/ia64/xen/xensetup.c	Tue Apr 24 16:28:37 2007 +0100
     4.2 +++ b/xen/arch/ia64/xen/xensetup.c	Tue Apr 24 16:52:15 2007 +0100
     4.3 @@ -421,7 +421,7 @@ void start_kernel(void)
     4.4  
     4.5      scheduler_init();
     4.6      idle_vcpu[0] = (struct vcpu*) ia64_r13;
     4.7 -    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     4.8 +    idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
     4.9      if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
    4.10          BUG();
    4.11  
    4.12 @@ -508,7 +508,7 @@ printk("num_online_cpus=%d, max_cpus=%d\
    4.13      expose_p2m_init();
    4.14  
    4.15      /* Create initial domain 0. */
    4.16 -    dom0 = domain_create(0, 0);
    4.17 +    dom0 = domain_create(0, 0, DOM0_SSIDREF);
    4.18      if (dom0 == NULL)
    4.19          panic("Error creating domain 0\n");
    4.20      dom0_vcpu0 = alloc_vcpu(dom0, 0, 0);
     5.1 --- a/xen/arch/powerpc/setup.c	Tue Apr 24 16:28:37 2007 +0100
     5.2 +++ b/xen/arch/powerpc/setup.c	Tue Apr 24 16:52:15 2007 +0100
     5.3 @@ -162,7 +162,7 @@ static void __init start_of_day(void)
     5.4      scheduler_init();
     5.5  
     5.6      /* create idle domain */
     5.7 -    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     5.8 +    idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
     5.9      if ((idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL))
    5.10          BUG();
    5.11      set_current(idle_domain->vcpu[0]);
    5.12 @@ -370,7 +370,7 @@ static void __init __start_xen(multiboot
    5.13      percpu_free_unused_areas();
    5.14  
    5.15      /* Create initial domain 0. */
    5.16 -    dom0 = domain_create(0, 0);
    5.17 +    dom0 = domain_create(0, 0, DOM0_SSIDREF);
    5.18      if (dom0 == NULL)
    5.19          panic("Error creating domain 0\n");
    5.20  
    5.21 @@ -380,9 +380,6 @@ static void __init __start_xen(multiboot
    5.22  
    5.23      dom0->is_privileged = 1;
    5.24  
    5.25 -    /* Post-create hook sets security label. */
    5.26 -    acm_post_domain0_create(dom0->domain_id);
    5.27 -
    5.28      cmdline = (char *)(mod[0].string ? __va((ulong)mod[0].string) : NULL);
    5.29  
    5.30      /* scrub_heap_pages() requires IRQs enabled, and we're post IRQ setup... */
     6.1 --- a/xen/arch/x86/setup.c	Tue Apr 24 16:28:37 2007 +0100
     6.2 +++ b/xen/arch/x86/setup.c	Tue Apr 24 16:52:15 2007 +0100
     6.3 @@ -254,7 +254,7 @@ static void __init init_idle_domain(void
     6.4      /* Domain creation requires that scheduler structures are initialised. */
     6.5      scheduler_init();
     6.6  
     6.7 -    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     6.8 +    idle_domain = domain_create(IDLE_DOMAIN_ID, 0, 0);
     6.9      if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
    6.10          BUG();
    6.11  
    6.12 @@ -727,15 +727,12 @@ void __init __start_xen(multiboot_info_t
    6.13      acm_init(_policy_start, _policy_len);
    6.14  
    6.15      /* Create initial domain 0. */
    6.16 -    dom0 = domain_create(0, 0);
    6.17 +    dom0 = domain_create(0, 0, DOM0_SSIDREF);
    6.18      if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
    6.19          panic("Error creating domain 0\n");
    6.20  
    6.21      dom0->is_privileged = 1;
    6.22  
    6.23 -    /* Post-create hook sets security label. */
    6.24 -    acm_post_domain0_create(dom0->domain_id);
    6.25 -
    6.26      /* Grab the DOM0 command line. */
    6.27      cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
    6.28      if ( cmdline != NULL )
     7.1 --- a/xen/common/domain.c	Tue Apr 24 16:28:37 2007 +0100
     7.2 +++ b/xen/common/domain.c	Tue Apr 24 16:52:15 2007 +0100
     7.3 @@ -28,6 +28,7 @@
     7.4  #include <asm/debugger.h>
     7.5  #include <public/sched.h>
     7.6  #include <public/vcpu.h>
     7.7 +#include <acm/acm_hooks.h>
     7.8  
     7.9  /* Protect updates/reads (resp.) of domain_list and domain_hash. */
    7.10  DEFINE_SPINLOCK(domlist_update_lock);
    7.11 @@ -178,7 +179,7 @@ struct vcpu *alloc_idle_vcpu(unsigned in
    7.12          return v;
    7.13  
    7.14      d = (vcpu_id == 0) ?
    7.15 -        domain_create(IDLE_DOMAIN_ID, 0) :
    7.16 +        domain_create(IDLE_DOMAIN_ID, 0, 0) :
    7.17          idle_vcpu[cpu_id - vcpu_id]->domain;
    7.18      BUG_ON(d == NULL);
    7.19  
    7.20 @@ -188,7 +189,8 @@ struct vcpu *alloc_idle_vcpu(unsigned in
    7.21      return v;
    7.22  }
    7.23  
    7.24 -struct domain *domain_create(domid_t domid, unsigned int domcr_flags)
    7.25 +struct domain *domain_create(
    7.26 +    domid_t domid, unsigned int domcr_flags, ssidref_t ssidref)
    7.27  {
    7.28      struct domain *d, **pd;
    7.29  
    7.30 @@ -210,18 +212,21 @@ struct domain *domain_create(domid_t dom
    7.31  
    7.32          if ( grant_table_create(d) != 0 )
    7.33              goto fail2;
    7.34 +
    7.35 +        if ( acm_domain_create(d, ssidref) != 0 )
    7.36 +            goto fail3;
    7.37      }
    7.38  
    7.39      if ( arch_domain_create(d) != 0 )
    7.40 -        goto fail3;
    7.41 +        goto fail4;
    7.42  
    7.43      d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
    7.44      d->irq_caps   = rangeset_new(d, "Interrupts", 0);
    7.45      if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
    7.46 -        goto fail4;
    7.47 +        goto fail5;
    7.48  
    7.49      if ( sched_init_domain(d) != 0 )
    7.50 -        goto fail4;
    7.51 +        goto fail5;
    7.52  
    7.53      if ( !is_idle_domain(d) )
    7.54      {
    7.55 @@ -243,8 +248,11 @@ struct domain *domain_create(domid_t dom
    7.56  
    7.57      return d;
    7.58  
    7.59 + fail5:
    7.60 +    arch_domain_destroy(d);
    7.61   fail4:
    7.62 -    arch_domain_destroy(d);
    7.63 +    if ( !is_idle_domain(d) )
    7.64 +        acm_domain_destroy(d);
    7.65   fail3:
    7.66      if ( !is_idle_domain(d) )
    7.67          grant_table_destroy(d);
    7.68 @@ -313,6 +321,7 @@ void domain_kill(struct domain *d)
    7.69          return;
    7.70      }
    7.71  
    7.72 +    acm_domain_destroy(d);
    7.73      gnttab_release_mappings(d);
    7.74      domain_relinquish_resources(d);
    7.75      put_domain(d);
     8.1 --- a/xen/common/domctl.c	Tue Apr 24 16:28:37 2007 +0100
     8.2 +++ b/xen/common/domctl.c	Tue Apr 24 16:52:15 2007 +0100
     8.3 @@ -176,7 +176,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
     8.4  {
     8.5      long ret = 0;
     8.6      struct xen_domctl curop, *op = &curop;
     8.7 -    void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
     8.8      static DEFINE_SPINLOCK(domctl_lock);
     8.9  
    8.10      if ( !IS_PRIV(current->domain) )
    8.11 @@ -188,9 +187,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    8.12      if ( op->interface_version != XEN_DOMCTL_INTERFACE_VERSION )
    8.13          return -EACCES;
    8.14  
    8.15 -    if ( acm_pre_domctl(op, &ssid) )
    8.16 -        return -EPERM;
    8.17 -
    8.18      spin_lock(&domctl_lock);
    8.19  
    8.20      switch ( op->cmd )
    8.21 @@ -334,7 +330,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    8.22              domcr_flags |= DOMCRF_hvm;
    8.23  
    8.24          ret = -ENOMEM;
    8.25 -        if ( (d = domain_create(dom, domcr_flags)) == NULL )
    8.26 +        d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
    8.27 +        if ( d == NULL )
    8.28              break;
    8.29  
    8.30          ret = 0;
    8.31 @@ -717,11 +714,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    8.32  
    8.33      spin_unlock(&domctl_lock);
    8.34  
    8.35 -    if ( ret == 0 )
    8.36 -        acm_post_domctl(op, &ssid);
    8.37 -    else
    8.38 -        acm_fail_domctl(op, &ssid);
    8.39 -
    8.40      return ret;
    8.41  }
    8.42  
     9.1 --- a/xen/include/acm/acm_hooks.h	Tue Apr 24 16:28:37 2007 +0100
     9.2 +++ b/xen/include/acm/acm_hooks.h	Tue Apr 24 16:52:15 2007 +0100
     9.3 @@ -96,10 +96,9 @@ struct acm_operations {
     9.4      int  (*dump_statistics)            (u8 *buffer, u16 buf_size);
     9.5      int  (*dump_ssid_types)            (ssidref_t ssidref, u8 *buffer, u16 buf_size);
     9.6      /* domain management control hooks (can be NULL) */
     9.7 -    int  (*pre_domain_create)          (void *subject_ssid, ssidref_t ssidref);
     9.8 -    void (*post_domain_create)         (domid_t domid, ssidref_t ssidref);
     9.9 -    void (*fail_domain_create)         (void *subject_ssid, ssidref_t ssidref);
    9.10 -    void (*post_domain_destroy)        (void *object_ssid, domid_t id);
    9.11 +    int  (*domain_create)              (void *subject_ssid, ssidref_t ssidref,
    9.12 +                                        domid_t domid);
    9.13 +    void (*domain_destroy)             (void *object_ssid, struct domain *d);
    9.14      /* event channel control hooks  (can be NULL) */
    9.15      int  (*pre_eventchannel_unbound)      (domid_t id1, domid_t id2);
    9.16      void (*fail_eventchannel_unbound)     (domid_t id1, domid_t id2);
    9.17 @@ -128,14 +127,9 @@ extern struct acm_operations *acm_second
    9.18  # define traceprintk(fmt, args...)
    9.19  #endif
    9.20  
    9.21 +
    9.22  #ifndef ACM_SECURITY
    9.23  
    9.24 -static inline int acm_pre_domctl(struct xen_domctl *op, void **ssid) 
    9.25 -{ return 0; }
    9.26 -static inline void acm_post_domctl(struct xen_domctl *op, void *ssid) 
    9.27 -{ return; }
    9.28 -static inline void acm_fail_domctl(struct xen_domctl *op, void *ssid) 
    9.29 -{ return; }
    9.30  static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
    9.31  { return 0; }
    9.32  static inline int acm_pre_eventchannel_interdomain(domid_t id)
    9.33 @@ -148,53 +142,17 @@ static inline int acm_init(char *policy_
    9.34  { return 0; }
    9.35  static inline int acm_is_policy(char *buf, unsigned long len)
    9.36  { return 0; }
    9.37 -static inline void acm_post_domain0_create(domid_t domid) 
    9.38 -{ return; }
    9.39  static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
    9.40  { return 0; }
    9.41 +static inline int acm_domain_create(struct domain *d, ssidref_t ssidref)
    9.42 +{ return 0; }
    9.43 +static inline void acm_domain_destroy(struct domain *d)
    9.44 +{ return; }
    9.45 +
    9.46 +#define DOM0_SSIDREF 0x0
    9.47  
    9.48  #else
    9.49  
    9.50 -static inline int acm_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
    9.51 -{
    9.52 -    if ((acm_primary_ops->pre_domain_create != NULL) && 
    9.53 -        acm_primary_ops->pre_domain_create(subject_ssid, ssidref))
    9.54 -        return ACM_ACCESS_DENIED;
    9.55 -    else if ((acm_secondary_ops->pre_domain_create != NULL) && 
    9.56 -             acm_secondary_ops->pre_domain_create(subject_ssid, ssidref)) {
    9.57 -        /* roll-back primary */
    9.58 -        if (acm_primary_ops->fail_domain_create != NULL)
    9.59 -            acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
    9.60 -        return ACM_ACCESS_DENIED;
    9.61 -    } else
    9.62 -        return ACM_ACCESS_PERMITTED;
    9.63 -}
    9.64 -
    9.65 -static inline void acm_post_domain_create(domid_t domid, ssidref_t ssidref)
    9.66 -{
    9.67 -    if (acm_primary_ops->post_domain_create != NULL)
    9.68 -        acm_primary_ops->post_domain_create(domid, ssidref);
    9.69 -    if (acm_secondary_ops->post_domain_create != NULL)
    9.70 -        acm_secondary_ops->post_domain_create(domid, ssidref);
    9.71 -}
    9.72 -
    9.73 -static inline void acm_fail_domain_create(
    9.74 -    void *subject_ssid, ssidref_t ssidref)
    9.75 -{
    9.76 -    if (acm_primary_ops->fail_domain_create != NULL)
    9.77 -        acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
    9.78 -    if (acm_secondary_ops->fail_domain_create != NULL)
    9.79 -        acm_secondary_ops->fail_domain_create(subject_ssid, ssidref);
    9.80 -}
    9.81 -
    9.82 -static inline void acm_post_domain_destroy(void *object_ssid, domid_t id)
    9.83 -{
    9.84 -    if (acm_primary_ops->post_domain_destroy != NULL)
    9.85 -        acm_primary_ops->post_domain_destroy(object_ssid, id);
    9.86 -    if (acm_secondary_ops->post_domain_destroy != NULL)
    9.87 -        acm_secondary_ops->post_domain_destroy(object_ssid, id);
    9.88 -    return;
    9.89 -}
    9.90  
    9.91  static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
    9.92  {
    9.93 @@ -226,85 +184,6 @@ static inline int acm_pre_eventchannel_i
    9.94          return ACM_ACCESS_PERMITTED;
    9.95  }
    9.96  
    9.97 -static inline int acm_pre_domctl(struct xen_domctl *op, void **ssid) 
    9.98 -{
    9.99 -    int ret = -EACCES;
   9.100 -    struct domain *d;
   9.101 -
   9.102 -    switch(op->cmd) {
   9.103 -    case XEN_DOMCTL_createdomain:
   9.104 -        ret = acm_pre_domain_create(
   9.105 -            current->domain->ssid, op->u.createdomain.ssidref);
   9.106 -        break;
   9.107 -    case XEN_DOMCTL_destroydomain:
   9.108 -        if (*ssid != NULL) {
   9.109 -            printkd("%s: Warning. Overlapping destruction.\n", 
   9.110 -                    __func__);
   9.111 -            return -EACCES;
   9.112 -        }
   9.113 -        d = rcu_lock_domain_by_id(op->domain);
   9.114 -        if (d != NULL) {
   9.115 -            *ssid = d->ssid; /* save for post destroy when d is gone */
   9.116 -            if (*ssid == NULL) {
   9.117 -                printk("%s: Warning. Destroying domain without ssid pointer.\n", 
   9.118 -                       __func__);
   9.119 -                rcu_unlock_domain(d);
   9.120 -                return -EACCES;
   9.121 -            }
   9.122 -            d->ssid = NULL; /* make sure it's not used any more */
   9.123 -             /* no policy-specific hook */
   9.124 -            rcu_unlock_domain(d);
   9.125 -            ret = 0;
   9.126 -        }
   9.127 -        break;
   9.128 -    default:
   9.129 -        ret = 0; /* ok */
   9.130 -    }
   9.131 -    return ret;
   9.132 -}
   9.133 -
   9.134 -static inline void acm_post_domctl(struct xen_domctl *op, void **ssid)
   9.135 -{
   9.136 -    switch(op->cmd) {
   9.137 -    case XEN_DOMCTL_createdomain:
   9.138 -        /* initialialize shared sHype security labels for new domain */
   9.139 -        acm_init_domain_ssid(
   9.140 -            op->domain, op->u.createdomain.ssidref);
   9.141 -        acm_post_domain_create(
   9.142 -            op->domain, op->u.createdomain.ssidref);
   9.143 -        break;
   9.144 -    case XEN_DOMCTL_destroydomain:
   9.145 -        if (*ssid == NULL) {
   9.146 -            printkd("%s: ERROR. SSID unset.\n",
   9.147 -                    __func__);
   9.148 -            break;
   9.149 -        }
   9.150 -        acm_post_domain_destroy(*ssid, op->domain);
   9.151 -        /* free security ssid for the destroyed domain (also if null policy */
   9.152 -        acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
   9.153 -        *ssid = NULL;
   9.154 -        break;
   9.155 -    }
   9.156 -}
   9.157 -
   9.158 -static inline void acm_fail_domctl(struct xen_domctl *op, void **ssid)
   9.159 -{
   9.160 -    switch(op->cmd) {
   9.161 -    case XEN_DOMCTL_createdomain:
   9.162 -        acm_fail_domain_create(
   9.163 -            current->domain->ssid, op->u.createdomain.ssidref);
   9.164 -        break;
   9.165 -    case XEN_DOMCTL_destroydomain:
   9.166 -        /*  we don't handle domain destroy failure but at least free the ssid */
   9.167 -        if (*ssid == NULL) {
   9.168 -            printkd("%s: ERROR. SSID unset.\n",
   9.169 -                    __func__);
   9.170 -            break;
   9.171 -        }
   9.172 -        acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
   9.173 -        *ssid = NULL;
   9.174 -    }
   9.175 -}
   9.176  
   9.177  static inline int acm_pre_grant_map_ref(domid_t id)
   9.178  {
   9.179 @@ -348,15 +227,52 @@ static inline int acm_pre_grant_setup(do
   9.180      }
   9.181  }
   9.182  
   9.183 -static inline void acm_post_domain0_create(domid_t domid)
   9.184 +
   9.185 +static inline int acm_domain_create(struct domain *d, ssidref_t ssidref)
   9.186  {
   9.187 -    /* initialialize shared sHype security labels for new domain */
   9.188 -    int dom0_ssidref = dom0_ste_ssidref << 16 | dom0_chwall_ssidref;
   9.189 +    void *subject_ssid = current->domain->ssid;
   9.190 +    domid_t domid = d->domain_id;
   9.191 +    int rc;
   9.192  
   9.193 -    acm_init_domain_ssid(domid, dom0_ssidref);
   9.194 -    acm_post_domain_create(domid, dom0_ssidref);
   9.195 +    /*
   9.196 +       To be called when a domain is created; returns '0' if the
   9.197 +       domain is allowed to be created, != '0' if not.
   9.198 +     */
   9.199 +    rc = acm_init_domain_ssid_new(d, ssidref);
   9.200 +    if (rc != ACM_OK)
   9.201 +        return rc;
   9.202 +
   9.203 +    if ((acm_primary_ops->domain_create != NULL) &&
   9.204 +        acm_primary_ops->domain_create(subject_ssid, ssidref, domid)) {
   9.205 +        return ACM_ACCESS_DENIED;
   9.206 +    } else if ((acm_secondary_ops->domain_create != NULL) &&
   9.207 +                acm_secondary_ops->domain_create(subject_ssid, ssidref,
   9.208 +                                                 domid)) {
   9.209 +        /* roll-back primary */
   9.210 +        if (acm_primary_ops->domain_destroy != NULL)
   9.211 +            acm_primary_ops->domain_destroy(d->ssid, d);
   9.212 +        acm_free_domain_ssid(d->ssid);
   9.213 +        return ACM_ACCESS_DENIED;
   9.214 +    }
   9.215 +
   9.216 +    return 0;
   9.217  }
   9.218  
   9.219 +
   9.220 +static inline void acm_domain_destroy(struct domain *d)
   9.221 +{
   9.222 +    void *ssid = d->ssid;
   9.223 +    if (ssid != NULL) {
   9.224 +        if (acm_primary_ops->domain_destroy != NULL)
   9.225 +            acm_primary_ops->domain_destroy(ssid, d);
   9.226 +        if (acm_secondary_ops->domain_destroy != NULL)
   9.227 +            acm_secondary_ops->domain_destroy(ssid, d);
   9.228 +        /* free security ssid for the destroyed domain (also if null policy */
   9.229 +        acm_free_domain_ssid((struct acm_ssid_domain *)(ssid));
   9.230 +    }
   9.231 +}
   9.232 +
   9.233 +
   9.234  static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
   9.235  {
   9.236      if ((acm_primary_ops->sharing != NULL) &&
   9.237 @@ -375,6 +291,8 @@ extern int acm_init(char *policy_start, 
   9.238  /* Return true iff buffer has an acm policy magic number.  */
   9.239  extern int acm_is_policy(char *buf, unsigned long len);
   9.240  
   9.241 +#define DOM0_SSIDREF (dom0_ste_ssidref << 16 | dom0_chwall_ssidref)
   9.242 +
   9.243  #endif
   9.244  
   9.245  #endif
    10.1 --- a/xen/include/xen/sched.h	Tue Apr 24 16:28:37 2007 +0100
    10.2 +++ b/xen/include/xen/sched.h	Tue Apr 24 16:52:15 2007 +0100
    10.3 @@ -10,6 +10,7 @@
    10.4  #include <public/xen.h>
    10.5  #include <public/domctl.h>
    10.6  #include <public/vcpu.h>
    10.7 +#include <public/acm.h>
    10.8  #include <xen/time.h>
    10.9  #include <xen/timer.h>
   10.10  #include <xen/grant_table.h>
   10.11 @@ -296,7 +297,8 @@ static inline struct domain *get_current
   10.12      return d;
   10.13  }
   10.14  
   10.15 -struct domain *domain_create(domid_t domid, unsigned int domcr_flags);
   10.16 +struct domain *domain_create(
   10.17 +    domid_t domid, unsigned int domcr_flags, ssidref_t ssidref);
   10.18   /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */
   10.19  #define _DOMCRF_hvm 0
   10.20  #define DOMCRF_hvm  (1U<<_DOMCRF_hvm)