WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [RFC 1/2] Domain Groups - VMM Support
From: Chris <hap10@xxxxxxxxxxxxxx>
Date: Tue, 18 Dec 2007 11:02:55 -0500
Delivery-date: Tue, 18 Dec 2007 08:02:45 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.9 (Macintosh/20071031)
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
<Prev in Thread] Current Thread [Next in Thread>