ia64/xen-unstable

changeset 16508:d2bef6551c12

xsm: Consolidate xsm processing within domain control hypercall.

Consolidate all the 15 xsm calls from within do_domctl a single
routine that is only called in one place, xsm_domctl:

int xsm_domctl (struct xen_domctl *domctl);

The parameter to domctl is a pointer to the xen_domctl structure that
contains a union of all sub operational parameters.

The benefits of this patch include:

(1) Easier to maintain because there is one place in the entire
hypercall to check with the xsm, instead of 15 or more.

(2) New sub-operations don't also need to add a corresponding xsm
function.

(3) Removes 178 lines of code.

(4) Enhanced security because of 1-4.

Signed-off-by: Mike D. Day <ncmike@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Dec 04 10:25:35 2007 +0000 (2007-12-04)
parents 190c2592247d
children 0e8e68cfc8ac
files xen/common/domctl.c xen/include/xsm/xsm.h
line diff
     1.1 --- a/xen/common/domctl.c	Tue Dec 04 10:17:32 2007 +0000
     1.2 +++ b/xen/common/domctl.c	Tue Dec 04 10:25:35 2007 +0000
     1.3 @@ -187,6 +187,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
     1.4  
     1.5      spin_lock(&domctl_lock);
     1.6  
     1.7 +    if ( xsm_domctl(op) )
     1.8 +        goto domctl_out;
     1.9 +
    1.10      switch ( op->cmd )
    1.11      {
    1.12  
    1.13 @@ -201,10 +204,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    1.14          if ( d == NULL )
    1.15              break;
    1.16  
    1.17 -        ret = xsm_setvcpucontext(d);
    1.18 -        if ( ret )
    1.19 -            goto svc_out;
    1.20 -
    1.21          ret = -EINVAL;
    1.22          if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
    1.23              goto svc_out;
    1.24 @@ -252,17 +251,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    1.25          ret = -ESRCH;
    1.26          if ( d != NULL )
    1.27          {
    1.28 -            ret = xsm_pausedomain(d);
    1.29 -            if ( ret )
    1.30 -                goto pausedomain_out;
    1.31 -
    1.32              ret = -EINVAL;
    1.33              if ( d != current->domain )
    1.34              {
    1.35                  domain_pause_by_systemcontroller(d);
    1.36                  ret = 0;
    1.37              }
    1.38 -        pausedomain_out:
    1.39              rcu_unlock_domain(d);
    1.40          }
    1.41      }
    1.42 @@ -275,14 +269,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    1.43          ret = -ESRCH;
    1.44          if ( d == NULL )
    1.45              break;
    1.46 -
    1.47 -        ret = xsm_unpausedomain(d);
    1.48 -        if ( ret )
    1.49 -        {
    1.50 -            rcu_unlock_domain(d);
    1.51 -            break;
    1.52 -        }
    1.53 -
    1.54          domain_unpause_by_systemcontroller(d);
    1.55          rcu_unlock_domain(d);
    1.56          ret = 0;
    1.57 @@ -297,13 +283,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    1.58          if ( d == NULL )
    1.59              break;
    1.60  
    1.61 -        ret = xsm_resumedomain(d);
    1.62 -        if ( ret )
    1.63 -        {
    1.64 -            rcu_unlock_domain(d);
    1.65 -            break;
    1.66 -        }
    1.67 -
    1.68          domain_resume(d);
    1.69          rcu_unlock_domain(d);
    1.70          ret = 0;
    1.71 @@ -379,13 +358,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    1.72          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
    1.73              break;
    1.74  
    1.75 -        ret = xsm_max_vcpus(d);
    1.76 -        if ( ret )
    1.77 -        {
    1.78 -            rcu_unlock_domain(d);
    1.79 -            break;
    1.80 -        }
    1.81 -
    1.82          /* Needed, for example, to ensure writable p.t. state is synced. */
    1.83          domain_pause(d);
    1.84  
    1.85 @@ -422,7 +394,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    1.86          ret = -ESRCH;
    1.87          if ( d != NULL )
    1.88          {
    1.89 -            ret = xsm_destroydomain(d) ? : domain_kill(d);
    1.90 +            domain_kill(d);
    1.91              rcu_unlock_domain(d);
    1.92          }
    1.93      }
    1.94 @@ -440,10 +412,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
    1.95          if ( d == NULL )
    1.96              break;
    1.97  
    1.98 -        ret = xsm_vcpuaffinity(op->cmd, d);
    1.99 -        if ( ret )
   1.100 -            goto vcpuaffinity_out;
   1.101 -
   1.102          ret = -EINVAL;
   1.103          if ( op->u.vcpuaffinity.vcpu >= MAX_VIRT_CPUS )
   1.104              goto vcpuaffinity_out;
   1.105 @@ -478,15 +446,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.106          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
   1.107              break;
   1.108  
   1.109 -        ret = xsm_scheduler(d);
   1.110 -        if ( ret )
   1.111 -            goto scheduler_op_out;
   1.112 -
   1.113          ret = sched_adjust(d, &op->u.scheduler_op);
   1.114          if ( copy_to_guest(u_domctl, op, 1) )
   1.115              ret = -EFAULT;
   1.116  
   1.117 -    scheduler_op_out:
   1.118          rcu_unlock_domain(d);
   1.119      }
   1.120      break;
   1.121 @@ -509,17 +472,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.122              break;
   1.123          }
   1.124  
   1.125 -        ret = xsm_getdomaininfo(d);
   1.126 -        if ( ret )
   1.127 -            goto getdomaininfo_out;
   1.128 -
   1.129          getdomaininfo(d, &op->u.getdomaininfo);
   1.130  
   1.131          op->domain = op->u.getdomaininfo.domain;
   1.132          if ( copy_to_guest(u_domctl, op, 1) )
   1.133              ret = -EFAULT;
   1.134  
   1.135 -    getdomaininfo_out:
   1.136          rcu_read_unlock(&domlist_read_lock);
   1.137      }
   1.138      break;
   1.139 @@ -534,10 +492,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.140          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
   1.141              break;
   1.142  
   1.143 -        ret = xsm_getvcpucontext(d);
   1.144 -        if ( ret )
   1.145 -            goto getvcpucontext_out;
   1.146 -
   1.147          ret = -EINVAL;
   1.148          if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS )
   1.149              goto getvcpucontext_out;
   1.150 @@ -594,10 +548,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.151          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
   1.152              break;
   1.153  
   1.154 -        ret = xsm_getvcpuinfo(d);
   1.155 -        if ( ret )
   1.156 -            goto getvcpuinfo_out;
   1.157 -
   1.158          ret = -EINVAL;
   1.159          if ( op->u.getvcpuinfo.vcpu >= MAX_VIRT_CPUS )
   1.160              goto getvcpuinfo_out;
   1.161 @@ -633,10 +583,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.162          if ( d == NULL )
   1.163              break;
   1.164  
   1.165 -        ret = xsm_setdomainmaxmem(d);
   1.166 -        if ( ret )
   1.167 -            goto max_mem_out;
   1.168 -
   1.169          ret = -EINVAL;
   1.170          new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10);
   1.171  
   1.172 @@ -651,7 +597,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.173          }
   1.174          spin_unlock(&d->page_alloc_lock);
   1.175  
   1.176 -    max_mem_out:
   1.177          rcu_unlock_domain(d);
   1.178      }
   1.179      break;
   1.180 @@ -665,13 +610,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.181          if ( d == NULL )
   1.182              break;
   1.183  
   1.184 -        ret = xsm_setdomainhandle(d);
   1.185 -        if ( ret )
   1.186 -        {
   1.187 -            rcu_unlock_domain(d);
   1.188 -            break;
   1.189 -        }
   1.190 -
   1.191          memcpy(d->handle, op->u.setdomainhandle.handle,
   1.192                 sizeof(xen_domain_handle_t));
   1.193          rcu_unlock_domain(d);
   1.194 @@ -688,13 +626,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.195          if ( d == NULL )
   1.196              break;
   1.197  
   1.198 -        ret = xsm_setdebugging(d);
   1.199 -        if ( ret )
   1.200 -        {
   1.201 -            rcu_unlock_domain(d);
   1.202 -            break;
   1.203 -        }
   1.204 -
   1.205          domain_pause(d);
   1.206          d->debugger_attached = !!op->u.setdebugging.enable;
   1.207          domain_unpause(d); /* causes guest to latch new status */
   1.208 @@ -717,16 +648,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.209          if ( d == NULL )
   1.210              break;
   1.211  
   1.212 -        ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access);
   1.213 -        if ( ret )
   1.214 -            goto irq_permission_out;
   1.215 -        
   1.216          if ( op->u.irq_permission.allow_access )
   1.217              ret = irq_permit_access(d, pirq);
   1.218          else
   1.219              ret = irq_deny_access(d, pirq);
   1.220  
   1.221 -    irq_permission_out:
   1.222          rcu_unlock_domain(d);
   1.223      }
   1.224      break;
   1.225 @@ -746,16 +672,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.226          if ( d == NULL )
   1.227              break;
   1.228  
   1.229 -        ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access);
   1.230 -        if ( ret )
   1.231 -            goto iomem_permission_out;
   1.232 -
   1.233          if ( op->u.iomem_permission.allow_access )
   1.234              ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
   1.235          else
   1.236              ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
   1.237  
   1.238 -    iomem_permission_out:
   1.239          rcu_unlock_domain(d);
   1.240      }
   1.241      break;
   1.242 @@ -768,13 +689,6 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.243          d = rcu_lock_domain_by_id(op->domain);
   1.244          if ( d != NULL )
   1.245          {
   1.246 -            ret = xsm_domain_settime(d);
   1.247 -            if ( ret )
   1.248 -            {
   1.249 -                rcu_unlock_domain(d);
   1.250 -                break;
   1.251 -            }
   1.252 -
   1.253              d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
   1.254              rcu_unlock_domain(d);
   1.255              ret = 0;
   1.256 @@ -787,6 +701,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   1.257          break;
   1.258      }
   1.259  
   1.260 +domctl_out:
   1.261      spin_unlock(&domctl_lock);
   1.262  
   1.263      return ret;
     2.1 --- a/xen/include/xsm/xsm.h	Tue Dec 04 10:17:32 2007 +0000
     2.2 +++ b/xen/include/xsm/xsm.h	Tue Dec 04 10:25:35 2007 +0000
     2.3 @@ -50,34 +50,18 @@ extern xsm_initcall_t __xsm_initcall_sta
     2.4  
     2.5  struct xsm_operations {
     2.6      void (*security_domaininfo) (struct domain *d,
     2.7 -                                        struct xen_domctl_getdomaininfo *info);
     2.8 -    int (*setvcpucontext) (struct domain *d);
     2.9 -    int (*pausedomain) (struct domain *d);
    2.10 -    int (*unpausedomain) (struct domain *d);
    2.11 -    int (*resumedomain) (struct domain *d);
    2.12 +                                 struct xen_domctl_getdomaininfo *info);
    2.13 +    int (*domctl) (struct xen_domctl *domctl);
    2.14      int (*domain_create) (struct domain *d, u32 ssidref);
    2.15 -    int (*max_vcpus) (struct domain *d);
    2.16 -    int (*destroydomain) (struct domain *d);
    2.17 -    int (*vcpuaffinity) (int cmd, struct domain *d);
    2.18 -    int (*scheduler) (struct domain *d);
    2.19      int (*getdomaininfo) (struct domain *d);
    2.20 -    int (*getvcpucontext) (struct domain *d);
    2.21 -    int (*getvcpuinfo) (struct domain *d);
    2.22 -    int (*domain_settime) (struct domain *d);
    2.23      int (*tbufcontrol) (void);
    2.24      int (*readconsole) (uint32_t clear);
    2.25      int (*sched_id) (void);
    2.26 -    int (*setdomainmaxmem) (struct domain *d);
    2.27 -    int (*setdomainhandle) (struct domain *d);
    2.28 -    int (*setdebugging) (struct domain *d);
    2.29 -    int (*irq_permission) (struct domain *d, uint8_t pirq, uint8_t access);
    2.30 -    int (*iomem_permission) (struct domain *d, unsigned long mfn, 
    2.31 -                                                                uint8_t access);
    2.32      int (*perfcontrol) (void);
    2.33  
    2.34      int (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t id2);
    2.35      int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
    2.36 -                                        struct domain *d2, struct evtchn *chn2);
    2.37 +                               struct domain *d2, struct evtchn *chn2);
    2.38      void (*evtchn_close_post) (struct evtchn *chn);
    2.39      int (*evtchn_send) (struct domain *d, struct evtchn *chn);
    2.40      int (*evtchn_status) (struct domain *d, struct evtchn *chn);
    2.41 @@ -149,69 +133,19 @@ static inline void xsm_security_domainin
    2.42      xsm_call(security_domaininfo(d, info));
    2.43  }
    2.44  
    2.45 -static inline int xsm_setvcpucontext(struct domain *d)
    2.46 +static inline int xsm_domctl(struct xen_domctl *domctl)
    2.47  {
    2.48 -    return xsm_call(setvcpucontext(d));
    2.49 -}
    2.50 -
    2.51 -static inline int xsm_pausedomain (struct domain *d)
    2.52 -{
    2.53 -    return xsm_call(pausedomain(d));
    2.54 +    return xsm_call(domctl(domctl));
    2.55  }
    2.56  
    2.57 -static inline int xsm_unpausedomain (struct domain *d)
    2.58 -{
    2.59 -    return xsm_call(unpausedomain(d));
    2.60 -}
    2.61 -
    2.62 -static inline int xsm_resumedomain (struct domain *d)
    2.63 -{
    2.64 -    return xsm_call(resumedomain(d));
    2.65 -}
    2.66 -
    2.67 -static inline int xsm_domain_create (struct domain *d, u32 ssidref)
    2.68 +static inline int xsm_domain_create(struct domain *d, u32 ssidref)
    2.69  {
    2.70      return xsm_call(domain_create(d, ssidref));
    2.71  }
    2.72  
    2.73 -static inline int xsm_max_vcpus(struct domain *d)
    2.74 -{
    2.75 -    return xsm_call(max_vcpus(d));
    2.76 -}
    2.77 -
    2.78 -static inline int xsm_destroydomain (struct domain *d)
    2.79 -{
    2.80 -    return xsm_call(destroydomain(d));
    2.81 -}
    2.82 -
    2.83 -static inline int xsm_vcpuaffinity (int cmd, struct domain *d)
    2.84 -{
    2.85 -    return xsm_call(vcpuaffinity(cmd, d));
    2.86 -}
    2.87 -
    2.88 -static inline int xsm_scheduler (struct domain *d)
    2.89 +static inline int xsm_getdomaininfo(struct domain *d)
    2.90  {
    2.91 -    return xsm_call(scheduler(d));
    2.92 -}
    2.93 -
    2.94 -static inline int xsm_getdomaininfo (struct domain *d)
    2.95 -{
    2.96 -    return xsm_call(getdomaininfo(d));
    2.97 -}
    2.98 -
    2.99 -static inline int xsm_getvcpucontext (struct domain *d)
   2.100 -{
   2.101 -    return xsm_call(getvcpucontext(d));
   2.102 -}
   2.103 -
   2.104 -static inline int xsm_getvcpuinfo (struct domain *d)
   2.105 -{
   2.106 -    return xsm_call(getvcpuinfo(d));
   2.107 -}
   2.108 -
   2.109 -static inline int xsm_domain_settime (struct domain *d)
   2.110 -{
   2.111 -    return xsm_call(domain_settime(d));
   2.112 +    return xsm_call(domain_getdomaininfo(d));
   2.113  }
   2.114  
   2.115  static inline int xsm_tbufcontrol (void)
   2.116 @@ -229,33 +163,6 @@ static inline int xsm_sched_id (void)
   2.117      return xsm_call(sched_id());
   2.118  }
   2.119  
   2.120 -static inline int xsm_setdomainmaxmem (struct domain *d)
   2.121 -{
   2.122 -    return xsm_call(setdomainmaxmem(d));
   2.123 -}
   2.124 -
   2.125 -static inline int xsm_setdomainhandle (struct domain *d)
   2.126 -{
   2.127 -    return xsm_call(setdomainhandle(d));
   2.128 -}
   2.129 -
   2.130 -static inline int xsm_setdebugging (struct domain *d)
   2.131 -{
   2.132 -    return xsm_call(setdebugging(d));
   2.133 -}
   2.134 -
   2.135 -static inline int xsm_irq_permission (struct domain *d, uint8_t pirq,
   2.136 -                                                                uint8_t access)
   2.137 -{
   2.138 -    return xsm_call(irq_permission(d, pirq, access));
   2.139 -} 
   2.140 -
   2.141 -static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn,
   2.142 -                                                                uint8_t access)
   2.143 -{
   2.144 -    return xsm_call(iomem_permission(d, mfn, access));
   2.145 -}
   2.146 -
   2.147  static inline int xsm_perfcontrol (void)
   2.148  {
   2.149      return xsm_call(perfcontrol());