[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC 1/2] Domain Groups - VMM Support



diffstat domgrps-vmm.patch

 arch/ia64/xen/xensetup.c                 |    7
 arch/powerpc/powerpc64/hypercall_table.S |    1
 arch/powerpc/setup.c                     |    7
 arch/x86/setup.c                         |    8
 arch/x86/x86_32/entry.S                  |    2
 arch/x86/x86_64/entry.S                  |    3
 common/Makefile                          |    2
 common/domain.c                          |    8
 common/domctl.c                          |   10
 common/domgrp.c                          |  315 +++++++++++++++++++++++++++++++
 common/domgrpctl.c                       |  134 +++++++++++++
 include/public/domctl.h                  |    2
 include/public/domgrpctl.h               |   86 ++++++++
 include/public/xen.h                     |    7
 include/xen/domgrp.h                     |   36 +++
 include/xen/hypercall.h                  |    5
 include/xen/sched.h                      |   26 ++

17 files changed, 657 insertions(+), 2 deletions(-)
diff -urN xen-unstable/xen/arch/ia64/xen/xensetup.c 
xen-unstable-trp-domgrps-rebase-tip/xen/arch/ia64/xen/xensetup.c
--- xen-unstable/xen/arch/ia64/xen/xensetup.c   2007-10-12 13:09:32.000000000 
-0400
+++ xen-unstable-trp-domgrps-rebase-tip/xen/arch/ia64/xen/xensetup.c    
2007-11-19 18:42:00.000000000 -0500
@@ -15,6 +15,7 @@
 #include <xen/version.h>
 #include <xen/console.h>
 #include <xen/domain.h>
+#include <xen/domgrp.h>
 #include <xen/serial.h>
 #include <xen/trace.h>
 #include <xen/keyhandler.h>
@@ -550,6 +551,10 @@
 
     expose_p2m_init();
 
+    /* initialize domain groups */
+    if (init_domain_groups())
+        panic("Error creating default groups\n");
+
     /* Create initial domain 0. */
     dom0 = domain_create(0, 0, DOM0_SSIDREF);
     if (dom0 == NULL)
@@ -559,6 +564,8 @@
         panic("Cannot allocate dom0 vcpu 0\n");
 
     dom0->is_privileged = 1;
+    if (add_dom_to_grp(dom0, 0))
+        panic("Error adding dom0 to grp0\n");
 
     /*
      * We're going to setup domain0 using the module(s) that we stashed safely
diff -urN xen-unstable/xen/arch/powerpc/powerpc64/hypercall_table.S 
xen-unstable-trp-domgrps-rebase-tip/xen/arch/powerpc/powerpc64/hypercall_table.S
--- xen-unstable/xen/arch/powerpc/powerpc64/hypercall_table.S   2007-08-06 
17:59:54.000000000 -0400
+++ 
xen-unstable-trp-domgrps-rebase-tip/xen/arch/powerpc/powerpc64/hypercall_table.S
    2007-11-19 18:42:00.000000000 -0500
@@ -41,6 +41,7 @@
         .quad 0 /* do_hvm_op */
         .quad do_sysctl             /* 35 */
         .quad do_domctl
+        .quad do_domgrpctl
         .rept NR_hypercalls-((.-__hypercall_table)/8)
         .quad do_ni_hypercall
         .endr
diff -urN xen-unstable/xen/arch/powerpc/setup.c 
xen-unstable-trp-domgrps-rebase-tip/xen/arch/powerpc/setup.c
--- xen-unstable/xen/arch/powerpc/setup.c       2007-09-13 14:40:11.000000000 
-0400
+++ xen-unstable-trp-domgrps-rebase-tip/xen/arch/powerpc/setup.c        
2007-11-19 18:42:00.000000000 -0500
@@ -32,6 +32,7 @@
 #include <xen/trace.h>
 #include <xen/mm.h>
 #include <xen/domain.h>
+#include <xen/domgrp.h>
 #include <xen/gdbstub.h>
 #include <xen/symbols.h>
 #include <xen/keyhandler.h>
@@ -365,6 +366,10 @@
     /* This cannot be called before secondary cpus are marked online.  */
     percpu_free_unused_areas();
 
+    /* initialize domain groups */
+    if (init_domain_groups())
+        panic("Error creating default groups\n");
+
     /* Create initial domain 0. */
     dom0 = domain_create(0, 0, DOM0_SSIDREF);
     if (dom0 == NULL)
@@ -375,6 +380,8 @@
     dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
 
     dom0->is_privileged = 1;
+    if (add_dom_to_grp(dom0, 0))
+        panic("Error adding dom0 to grp0\n");
 
     /* scrub_heap_pages() requires IRQs enabled, and we're post IRQ setup... */
     local_irq_enable();
diff -urN xen-unstable/xen/arch/x86/setup.c 
xen-unstable-trp-domgrps-rebase-tip/xen/arch/x86/setup.c
--- xen-unstable/xen/arch/x86/setup.c   2007-12-17 16:45:04.000000000 -0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/arch/x86/setup.c    2007-12-17 
16:44:23.000000000 -0500
@@ -3,6 +3,7 @@
 #include <xen/lib.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
+#include <xen/domgrp.h>
 #include <xen/serial.h>
 #include <xen/softirq.h>
 #include <xen/acpi.h>
@@ -955,6 +956,10 @@
     if ( opt_watchdog ) 
         watchdog_enable();
 
+    /* initialize domain groups */
+    if (init_domain_groups())
+        panic("Error creating default groups\n");
+
     /* Create initial domain 0. */
     dom0 = domain_create(0, 0, DOM0_SSIDREF);
     if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
@@ -962,6 +967,9 @@
 
     dom0->is_privileged = 1;
 
+    if (add_dom_to_grp(dom0, 0))
+        panic("Error adding dom0 to grp0\n");
+
     /* Grab the DOM0 command line. */
     cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
     if ( (cmdline != NULL) || (kextra != NULL) )
diff -urN xen-unstable/xen/arch/x86/x86_32/entry.S 
xen-unstable-trp-domgrps-rebase-tip/xen/arch/x86/x86_32/entry.S
--- xen-unstable/xen/arch/x86/x86_32/entry.S    2007-11-19 10:38:08.000000000 
-0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/arch/x86/x86_32/entry.S     
2007-11-19 18:42:00.000000000 -0500
@@ -682,6 +682,7 @@
         .long do_sysctl             /* 35 */
         .long do_domctl
         .long do_kexec_op
+        .long do_domgrpctl
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
@@ -725,6 +726,7 @@
         .byte 1 /* do_sysctl            */  /* 35 */
         .byte 1 /* do_domctl            */
         .byte 2 /* do_kexec_op          */
+        .byte 1 /* do_domgrpctl         */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -urN xen-unstable/xen/arch/x86/x86_64/entry.S 
xen-unstable-trp-domgrps-rebase-tip/xen/arch/x86/x86_64/entry.S
--- xen-unstable/xen/arch/x86/x86_64/entry.S    2007-11-19 10:38:08.000000000 
-0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/arch/x86/x86_64/entry.S     
2007-11-19 18:43:06.000000000 -0500
@@ -672,6 +672,7 @@
         .quad do_sysctl             /* 35 */
         .quad do_domctl
         .quad do_kexec_op
+        .quad do_domgrpctl
         .rept NR_hypercalls-((.-hypercall_table)/8)
         .quad do_ni_hypercall
         .endr
@@ -715,7 +716,7 @@
         .byte 1 /* do_sysctl            */  /* 35 */
         .byte 1 /* do_domctl            */
         .byte 2 /* do_kexec             */
-        .byte 1 /* do_xsm_op            */
+        .byte 1 /* do_domgrpctl         */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -urN xen-unstable/xen/common/domain.c 
xen-unstable-trp-domgrps-rebase-tip/xen/common/domain.c
--- xen-unstable/xen/common/domain.c    2007-11-19 10:38:08.000000000 -0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/common/domain.c     2007-11-19 
18:42:00.000000000 -0500
@@ -11,6 +11,7 @@
 #include <xen/errno.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
+#include <xen/domgrp.h>
 #include <xen/mm.h>
 #include <xen/event.h>
 #include <xen/time.h>
@@ -57,6 +58,7 @@
 
     memset(d, 0, sizeof(*d));
     d->domain_id = domid;
+    d->group_id = INVAL_GROUP_ID;
 
     if ( xsm_alloc_security_domain(d) != 0 )
     {
@@ -241,6 +243,8 @@
         rcu_assign_pointer(*pd, d);
         rcu_assign_pointer(domain_hash[DOMAIN_HASH(domid)], d);
         spin_unlock(&domlist_update_lock);
+
+        add_dom_to_grp(d, NULL_GROUP_ID);
     }
 
     return d;
@@ -388,6 +392,8 @@
 {
     struct vcpu *v;
 
+    del_dom_from_grp(d);
+
     if ( d->domain_id == 0 )
         dom0_shutdown(reason);
 
@@ -522,6 +528,8 @@
     if ( _atomic_read(old) != 0 )
         return;
 
+    del_dom_from_grp(d);
+
     /* Delete from task list and task hashtable. */
     spin_lock(&domlist_update_lock);
     pd = &domain_list;
diff -urN xen-unstable/xen/common/domctl.c 
xen-unstable-trp-domgrps-rebase-tip/xen/common/domctl.c
--- xen-unstable/xen/common/domctl.c    2007-12-17 16:45:04.000000000 -0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/common/domctl.c     2007-12-17 
16:44:23.000000000 -0500
@@ -12,6 +12,7 @@
 #include <xen/mm.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
+#include <xen/domgrp.h>
 #include <xen/event.h>
 #include <xen/domain_page.h>
 #include <xen/trace.h>
@@ -94,8 +95,10 @@
     u64 cpu_time = 0;
     int flags = XEN_DOMINF_blocked;
     struct vcpu_runstate_info runstate;
-    
+    struct domain_group *grp;
+
     info->domain = d->domain_id;
+    info->group = d->group_id;
     info->nr_online_vcpus = 0;
     
     /* 
@@ -136,6 +139,9 @@
     info->shared_info_frame = mfn_to_gmfn(d, __pa(d->shared_info)>>PAGE_SHIFT);
 
     memcpy(info->handle, d->handle, sizeof(xen_domain_handle_t));
+    grp = find_grp_by_id(info->group);
+    if (grp)
+        memcpy(info->dg_handle, grp->handle, 
sizeof(xen_domain_group_handle_t));
 }
 
 static unsigned int default_vcpu0_location(void)
@@ -256,6 +262,7 @@
     {
         struct domain *d = rcu_lock_domain_by_id(op->domain);
         ret = -ESRCH;
+
         if ( d != NULL )
         {
             ret = xsm_pausedomain(d);
@@ -426,6 +433,7 @@
     {
         struct domain *d = rcu_lock_domain_by_id(op->domain);
         ret = -ESRCH;
+
         if ( d != NULL )
         {
             ret = xsm_destroydomain(d) ? : domain_kill(d);
diff -urN xen-unstable/xen/common/domgrp.c 
xen-unstable-trp-domgrps-rebase-tip/xen/common/domgrp.c
--- xen-unstable/xen/common/domgrp.c    1969-12-31 19:00:00.000000000 -0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/common/domgrp.c     2007-11-26 
16:46:46.000000000 -0500
@@ -0,0 +1,315 @@
+/******************************************************************************
+ * domgrp.c
+ *
+ * Generic domain group-handling functions.
+ *
+ * Author: Chris Bookholt (hap10@xxxxxxxxxxxxxx)
+ */
+
+#include <xen/sched.h>
+#include <xen/list.h>
+#include <xen/xmalloc.h>
+#include <public/domgrpctl.h>
+
+DEFINE_SPINLOCK(domgrplist_update_lock);
+DEFINE_RCU_READ_LOCK(domgrplist_read_lock);
+
+struct list_head domgrplist;
+
+#define SERIALIZE_LINKED_LIST(op_name, list_name)              \
+    rcu_read_lock(&grp->op_name##_read_lock);                  \
+    memset(&info->op_name, 0, sizeof(domid_t)*MAX_GROUP_SIZE); \
+    if (!list_empty(&grp->op_name)) {                          \
+        i = 0;                                                 \
+        list_for_each_entry(dom, &grp->op_name, list_name) {   \
+            info->op_name[i] = dom->domain_id;                 \
+                   i++;                                                \
+       }                                                       \
+    } else                                                     \
+       info->op_name[i] = NULL_GROUP_ID;                       \
+    rcu_read_unlock(&grp->op_name##_read_lock);
+
+void get_grp_info(struct domain_group *grp, xen_domgrpctl_getgrpinfo_t * info)
+{
+       struct domain *dom;
+       uint16_t i = 0;
+
+       info->dgid = grp->group_id;
+       info->size = grp->size;
+
+       SERIALIZE_LINKED_LIST(member_list, member);
+
+       memcpy(info->handle, grp->handle, sizeof(xen_domain_group_handle_t));
+}
+
+struct domain_group *alloc_domain_group(void)
+{
+       struct domain_group *grp = NULL;
+
+       if ((grp = xmalloc(struct domain_group)) != NULL)
+                memset(grp, 0, sizeof(*grp));
+
+       return grp;
+}
+
+struct domain_group *find_grp_by_id(dgid_t dgid)
+{
+       struct domain_group *grp;
+
+       rcu_read_lock(&domgrplist_read_lock);
+       list_for_each_entry(grp, &domgrplist, groups) {
+           BUG_ON(grp == NULL);
+           if (grp->group_id == dgid) 
+               goto out;
+       }
+       grp = NULL;
+      out:
+       rcu_read_unlock(&domgrplist_read_lock);
+       return grp;
+}
+
+uint16_t get_new_group_id(void)
+{
+       static DEFINE_SPINLOCK(domgrpcnt_lock);
+       static dgid_t group_counter = 1;
+       dgid_t ret;
+       
+       if (group_counter < NULL_GROUP_ID - 1) {
+               spin_lock(&domgrpcnt_lock);
+               ret = group_counter++;
+               spin_unlock(&domgrpcnt_lock);
+       } else
+               ret = NULL_GROUP_ID;
+       return ret;
+}
+
+struct domain_group *domain_group_create(dgid_t dgid)
+{
+       struct domain_group *grp = NULL, *tail;
+
+       grp = alloc_domain_group();
+       if (!grp)
+               goto out;
+
+       grp->group_id = dgid;
+       grp->size = 0;
+       if (dgid == 0)
+               memset(grp->handle, 0, sizeof(xen_domain_group_handle_t));
+       else if (dgid == NULL_GROUP_ID)
+               memset(grp->handle, 0xFF, sizeof(xen_domain_group_handle_t));
+
+       /* init group's lists */
+       INIT_LIST_HEAD(&grp->member_list);
+
+       /* init group's locks */
+       spin_lock_init(&grp->grp_big_lock);
+       spin_lock_init(&grp->member_list_update_lock);
+
+       /* add new group to domgrplist *
+        * TODO: This is a candidate for optimization. Could 
+        * be optimized by maintaining a ptr to the tail, but 
+        * list size is small, so search isn't expensive */
+       if (dgid != 0 && dgid != NULL_GROUP_ID) {
+               tail = find_grp_by_id(NULL_GROUP_ID);
+               spin_lock(&domgrplist_update_lock);
+               list_add_tail(&grp->groups, &tail->groups);
+               spin_unlock(&domgrplist_update_lock);
+       } else {
+               spin_lock(&domgrplist_update_lock);
+               list_add_tail(&grp->groups, &domgrplist);
+               spin_unlock(&domgrplist_update_lock);
+       }
+
+      out:
+       return grp;
+}
+
+int dom_in_member_list(domid_t domid, struct domain_group *grp)
+{
+       struct domain *dom;
+       int ret = 0;
+
+       if (grp == NULL) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       rcu_read_lock(&grp->member_list_read_lock);
+       list_for_each_entry(dom, &grp->member_list, member) {
+               if (dom->domain_id == domid) {
+                       ret = 1;
+                       break;
+               }
+       }
+       rcu_read_unlock(&grp->member_list_read_lock);
+      out:
+       return ret;
+}
+
+#define RM_DOM_FROM_LIST(list_name, entry)     \
+    spin_lock(&grp->list_name##_update_lock);  \
+    if (!list_empty(&grp->list_name))          \
+        list_del(&dom->entry);                 \
+    spin_unlock(&grp->list_name##_update_lock);
+
+void del_dom_from_grp(struct domain *dom)
+{
+       struct domain_group *grp;
+
+       grp = find_grp_by_id(dom->group_id);
+
+       if (grp == NULL)
+               goto out;
+
+       if (dom_in_member_list(dom->domain_id, grp) <= 0)
+               goto out;
+
+       RM_DOM_FROM_LIST(member_list, member);
+       dom->group_id = INVAL_GROUP_ID;
+       grp->size--;
+       
+      out:
+       return;
+}
+
+int add_dom_to_grp(struct domain *dom, dgid_t dgid)
+{
+       struct domain_group *grp = NULL;
+       int ret = 0;
+
+       grp = find_grp_by_id(dgid);
+       if (grp == NULL) {
+               ret = -ESRCH;
+               goto out;
+       } 
+
+       if (grp->size >= MAX_GROUP_SIZE) {
+               ret = -EPERM;
+               goto out;
+       } 
+
+       /* skip it if dom is already a member */
+       if (dom_in_member_list(dom->domain_id, grp))
+               goto out;
+       
+       /* remove dom from old group */
+       if (dom->group_id != INVAL_GROUP_ID)
+               del_dom_from_grp(dom);
+
+       /* add dom to end of new group list */
+       spin_lock(&grp->member_list_update_lock);
+       list_add_tail(&dom->member, &grp->member_list);
+       spin_unlock(&grp->member_list_update_lock);
+
+       dom->group_id = dgid;
+       dom->grp_big_lock = &grp->grp_big_lock;
+
+       grp->size++;
+      out:
+       return ret;
+}
+
+int pause_grp(dgid_t dgid)
+{
+       int ret = 0;
+       struct domain *member;
+       struct domain_group *grp;
+
+       if (dgid == 0) {
+               ret = -EPERM;
+               goto out;
+       }
+
+       grp = find_grp_by_id(dgid);
+
+       if (grp == NULL) {
+               ret = -ESRCH;
+               goto out;
+       }
+
+       spin_lock_recursive(&grp->grp_big_lock);
+       rcu_read_lock(&grp->member_list_read_lock);
+       /* could ignore interupts during this loop to increase atomicity */
+       list_for_each_entry(member, &grp->member_list, member) {
+               if (member != current->domain && member->domain_id != 0)
+                       domain_pause_by_systemcontroller(member);
+       }
+       rcu_read_unlock(&grp->member_list_read_lock);
+       spin_unlock_recursive(&grp->grp_big_lock);
+      out:
+       return ret;
+}
+
+int unpause_grp(dgid_t dgid)
+{
+       int ret = 0;
+       struct domain *member;
+       struct domain_group *grp;
+
+       if (dgid == 0) {
+               ret = -EPERM;
+               goto out;
+       }
+
+       grp = find_grp_by_id(dgid);
+
+       if (grp == NULL) {
+               ret = -ESRCH;
+               goto out;
+       }
+
+       spin_lock_recursive(&grp->grp_big_lock);
+       rcu_read_lock(&grp->member_list_read_lock);
+       /* could ignore interupts during this loop to increase atomicity */
+       list_for_each_entry(member, &grp->member_list, member) {
+               if (member != current->domain && member->domain_id != 0)
+                       domain_unpause_by_systemcontroller(member);
+       }
+       rcu_read_unlock(&grp->member_list_read_lock);
+       spin_unlock_recursive(&grp->grp_big_lock);
+      out:
+       return ret;
+}
+
+int domain_group_destroy(dgid_t dgid)
+{
+       int ret = 0;
+       struct domain_group *grp;
+
+       grp = find_grp_by_id(dgid);
+       if (grp == NULL) {
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (grp->size != 0) {
+               ret = -EPERM;
+               printk(KERN_INFO "refusing to destroy non-emtpry group %d\n", 
grp->group_id);
+               goto out;
+       }
+
+       spin_lock(&domgrplist_update_lock);
+       list_del(&grp->groups);
+       spin_unlock(&domgrplist_update_lock);
+
+       xfree(grp);
+      out:
+       return ret;
+}
+
+int init_domain_groups(void)
+{
+       struct domain_group *grp0, *nullgrp;
+       int ret = 0;
+       INIT_LIST_HEAD(&domgrplist);
+
+       /* order matters for creation of default groups: 
+        * create default groups in order of ascending dgid so they 
+        * are added to the group list in the expected order */
+       grp0 = domain_group_create(0);
+       nullgrp = domain_group_create(NULL_GROUP_ID);
+
+       if (!grp0 || !nullgrp)
+           ret = -ENOMEM;
+       return ret;
+}
diff -urN xen-unstable/xen/common/domgrpctl.c 
xen-unstable-trp-domgrps-rebase-tip/xen/common/domgrpctl.c
--- xen-unstable/xen/common/domgrpctl.c 1969-12-31 19:00:00.000000000 -0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/common/domgrpctl.c  2007-11-19 
18:42:00.000000000 -0500
@@ -0,0 +1,134 @@
+/******************************************************************************
+ * domgrpctl.c
+ *
+ * Domain group management operations. For use by node control stack.
+ *
+ * Author: Chris Bookholt (hap10@xxxxxxxxxxxxxx)
+ */
+
+#include <xen/sched.h>
+#include <xen/domgrp.h>
+#include <xen/guest_access.h>
+#include <public/domgrpctl.h>
+#include <asm/current.h>
+
+long do_domgrpctl(XEN_GUEST_HANDLE(xen_domgrpctl_t) u_domgrpctl)
+{
+       long ret = 0;
+       struct xen_domgrpctl curop, *op = &curop;
+       static DEFINE_SPINLOCK(domgrpctl_lock);
+       struct domain_group *grp;
+       dgid_t dgid;
+
+       if (!IS_PRIV(current->domain)) {
+               ret = -EPERM;
+               goto out;
+       }
+
+       if (copy_from_guest(op, u_domgrpctl, 1)) {
+               ret = -EFAULT;
+               goto out;
+       }
+
+       if (op->interface_version != XEN_DOMGRPCTL_INTERFACE_VERSION) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       spin_lock(&domgrpctl_lock);
+
+       switch (op->cmd) {
+
+       case XEN_DOMGRPCTL_getgrpinfo:
+               {
+                       rcu_read_lock(&domgrplist_read_lock);
+                       ret = -ESRCH;
+                       dgid = op->u.get_grp_info.dgid;
+
+                       list_for_each_entry(grp, &domgrplist, groups) {
+                               if (grp->group_id >= dgid) {
+                                       ret = 0;
+                                       break;
+                               }
+                       }
+                       if (ret)
+                               goto getgrpinfo_out;
+
+                       get_grp_info(grp, &op->u.get_grp_info);
+
+                       if (copy_to_guest(u_domgrpctl, op, 1))
+                               ret = -EFAULT;
+
+                     getgrpinfo_out:
+                       rcu_read_unlock(&domgrplist_read_lock);
+                       break;
+               }
+
+       case XEN_DOMGRPCTL_creategrp:
+               {
+                       dgid = get_new_group_id();
+                       if (dgid == NULL_GROUP_ID) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       grp = domain_group_create(dgid);
+                       if (grp == NULL) {
+                               ret = -ENOMEM;
+                               break;
+                       }
+
+                       memcpy(grp->handle, op->u.create_grp.handle,
+                              sizeof(xen_domain_group_handle_t));
+
+                       op->u.create_grp.dgid = grp->group_id;
+                       if (copy_to_guest(u_domgrpctl, op, 1))
+                               ret = -EFAULT;
+
+                       break;
+               }
+
+       case XEN_DOMGRPCTL_joingrp:
+               {
+                       domid_t domid;
+                       struct domain *dom;
+
+                       domid = op->u.join_grp.domid;
+                       dgid = op->u.join_grp.dgid;
+
+                       dom = get_domain_by_id(domid);
+                       if (dom == NULL)
+                               ret = -ESRCH;
+                       else
+                               ret = add_dom_to_grp(dom, dgid);
+                       put_domain(dom);
+
+                       break;
+               }
+
+       case XEN_DOMGRPCTL_pausegrp:
+               {
+                       ret = pause_grp(op->u.pause_grp.dgid);
+                       break;
+               }
+
+       case XEN_DOMGRPCTL_unpausegrp:
+               {
+                       ret = unpause_grp(op->u.unpause_grp.dgid);
+                       break;
+               }
+
+       case XEN_DOMGRPCTL_destroygrp:
+               {
+                       ret = domain_group_destroy(op->u.destroy_grp.dgid);
+                       break;
+               }
+
+       default:
+               ret = -EINVAL;
+       }
+
+       spin_unlock(&domgrpctl_lock);
+      out:
+       return ret;
+}
diff -urN xen-unstable/xen/common/Makefile 
xen-unstable-trp-domgrps-rebase-tip/xen/common/Makefile
--- xen-unstable/xen/common/Makefile    2007-11-19 10:38:08.000000000 -0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/common/Makefile     2007-11-19 
18:42:00.000000000 -0500
@@ -1,6 +1,8 @@
 obj-y += bitmap.o
 obj-y += domctl.o
+obj-y += domgrpctl.o
 obj-y += domain.o
+obj-y += domgrp.o
 obj-y += event_channel.o
 obj-y += grant_table.o
 obj-y += kernel.o
diff -urN xen-unstable/xen/include/public/domctl.h 
xen-unstable-trp-domgrps-rebase-tip/xen/include/public/domctl.h
--- xen-unstable/xen/include/public/domctl.h    2007-12-17 16:45:05.000000000 
-0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/include/public/domctl.h     
2007-12-17 16:44:23.000000000 -0500
@@ -67,6 +67,7 @@
 struct xen_domctl_getdomaininfo {
     /* OUT variables. */
     domid_t  domain;              /* Also echoed in domctl.domain */
+    dgid_t   group;
  /* Domain is scheduled to die. */
 #define _XEN_DOMINF_dying     0
 #define XEN_DOMINF_dying      (1U<<_XEN_DOMINF_dying)
@@ -103,6 +104,7 @@
     uint32_t max_vcpu_id;        /* Maximum VCPUID in use by this domain. */
     uint32_t ssidref;
     xen_domain_handle_t handle;
+    xen_domain_group_handle_t dg_handle;
 };
 typedef struct xen_domctl_getdomaininfo xen_domctl_getdomaininfo_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t);
diff -urN xen-unstable/xen/include/public/domgrpctl.h 
xen-unstable-trp-domgrps-rebase-tip/xen/include/public/domgrpctl.h
--- xen-unstable/xen/include/public/domgrpctl.h 1969-12-31 19:00:00.000000000 
-0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/include/public/domgrpctl.h  
2007-11-19 18:42:00.000000000 -0500
@@ -0,0 +1,86 @@
+/******************************************************************************
+ * domgrpctl.h
+ *
+ * Domain group management operations. For use by node control stack.
+ *
+ * Author: Chris Bookholt (hap10@xxxxxxxxxxxxxx)
+ */
+
+#ifndef __XEN_PUBLIC_DOMGRPCTL_H__
+#define __XEN_PUBLIC_DOMGRPCTL_H__
+
+#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
+#error "domgrpctl operations are intended for use by node control tools only"
+#endif
+
+#include "xen.h"
+
+#define XEN_DOMGRPCTL_INTERFACE_VERSION 0x00000001
+
+#define MAX_GROUP_SIZE                 24
+#define NULL_GROUP_ID                  (0x7FFFU)
+#define INVAL_GROUP_ID                 (0xFFFFU)
+
+#define XEN_DOMGRPCTL_creategrp                1
+struct xen_domgrpctl_creategrp {
+       dgid_t dgid;
+       xen_domain_group_handle_t handle;
+};
+typedef struct xen_domgrpctl_creategrp xen_domgrpctl_creategrp_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domgrpctl_creategrp_t);
+
+#define XEN_DOMGRPCTL_joingrp          2
+struct xen_domgrpctl_joingrp {
+       domid_t domid;
+       dgid_t dgid;
+};
+typedef struct xen_domgrpctl_joingrp xen_domgrpctl_joingrp_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domgrpctl_joingrp_t);
+
+#define XEN_DOMGRPCTL_pausegrp         3
+struct xen_domgrpctl_pausegrp {
+       dgid_t dgid;
+};
+typedef struct xen_domgrpctl_pausegrp xen_domgrpctl_pausegrp_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domgrpctl_pausegrp_t);
+
+#define XEN_DOMGRPCTL_unpausegrp       4
+struct xen_domgrpctl_unpausegrp {
+       dgid_t dgid;
+};
+typedef struct xen_domgrpctl_unpausegrp xen_domgrpctl_unpausegrp_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domgrpctl_unpausegrp_t);
+
+#define XEN_DOMGRPCTL_destroygrp       5
+struct xen_domgrpctl_destroygrp {
+       dgid_t dgid;
+};
+typedef struct xen_domgrpctl_destroygrp xen_domgrpctl_destroygrp_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domgrpctl_destroygrp_t);
+
+#define XEN_DOMGRPCTL_getgrpinfo       6
+struct xen_domgrpctl_getgrpinfo {
+       dgid_t dgid;
+       uint16_t size;
+       domid_t member_list[MAX_GROUP_SIZE];
+       xen_domain_group_handle_t handle;
+};
+typedef struct xen_domgrpctl_getgrpinfo xen_domgrpctl_getgrpinfo_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domgrpctl_getgrpinfo_t);
+
+struct xen_domgrpctl {
+       uint32_t cmd;
+       uint32_t interface_version;
+       union {
+               struct xen_domgrpctl_creategrp create_grp;
+               struct xen_domgrpctl_joingrp join_grp;
+               struct xen_domgrpctl_pausegrp pause_grp;
+               struct xen_domgrpctl_unpausegrp unpause_grp;
+               struct xen_domgrpctl_destroygrp destroy_grp;
+               struct xen_domgrpctl_getgrpinfo get_grp_info;
+       } u;
+};
+typedef struct xen_domgrpctl xen_domgrpctl_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domgrpctl_t);
+
+#endif                         /* __XEN_PUBLIC_DOMGRPCTL_H__ */
diff -urN xen-unstable/xen/include/public/xen.h 
xen-unstable-trp-domgrps-rebase-tip/xen/include/public/xen.h
--- xen-unstable/xen/include/public/xen.h       2007-10-22 15:12:58.000000000 
-0400
+++ xen-unstable-trp-domgrps-rebase-tip/xen/include/public/xen.h        
2007-11-19 18:42:00.000000000 -0500
@@ -80,6 +80,7 @@
 #define __HYPERVISOR_sysctl               35
 #define __HYPERVISOR_domctl               36
 #define __HYPERVISOR_kexec_op             37
+#define __HYPERVISOR_domgrpctl            38
 
 /* Architecture-specific hypercall definitions. */
 #define __HYPERVISOR_arch_0               48
@@ -297,6 +298,8 @@
 
 typedef uint16_t domid_t;
 
+typedef uint16_t dgid_t;
+
 /* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */
 #define DOMID_FIRST_RESERVED (0x7FF0U)
 
@@ -520,7 +523,9 @@
     unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames.       */
     unsigned long mfn_list;     /* VIRTUAL address of page-frame list.    */
     unsigned long mod_start;    /* VIRTUAL address of pre-loaded module.  */
+                                /* or VIRTUAL address of module_t array   */
     unsigned long mod_len;      /* Size (bytes) of pre-loaded module.     */
+                                /* or length of module_t array.           */
     int8_t cmd_line[MAX_GUEST_CMDLINE];
 };
 typedef struct start_info start_info_t;
@@ -579,6 +584,8 @@
 
 typedef uint8_t xen_domain_handle_t[16];
 
+typedef uint8_t xen_domain_group_handle_t[16];
+
 /* Turn a plain number into a C unsigned long constant. */
 #define __mk_unsigned_long(x) x ## UL
 #define mk_unsigned_long(x) __mk_unsigned_long(x)
diff -urN xen-unstable/xen/include/xen/domgrp.h 
xen-unstable-trp-domgrps-rebase-tip/xen/include/xen/domgrp.h
--- xen-unstable/xen/include/xen/domgrp.h       1969-12-31 19:00:00.000000000 
-0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/include/xen/domgrp.h        
2007-11-19 18:42:00.000000000 -0500
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * domgrp.h
+ *
+ * Generic domain group-handling functions.
+ *
+ * Author: Chris Bookholt (hap10@xxxxxxxxxxxxxx)
+ */
+
+#ifndef __XEN_DOM_GROUP_H__
+#define __XEN_DOM_GROUP_H__
+
+#include <public/domgrpctl.h>
+
+extern struct list_head domgrplist;
+
+void get_grp_info(struct domain_group *grp, xen_domgrpctl_getgrpinfo_t * info);
+
+struct domain_group *find_grp_by_id(dgid_t dgid);
+
+uint16_t get_new_group_id(void);
+
+struct domain_group *domain_group_create(dgid_t dgid);
+
+int del_dom_from_grp(struct domain *old_dom);
+
+int add_dom_to_grp(struct domain *dom, dgid_t dgid);
+
+int pause_grp(dgid_t dgid);
+
+int unpause_grp(dgid_t dgid);
+
+int domain_group_destroy(dgid_t dgid);
+
+int init_domain_groups(void);
+
+#endif                         /* __XEN_DOM_GROUP_H__ */
diff -urN xen-unstable/xen/include/xen/hypercall.h 
xen-unstable-trp-domgrps-rebase-tip/xen/include/xen/hypercall.h
--- xen-unstable/xen/include/xen/hypercall.h    2007-09-13 14:40:12.000000000 
-0400
+++ xen-unstable-trp-domgrps-rebase-tip/xen/include/xen/hypercall.h     
2007-11-19 18:42:00.000000000 -0500
@@ -10,6 +10,7 @@
 #include <xen/time.h>
 #include <public/xen.h>
 #include <public/domctl.h>
+#include <public/domgrpctl.h>
 #include <public/sysctl.h>
 #include <public/platform.h>
 #include <public/event_channel.h>
@@ -35,6 +36,10 @@
     XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
 
 extern long
+do_domgrpctl(
+    XEN_GUEST_HANDLE(xen_domgrpctl_t) u_domgrpctl);
+
+extern long
 do_sysctl(
     XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
 
diff -urN xen-unstable/xen/include/xen/sched.h 
xen-unstable-trp-domgrps-rebase-tip/xen/include/xen/sched.h
--- xen-unstable/xen/include/xen/sched.h        2007-11-19 10:38:08.000000000 
-0500
+++ xen-unstable-trp-domgrps-rebase-tip/xen/include/xen/sched.h 2007-11-19 
18:47:23.000000000 -0500
@@ -9,6 +9,7 @@
 #include <xen/shared.h>
 #include <public/xen.h>
 #include <public/domctl.h>
+#include <public/domgrpctl.h>
 #include <public/vcpu.h>
 #include <public/xsm/acm.h>
 #include <xen/time.h>
@@ -19,6 +20,7 @@
 #include <xen/xenoprof.h>
 #include <xen/rcupdate.h>
 #include <xen/irq.h>
+#include <xen/init.h>
 
 #ifdef CONFIG_COMPAT
 #include <compat/vcpu.h>
@@ -27,6 +29,9 @@
 
 extern unsigned long volatile jiffies;
 
+extern spinlock_t domgrplist_update_lock;
+extern rcu_read_lock_t domgrplist_read_lock;
+
 /* A global pointer to the initial domain (DOM0). */
 extern struct domain *dom0;
 
@@ -145,9 +150,13 @@
 {
     domid_t          domain_id;
 
+    dgid_t           group_id;        /* TODO: replace struct group ptr */
+    struct list_head member;
+
     shared_info_t   *shared_info;     /* shared data area */
 
     spinlock_t       big_lock;
+    spinlock_t      *grp_big_lock;
 
     spinlock_t       page_alloc_lock; /* protects all the following fields  */
     struct list_head page_list;       /* linked list, of size tot_pages     */
@@ -233,6 +242,23 @@
     spinlock_t hypercall_deadlock_mutex;
 };
 
+struct domain_group
+{
+    dgid_t                       group_id;
+    uint16_t                     size;
+
+    struct list_head             groups;
+
+    struct list_head             member_list;
+
+    spinlock_t                   grp_big_lock;
+
+    spinlock_t                   member_list_update_lock;
+    rcu_read_lock_t              member_list_read_lock;
+
+    xen_domain_group_handle_t    handle;
+};
+
 struct domain_setup_info
 {
     /* Initialised by caller. */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.