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

Re: [Xen-devel] Proposal for init/kexec/hotplug format for Xen



On Sun, 2005-02-27 at 09:25 -0600, Anthony Liguori wrote:
> Keir Fraser wrote:
> > I like the idea of bringing out device discovery, bringup, teardown, 
> > recovery all into its own driver or subsystem -- it seems the obvious 
> > way to go. But I think the 'device tree' should be in the 
> > to-be-designed persistent store, and we publish an interface to allow 
> > guests to peek/poke that store.
> 
> I think publishing domain-information in an OF-like tree would be great.

I'm not convinced of the persistent store idea, at least for this.  I
think it's simpler to have it dropped into memory at boot (just like the
initrd image), and then later messages are sent which update it (ie.
hotlplug) which have a similar form.

The former is implemented, but breaks when I actually test it (you can
see that code #ifdef'ed out, debugging now).  I added simple routines so
that you can build a device tree and pass it to the domain builder.

Included below for your reading pleasure,
Rusty.
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c 
xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c
--- xen-unstable/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c   
2005-02-26 01:20:55.000000000 +1100
+++ xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c   
2005-02-28 09:27:36.000000000 +1100
@@ -1142,6 +1142,11 @@ static unsigned long __init setup_memory
        }
 #endif
 
+       /* We're going to keep pointers into this */
+       if (xen_start_info.devtree_len)
+               reserve_bootmem(xen_start_info.devtree_start,
+                               xen_start_info.devtree_len);
+
        phys_to_machine_mapping = (unsigned int *)xen_start_info.mfn_list;
 
        return max_low_pfn;
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c 
xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c
--- xen-unstable/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c      
1970-01-01 10:00:00.000000000 +1000
+++ xen-unstable-devtree/linux-2.6.10-xen-sparse/arch/xen/kernel/devtree.c      
2005-02-28 10:08:44.000000000 +1100
@@ -0,0 +1,148 @@
+/******************************************************************************
+ * Simple device tree unbundling and query interface.
+ *
+ * Copyright (C) 2005 Rusty Russell IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <asm-xen/devtree.h>
+
+LIST_HEAD(devtree_root);
+spinlock_t devtree_lock;
+
+/* Skip separator, return next path element. */
+static inline const char *path_element(const char *path, unsigned int *len)
+{
+       path += strspn(path, "/");
+       *len = strcspn(path, "/");
+       return path;
+}
+
+struct xen_devtree *devtree_get(const char *path)
+{
+       struct xen_devtree *i;
+       struct list_head *list = &devtree_root;
+       unsigned int pathlen;
+
+       assert_spin_locked(&devtree_lock);
+
+       path = path_element(path, &pathlen);
+next_level:
+       list_for_each_entry(i, list, siblings) {
+               /* Doesn't match?  Keep looking through names. */
+               if (strlen(i->name) != pathlen
+                   || memcmp(path, i->name, pathlen) != 0)
+                       continue;
+
+               path = path_element(path, &pathlen);
+               /* Finished iteration?  This is the element they want. */
+               if (pathlen == 0)
+                       return i;
+
+               list = &i->children;
+               goto next_level;
+       }
+       return NULL;
+}
+
+/* This is recursive, but used for debugging simple trees, so an OK hack. */
+static void dump_tree(struct list_head *list, int indent)
+{
+       struct xen_devtree *i;
+
+       list_for_each_entry(i, list, siblings) {
+               unsigned int j;
+               for (j = 0; j < indent; j++)
+                       printk(" ");
+               printk("- %s (%u)\n", i->name, i->length);
+               dump_tree(&i->children, indent+2);
+       }
+}
+
+#define DEVTREE_VERSION 1
+
+/* Initial routine to populate tree from flattened structure. */
+static void __init devtree_init(void)
+{
+       struct xen_devtree_header *head;
+       const struct xen_devtree_node *nodes;
+       const char *names;
+       void *data;
+       struct xen_devtree **dev_array;
+       unsigned int i, length;
+
+       BUG_ON(!list_empty(&devtree_root));
+
+       head = (void *)xen_start_info.devtree_start;
+       length = xen_start_info.devtree_len;
+
+       /* No device tree at all currently for domain 0. */
+       if (length == 0)
+               return;
+
+       if (head->last_comp_version > DEVTREE_VERSION)
+               panic("Incompatible Xen device tree version %i (%i)\n",
+                     head->version, head->last_comp_version);
+
+       /* Simple sanity checks. */
+       if (head->root_offset >= length
+           || head->root_offset + head->num_nodes * sizeof(*nodes) >= length
+           || head->name_offset >= length
+           || head->data_offset >= length)
+               panic("Xen device tree v%i %u/%u/%u/%u overflows %lu\n",
+                     head->version, head->root_offset, head->num_nodes,
+                     head->name_offset, head->data_offset,
+                     length);
+
+       nodes = (void *)head + head->root_offset;
+       names = (void *)head + head->name_offset;
+       data = (void *)head + head->data_offset;
+
+       /* Set up temporary node number to node mapping. */
+       dev_array = kmalloc(sizeof(*dev_array) * head->num_nodes, GFP_KERNEL);
+
+       /* Element 0 is simple a root node marker; ignore it. */
+       for (i = 1; i < head->num_nodes; i++) {
+               BUG_ON(nodes[i].parent >= i);
+
+               dev_array[i] = kmalloc(sizeof(*dev_array[i]), GFP_KERNEL);
+               dev_array[i]->name = names + nodes[i].name;
+               dev_array[i]->length = nodes[i].len;
+               dev_array[i]->data = data + nodes[i].data;
+               INIT_LIST_HEAD(&dev_array[i]->children);
+               /* Locking here is simple paranoia. */
+               spin_lock_irq(&devtree_lock);
+               if (nodes[i].parent == 0)
+                       list_add(&dev_array[i]->siblings, &devtree_root);
+               else
+                       list_add(&dev_array[i]->siblings,
+                                &dev_array[nodes[i].parent]->children);
+               spin_unlock_irq(&devtree_lock);
+       }
+       kfree(dev_array);
+
+       dump_tree(&devtree_root, 0);
+}
+
+core_initcall(devtree_init);
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h 
xen-unstable-devtree/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h
--- xen-unstable/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h      
1970-01-01 10:00:00.000000000 +1000
+++ xen-unstable-devtree/linux-2.6.10-xen-sparse/include/asm-xen/devtree.h      
2005-02-28 10:05:46.000000000 +1100
@@ -0,0 +1,27 @@
+#ifndef __ASM_DEVTREE_H__
+#define __ASM_DEVTREE_H__
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+struct xen_devtree
+{
+       /* Siblings list */
+       struct list_head siblings;
+
+       /* Children */
+       struct list_head children;
+
+       const char *name;
+       u32 length;
+       void *data;
+};
+
+/* Root of the tree, and the big lock to protect all allocations. */
+extern struct list_head devtree_root;
+extern spinlock_t devtree_lock;
+
+/* Must be holding devtree_lock.  Returns NULL if no such entry. */
+struct xen_devtree *devtree_get(const char *path);
+#endif /* __ASM_DEVTREE_H__ */
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/Makefile xen-unstable-devtree/tools/libxc/Makefile
--- xen-unstable/tools/libxc/Makefile   2005-02-26 01:20:58.000000000 +1100
+++ xen-unstable-devtree/tools/libxc/Makefile   2005-02-28 04:59:05.000000000 
+1100
@@ -29,6 +29,7 @@ SRCS     += xc_misc.c
 SRCS     += xc_physdev.c
 SRCS     += xc_private.c
 SRCS     += xc_rrobin.c
+SRCS     += xc_devtree.c
 SRCS     += xc_vmx_build.c
 
 CFLAGS   += -Wall
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc.h xen-unstable-devtree/tools/libxc/xc.h
--- xen-unstable/tools/libxc/xc.h       2005-02-07 15:12:20.000000000 +1100
+++ xen-unstable-devtree/tools/libxc/xc.h       2005-02-28 07:07:35.000000000 
+1100
@@ -169,6 +169,30 @@ int xc_shadow_control(int xc_handle,
 
 struct XcIOContext;
 
+/*\
+ * Functions to handle device trees, which are fed into the image in a
+ * flattened form to describe their environment.  Device trees are
+ * trees of keyword value pairs, eg /cpu/1/foo = 1.
+\*/
+struct devtree;
+
+struct devtree *xc_devtree_root_alloc(void);
+
+#define xc_devtree_add(r, d, n, var) \
+       xc_devtree_add_bytes(r, d, n, &(var), sizeof(var), __alignof__(var))
+
+#define xc_devtree_add_string(r, d, n, string) \
+       xc_devtree_add_bytes(r, d, n, (string), strlen(string)+1, 1)
+
+struct devtree *xc_devtree_add_bytes(struct devtree *root,
+                                    const char *dirname,
+                                    const char *name,
+                                    void *data,
+                                    u32 length,
+                                    u32 align);
+
+void xc_devtree_free(struct devtree *root);
+
 /**
  * This function will save a domain running Linux to an IO context.  This
  * IO context is currently a private interface making this function difficult
@@ -198,7 +222,8 @@ int xc_linux_build(int xc_handle,
                    const char *cmdline,
                    unsigned int control_evtchn,
                    unsigned long flags,
-                   unsigned int vcpus);
+                   unsigned int vcpus,
+                   struct devtree *devtree);
 
 int
 xc_plan9_build (int xc_handle,
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc_devtree.c 
xen-unstable-devtree/tools/libxc/xc_devtree.c
--- xen-unstable/tools/libxc/xc_devtree.c       1970-01-01 10:00:00.000000000 
+1000
+++ xen-unstable-devtree/tools/libxc/xc_devtree.c       2005-02-28 
10:09:32.000000000 +1100
@@ -0,0 +1,222 @@
+/*
+ * Code to set up the device tree for a partition.
+ *
+ * Copyright (C) 2005 Rusty Russell IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "xc_private.h"
+
+#define DEVTREE_VERSION 1
+#define DEVTREE_COMPAT_VERSION 1
+
+struct devtree
+{
+       struct devtree *sibling;
+       struct devtree *children;
+
+       u32 datalen;
+       u32 align;
+       void *data;
+
+       char name[0];
+};
+
+/* Skip separator, return next path element. */
+static inline const char *path_element(const char *path, unsigned int *len)
+{
+       path += strspn(path, "/");
+       *len = strcspn(path, "/");
+       return path;
+}
+
+/* Find this name (of this length) under the root. */
+static struct devtree *find(struct devtree *root,
+                           const char *name, unsigned int len)
+{
+       struct devtree *i;
+       for (i = root->children; i; i = i->sibling)
+               if (strlen(i->name) == len && memcmp(name, i->name, len) == 0)
+                       return i;
+       return NULL;
+}
+
+static struct devtree *xc_dt_new(const char *name, unsigned int namelen,
+                                void *data, unsigned int datalen,
+                                unsigned int align)
+{
+       struct devtree *dt = malloc(sizeof(*dt) + namelen + 1 + datalen);
+
+       if (!dt)
+               return NULL;
+
+       dt->children = NULL;
+       dt->sibling = NULL;
+
+       memcpy(dt->name, name, namelen);
+       dt->name[namelen] = '\0';
+
+       dt->datalen = datalen;
+       dt->align = align;
+       dt->data = dt->name + namelen + 1;
+       memcpy(dt->data, data, datalen);
+       return dt;
+}
+
+struct devtree *xc_devtree_root_alloc(void)
+{
+       return xc_dt_new(NULL, 0, NULL, 0, 1);
+}
+
+/* Find directory, make it if neccessary.  */
+static struct devtree *find_dir(struct devtree *root, const char *dirname)
+{
+       unsigned int dirlen;
+       struct devtree *subdir;
+
+       dirname = path_element(dirname, &dirlen);
+       if (dirlen == 0)
+               return root;
+
+       subdir = find(root, dirname, dirlen);
+       if (!subdir) {
+               subdir = xc_dt_new(dirname, dirlen, NULL, 0, 0);
+               if (!subdir)
+                       return NULL;
+               subdir->sibling = root->children;
+               root->children = subdir;
+       }
+       return find_dir(subdir, dirname + dirlen);
+}
+
+struct devtree *xc_devtree_add_bytes(struct devtree *root,
+                                    const char *dirname,
+                                    const char *name,
+                                    void *data,
+                                    u32 length,
+                                    u32 align)
+{
+       struct devtree *dir, *dt;
+
+       dir = find_dir(root, dirname);
+       if (!dir)
+               return NULL;
+
+       dt = xc_dt_new(name, strlen(name), data, length, align);
+       if (!dt)
+               return NULL;
+
+       dt->sibling = dir->children;
+       dir->children = dt;
+       return root;
+}
+
+void xc_devtree_free(struct devtree *root)
+{
+       struct devtree *i;
+
+       for (i = root->children; i; i = i->sibling)
+               xc_devtree_free(i);
+       free(root);
+}
+
+/* Assume alignment is a power of 2. */
+static inline u32 align_up(u32 val, u32 alignment)
+{
+       return (val + alignment-1) & ~(alignment-1);
+}
+
+static u32 calculate_sizes(struct devtree *root, u32 *namelen, u32 *datalen,
+                          u32 *maxalign)
+{
+       u32 nodes = 1;
+       struct devtree *i;
+
+       *namelen += strlen(root->name) + 1;
+       *datalen = align_up(*datalen, root->align) + root->datalen;
+
+       if (root->align > *maxalign)
+               *maxalign = root->align;
+
+       for (i = root->children; i; i = i->sibling)
+               nodes += calculate_sizes(i, namelen, datalen, maxalign);
+       return nodes;
+}
+
+/* FIXME: In future if trees get big, search for duplicate names. */
+static void copy_nodes(struct devtree *root, u32 parent_index,
+                      struct xen_devtree_node *nodes, u32 *nodeindex,
+                      char *names, u32 *nameindex,
+                      void *data, u32 *dataindex)
+{
+       struct devtree *i;
+
+       /* Copy myself in. */
+       nodes[*nodeindex].parent = parent_index;
+       strcpy(names + *nameindex, root->name);
+       nodes[*nodeindex].name = *nameindex;
+       *nameindex += strlen(root->name) + 1;
+       *dataindex = align_up(*dataindex, root->align);
+       memcpy(data + *dataindex, root->data, root->datalen);
+       nodes[*nodeindex].data = *dataindex;
+       *dataindex += root->datalen;
+       nodes[*nodeindex].len = root->datalen;
+
+       parent_index = (*nodeindex);
+       (*nodeindex)++;
+
+       /* Copy children in. */
+       for (i = root->children; i; i = i->sibling)
+               copy_nodes(i, parent_index, nodes, nodeindex,
+                          names, nameindex, data, dataindex);
+}
+
+struct xen_devtree_header *xc_devtree_flatten(struct devtree *root, u32 *len)
+{
+       u32 nodes, namelen, datalen, maxalign;
+       u32 nodeindex, nameindex, dataindex;
+       struct xen_devtree_header *hdr;
+
+       namelen = datalen = 0;
+       maxalign = 1;
+
+       /* Walk once to calculate lengths (and hence offsets). */
+       nodes = calculate_sizes(root, &namelen, &datalen, &maxalign);
+
+       *len = sizeof(*hdr) + nodes * sizeof(struct xen_devtree_node);
+       *len += namelen;
+       *len = align_up(*len, maxalign);
+       *len += datalen;
+
+       hdr = malloc(*len);
+       if (!hdr)
+               return NULL;
+
+       hdr->version = DEVTREE_VERSION;
+       hdr->last_comp_version = DEVTREE_COMPAT_VERSION;
+       hdr->root_offset = sizeof(*hdr);
+       hdr->num_nodes = nodes;
+       hdr->name_offset = hdr->root_offset
+               + nodes * sizeof(struct xen_devtree_node);
+       hdr->data_offset = align_up(hdr->name_offset + namelen, maxalign);
+
+       nodeindex = nameindex = dataindex = 0;
+       /* Walk a second time actually copying. */
+       copy_nodes(root, 0,
+                  (void *)hdr + hdr->root_offset, &nodeindex,
+                  (void *)hdr + hdr->name_offset, &nameindex,
+                  (void *)hdr + hdr->data_offset, &dataindex);
+       return hdr;
+}
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc_linux_build.c 
xen-unstable-devtree/tools/libxc/xc_linux_build.c
--- xen-unstable/tools/libxc/xc_linux_build.c   2005-02-26 01:20:58.000000000 
+1100
+++ xen-unstable-devtree/tools/libxc/xc_linux_build.c   2005-02-28 
06:25:05.000000000 +1100
@@ -52,7 +52,8 @@ static int setup_guest(int xc_handle,
                          unsigned long shared_info_frame,
                          unsigned int control_evtchn,
                          unsigned long flags,
-                         unsigned int vcpus)
+                         unsigned int vcpus,
+                         void *flat_tree, unsigned long flat_size)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
     l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -72,6 +73,8 @@ static int setup_guest(int xc_handle,
     struct domain_setup_info dsi;
     unsigned long vinitrd_start;
     unsigned long vinitrd_end;
+    unsigned long vdevtree_start;
+    unsigned long vdevtree_end;
     unsigned long vphysmap_start;
     unsigned long vphysmap_end;
     unsigned long vstartinfo_start;
@@ -110,7 +113,9 @@ static int setup_guest(int xc_handle,
      */
     vinitrd_start    = round_pgup(dsi.v_end);
     vinitrd_end      = vinitrd_start + initrd_len;
-    vphysmap_start   = round_pgup(vinitrd_end);
+    vdevtree_start   = round_pgup(vinitrd_end);
+    vdevtree_end     = vdevtree_start + flat_size;
+    vphysmap_start   = round_pgup(vdevtree_end);
     vphysmap_end     = vphysmap_start + (nr_pages * sizeof(unsigned long));
     vpt_start        = round_pgup(vphysmap_end);
     for ( nr_pt_pages = 2; ; nr_pt_pages++ )
@@ -131,6 +136,7 @@ static int setup_guest(int xc_handle,
     printf("VIRTUAL MEMORY ARRANGEMENT:\n"
            " Loaded kernel: %08lx->%08lx\n"
            " Init. ramdisk: %08lx->%08lx\n"
+           " Device tree:   %08lx->%08lx\n"
            " Phys-Mach map: %08lx->%08lx\n"
            " Page tables:   %08lx->%08lx\n"
            " Start info:    %08lx->%08lx\n"
@@ -138,6 +144,7 @@ static int setup_guest(int xc_handle,
            " TOTAL:         %08lx->%08lx\n",
            dsi.v_kernstart, dsi.v_kernend, 
            vinitrd_start, vinitrd_end,
+           vdevtree_start, vdevtree_end,
            vphysmap_start, vphysmap_end,
            vpt_start, vpt_end,
            vstartinfo_start, vstartinfo_end,
@@ -187,6 +194,15 @@ static int setup_guest(int xc_handle,
         }
     }
 
+    /* Load the flattened device tree. */
+    for ( i = (vdevtree_start - dsi.v_start); 
+         i < (vdevtree_end - dsi.v_start); i += PAGE_SIZE )
+    {
+       xc_copy_to_domain_page(xc_handle, dom,
+                              page_array[i>>PAGE_SHIFT],
+                              flat_tree + i);
+    }
+
     if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
         goto error_out;
 
@@ -323,7 +339,8 @@ int xc_linux_build(int xc_handle,
                    const char *cmdline,
                    unsigned int control_evtchn,
                    unsigned long flags,
-                   unsigned int vcpus)
+                   unsigned int vcpus,
+                   struct devtree *devtree)
 {
     dom0_op_t launch_op, op;
     int initrd_fd = -1;
@@ -333,7 +350,9 @@ int xc_linux_build(int xc_handle,
     unsigned long nr_pages;
     char         *image = NULL;
     unsigned long image_size, initrd_size=0;
+    u32 flat_size = 0;
     unsigned long vstartinfo_start, vkern_entry;
+    struct xen_devtree_header *flat_tree = NULL;
 
     if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
     {
@@ -383,13 +402,22 @@ int xc_linux_build(int xc_handle,
         ERROR("Domain is already constructed");
         goto error_out;
     }
+    if ( devtree )
+    {
+       flat_tree = xc_devtree_flatten(devtree, &flat_size);
+       if ( !flat_tree ) {
+           ERROR("Out of memory flattening device tree");
+           goto error_out;
+       }
+    }
 
     if ( setup_guest(xc_handle, domid, image, image_size, 
                        initrd_gfd, initrd_size, nr_pages, 
                        &vstartinfo_start, &vkern_entry,
                        ctxt, cmdline,
                        op.u.getdomaininfo.shared_info_frame,
-                       control_evtchn, flags, vcpus) < 0 )
+                       control_evtchn, flags, vcpus,
+                       flat_tree, flat_size) < 0 )
     {
         ERROR("Error constructing guest OS");
         goto error_out;
@@ -401,6 +429,8 @@ int xc_linux_build(int xc_handle,
         gzclose(initrd_gfd);
     if ( image != NULL )
         free(image);
+    if ( flat_tree )
+       free(flat_tree);
 
     ctxt->flags = 0;
 
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/libxc/xc_private.h 
xen-unstable-devtree/tools/libxc/xc_private.h
--- xen-unstable/tools/libxc/xc_private.h       2005-02-07 15:12:19.000000000 
+1100
+++ xen-unstable-devtree/tools/libxc/xc_private.h       2005-02-28 
07:08:07.000000000 +1100
@@ -202,4 +202,9 @@ void xc_map_memcpy(unsigned long dst, ch
                    int xch, u32 dom, unsigned long *parray,
                    unsigned long vstart);
 
+/* Returns a flattened structure: free() as normal. */
+struct xen_devtree_header;
+struct devtree;
+struct xen_devtree_header *xc_devtree_flatten(struct devtree *root, u32 *len);
+
 #endif /* __XC_PRIVATE_H__ */
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/tools/python/xen/lowlevel/xc/xc.c 
xen-unstable-devtree/tools/python/xen/lowlevel/xc/xc.c
--- xen-unstable/tools/python/xen/lowlevel/xc/xc.c      2005-02-26 
01:20:59.000000000 +1100
+++ xen-unstable-devtree/tools/python/xen/lowlevel/xc/xc.c      2005-02-28 
10:18:30.000000000 +1100
@@ -349,19 +349,34 @@ static PyObject *pyxc_linux_build(PyObje
     u32   dom;
     char *image, *ramdisk = NULL, *cmdline = "";
     int   control_evtchn, flags = 0, vcpus = 1;
+    struct devtree *root = NULL;
 
     static char *kwd_list[] = { "dom", "control_evtchn", 
                                 "image", "ramdisk", "cmdline", "flags", 
"vcpus",
                                 NULL };
 
+#if 0
+    root = xc_devtree_root_alloc();
+    root = xc_devtree_add_string(root, "/", "test", "teststring");
+    {
+           int x = 7;
+           root = xc_devtree_add(root, "/dir/subdir", "seven", x);
+    }
+#endif
+
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssii", kwd_list, 
                                       &dom, &control_evtchn, 
                                       &image, &ramdisk, &cmdline, &flags, 
&vcpus) )
         return NULL;
 
+
     if ( xc_linux_build(xc->xc_handle, dom, image,
-                        ramdisk, cmdline, control_evtchn, flags, vcpus) != 0 )
+                        ramdisk, cmdline, control_evtchn, flags, vcpus, root) 
!= 0 )
         return PyErr_SetFromErrno(xc_error);
+
+#if 0
+    xc_devtree_free(root);
+#endif
     
     Py_INCREF(zero);
     return zero;
diff -urpN --exclude='*.py' --exclude dist --exclude html --exclude ps 
--exclude '*-xen0' --exclude '*-xenU' --exclude 'pristine-*' --exclude TAGS 
--exclude '*.o' --exclude asm-offsets.h --exclude asm-offsets.s --exclude 
.chkbuild --exclude '*~' --exclude '.*.d' --exclude classlist.h --exclude 
devlist.h --exclude asm --exclude banner.h --exclude compile.h --minimal 
xen-unstable/xen/include/public/xen.h 
xen-unstable-devtree/xen/include/public/xen.h
--- xen-unstable/xen/include/public/xen.h       2005-02-26 01:21:04.000000000 
+1100
+++ xen-unstable-devtree/xen/include/public/xen.h       2005-02-28 
04:50:02.000000000 +1100
@@ -428,8 +428,30 @@ typedef struct {
     _MEMORY_PADDING(F);
     memory_t mod_len;         /* 56: Size (bytes) of pre-loaded module.    */
     _MEMORY_PADDING(G);
-    u8 cmd_line[MAX_CMDLINE]; /* 64 */
-} PACKED start_info_t; /* 320 bytes */
+    memory_t devtree_start;   /* 64: VIRTUAL address of device tree. */
+    _MEMORY_PADDING(H);
+    memory_t devtree_len;     /* 72: Size (bytes) of device tree. */
+    _MEMORY_PADDING(I);
+    u8 cmd_line[MAX_CMDLINE]; /* 80 */
+} PACKED start_info_t; /* 336 bytes */
+
+/* Nodes are arranged so parent always preceeds us. */
+struct xen_devtree_node
+{
+    u32 parent;               /* Index of parent (root has parent 0 = self) */
+    u32 name;                 /* Offset of name in name table. */
+    u32 data, len;            /* Offset of data in data table, and length */
+};
+
+struct xen_devtree_header
+{
+    u32 version;              /* Version of this structure. */
+    u32 last_comp_version;    /* You must be >= this to read it. */
+    u32 root_offset;          /* Offset to root of tree. */
+    u32 num_nodes;            /* Total number of nodes in tree. */
+    u32 name_offset;          /* Offset to (nul-terminated) names table. */
+    u32 data_offset;          /* Offset to data table. */
+};
 
 /* These flags are passed in the 'flags' field of start_info_t. */
 #define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */

-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/xen-devel


 


Rackspace

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