[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XenPPC] [PATCH 3 of 4] [PATCH] Move flat device tree construction from python to libxc for xc_linux_build()
* Jimi Xenidis <jimix@xxxxxxxxxxxxxx> [2007-01-11 16:53]: > > Ok there are a few things here. Respun with fixes: - preserve and return errno where approriate - using open/close and read/write instead of f* - dropped vcpu argument, only fill out one cpu in devtree - dropped regexp requirment, use a null-terminated list of filters - made sure to call closedir() - fixed double-free of bph on error path - fixed static function names - renamed find_first_cpu to find_cpu, we don't care which cpu we find -- Ryan Harper Software Engineer; Linux Technology Center IBM Corp., Austin, Tx (512) 838-9253 T/L: 678-9253 ryanh@xxxxxxxxxx diffstat output: b/tools/libxc/powerpc64/mk_flatdevtree.c | 567 +++++++++++++++++++++++++++++++ b/tools/libxc/powerpc64/mk_flatdevtree.h | 44 ++ tools/libxc/powerpc64/Makefile | 1 tools/libxc/powerpc64/xc_linux_build.c | 30 + tools/libxc/xenguest.h | 4 tools/python/xen/lowlevel/xc/xc.c | 12 tools/python/xen/xend/image.py | 5 7 files changed, 646 insertions(+), 17 deletions(-) Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx> --- [PATCH] Move flat device tree construction from python to libxc for xc_linux_build(). Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx> diff -r 3edbfb956864 tools/libxc/powerpc64/Makefile --- a/tools/libxc/powerpc64/Makefile Fri Jan 12 15:16:42 2007 -0600 +++ b/tools/libxc/powerpc64/Makefile Fri Jan 12 15:16:42 2007 -0600 @@ -1,4 +1,5 @@ GUEST_SRCS-y += powerpc64/flatdevtree.c GUEST_SRCS-y += powerpc64/flatdevtree.c +GUEST_SRCS-y += powerpc64/mk_flatdevtree.c GUEST_SRCS-y += powerpc64/xc_linux_build.c GUEST_SRCS-y += powerpc64/xc_prose_build.c GUEST_SRCS-y += powerpc64/utils.c diff -r 3edbfb956864 tools/libxc/powerpc64/xc_linux_build.c --- a/tools/libxc/powerpc64/xc_linux_build.c Fri Jan 12 15:16:42 2007 -0600 +++ b/tools/libxc/powerpc64/xc_linux_build.c Fri Jan 12 16:00:33 2007 -0600 @@ -13,9 +13,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * Copyright (C) IBM Corporation 2006 + * Copyright IBM Corporation 2006, 2007 * * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> + * Ryan Harper <ryanh@xxxxxxxxxx> */ #include <stdio.h> @@ -36,6 +37,7 @@ #include "flatdevtree_env.h" #include "flatdevtree.h" #include "utils.h" +#include "mk_flatdevtree.h" #define INITRD_ADDR (24UL << 20) #define DEVTREE_ADDR (16UL << 20) @@ -238,8 +240,7 @@ int xc_linux_build(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, - unsigned long *console_mfn, - void *devtree) + unsigned long *console_mfn) { start_info_t start_info; struct domain_setup_info dsi; @@ -251,12 +252,34 @@ int xc_linux_build(int xc_handle, unsigned long initrd_len = 0; unsigned long start_info_addr; unsigned long rma_pages; + unsigned long shadow_mb; int rc = 0; + int op; + struct ft_cxt root; + void *devtree; DPRINTF("%s\n", __func__); nr_pages = mem_mb << (20 - PAGE_SHIFT); DPRINTF("nr_pages 0x%lx\n", nr_pages); + + /* fetch the current shadow_memory value for this domain */ + op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION; + if (xc_shadow_control(xc_handle, domid, op, NULL, 0, &shadow_mb, 0, NULL) < 0 ) { + rc = -1; + goto out; + } + + /* build the devtree here */ + DPRINTF("constructing devtree\n"); + if (make_devtree(&root, domid, mem_mb, shadow_mb, cmdline) < 0) { + DPRINTF("failed to create flattened device tree\n"); + rc = -1; + goto out; + } + + /* point devtree at bph blob */ + devtree = root.bph; rma_pages = get_rma_pages(devtree); if (rma_pages == 0) { @@ -314,6 +337,7 @@ int xc_linux_build(int xc_handle, } out: + free_devtree(&root); free_page_array(page_array); return rc; } diff -r 3edbfb956864 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Fri Jan 12 15:16:42 2007 -0600 +++ b/tools/libxc/xenguest.h Fri Jan 12 17:08:40 2007 -0600 @@ -57,7 +57,6 @@ int xc_linux_restore(int xc_handle, int * @parm store_mfn returned with the mfn of the store page * @parm console_evtchn the console event channel for this domain to use * @parm console_mfn returned with the mfn of the console page - * @parm arch_args architecture-specific data * @return 0 on success, -1 on failure */ int xc_linux_build(int xc_handle, @@ -71,8 +70,7 @@ int xc_linux_build(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, - unsigned long *console_mfn, - void *arch_args); + unsigned long *console_mfn); /** * This function will create a domain for a paravirtualized Linux diff -r 3edbfb956864 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Fri Jan 12 15:16:42 2007 -0600 +++ b/tools/python/xen/lowlevel/xc/xc.c Fri Jan 12 17:08:40 2007 -0600 @@ -338,28 +338,26 @@ static PyObject *pyxc_linux_build(XcObje unsigned int mem_mb; unsigned long store_mfn = 0; unsigned long console_mfn = 0; - void *arch_args = NULL; int unused; static char *kwd_list[] = { "domid", "store_evtchn", "memsize", "console_evtchn", "image", /* optional */ "ramdisk", "cmdline", "flags", - "features", "arch_args", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssiss#", kwd_list, + "features", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis#", kwd_list, &dom, &store_evtchn, &mem_mb, &console_evtchn, &image, /* optional */ &ramdisk, &cmdline, &flags, - &features, &arch_args, &unused) ) + &features, &unused) ) return NULL; if ( xc_linux_build(self->xc_handle, dom, mem_mb, image, ramdisk, cmdline, features, flags, store_evtchn, &store_mfn, - console_evtchn, &console_mfn, - arch_args) != 0 ) { + console_evtchn, &console_mfn) != 0 ) { if (!errno) errno = EINVAL; return PyErr_SetFromErrno(xc_error); diff -r 3edbfb956864 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Fri Jan 12 15:16:42 2007 -0600 +++ b/tools/python/xen/xend/image.py Fri Jan 12 17:08:40 2007 -0600 @@ -234,8 +234,6 @@ class PPC_LinuxImageHandler(LinuxImageHa log.debug("vcpus = %d", self.vm.getVCpuCount()) log.debug("features = %s", self.vm.getFeatures()) - devtree = FlatDeviceTree.build(self) - return xc.linux_build(domid = self.vm.getDomid(), memsize = mem_mb, image = self.kernel, @@ -243,8 +241,7 @@ class PPC_LinuxImageHandler(LinuxImageHa console_evtchn = console_evtchn, cmdline = self.cmdline, ramdisk = self.ramdisk, - features = self.vm.getFeatures(), - arch_args = devtree.to_bin()) + features = self.vm.getFeatures()) def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): """@param shadow_mem_kb The configured shadow memory, in KiB. diff -r 3edbfb956864 tools/libxc/powerpc64/mk_flatdevtree.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/powerpc64/mk_flatdevtree.c Sun Jan 14 13:28:16 2007 -0600 @@ -0,0 +1,567 @@ +/* + * 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. + * + * Copyright IBM Corporation 2007 + * + * Authors: Ryan Harper <ryanh@xxxxxxxxxx> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <dirent.h> +#include <unistd.h> +#include <libgen.h> +#include <inttypes.h> +#include <math.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/dir.h> +#include <sys/stat.h> +#include <sys/param.h> + +#include <xc_private.h> /* for PERROR() */ + +#include "mk_flatdevtree.h" + + +static int readfile(const char *fullpath, void *data, int len) +{ + struct stat st; + int saved_errno; + int rc = -1; + int fd; + + if ((fd = open(fullpath, O_RDONLY)) == -1) { + PERROR("%s: failed to open file %s", __func__, fullpath); + return -1; + } + + if ((rc = fstat(fd, &st)) == -1) { + PERROR("%s: failed to stat fd %d", __func__, fd); + goto error; + } + + if (S_ISREG(st.st_mode)) + rc = read(fd, data, MIN(len, st.st_size)); + + close(fd); + return rc; + +error: + saved_errno = errno; + close(fd); + errno = saved_errno; + return -1; +} + +/* + * @property - string to check against the filter list + * @filter - NULL terminated list of strings + * + * compare @property string to each string in @filter + * + * return 1 if @property matches any filter, otherwise 0 + * + */ +static int match(const char *property, const char **filter) +{ + int i; + + if ((property == NULL) || (filter == NULL) || (*filter == NULL)) + return -1; + + for (i=0; filter[i] != NULL; i++) { + /* compare the filter to property, ignoring NULL terminator */ + if (strncmp(property, filter[i], sizeof(filter[i])-1) == 0) + return 1; + } + + return 0; +} + +/* + * copy the node at @dirpath filtering out any properties that match in @propfilter + */ +static int copynode(struct ft_cxt *cxt, const char *dirpath, const char **propfilter) +{ + struct dirent *tree; + struct stat st; + DIR *dir; + char fullpath[MAX_PATH]; + char *bname = NULL; + char *basec = NULL; + int saved_errno; + + if ((dir = opendir(dirpath)) == NULL) { + PERROR("%s: failed to open dir %s", __func__, dirpath); + return -1; + } + + while (1) { + if ((tree = readdir(dir)) == NULL) + break; /* reached end of directory entries */ + + /* ignore . and .. */ + if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0) + continue; + + /* build full path name of the file, for stat() */ + if (snprintf(fullpath, sizeof(fullpath), "%s/%s", dirpath, tree->d_name) <= 0) { + PERROR("%s: failed to build full path", __func__); + goto error; + } + + /* stat the entry */ + if (stat(fullpath, &st) < 0) { + PERROR("%s: failed to stat file %s", __func__, fullpath); + goto error; + } + + if (S_ISDIR(st.st_mode)) { + /* start a new node for a dir */ + ft_begin_node(cxt, tree->d_name); + + /* copy everything in this dir */ + if (copynode(cxt, fullpath, propfilter) < 0) { + PERROR("%s: failed to copy node @ %s", __func__, fullpath); + goto error; + } + + /* end the node */ + ft_end_node(cxt); + } + /* add files in dir as properties */ + else if (S_ISREG(st.st_mode)) { + + if ((basec = strdup(fullpath)) == NULL) { + PERROR("%s: failed to dupe string", __func__); + goto error; + } + + if ((bname = basename(basec)) == NULL) { + PERROR("%s: basename() failed", __func__); + goto error; + } + + /* only add files that don't match the property filter string */ + if (!match(bname, propfilter)) { + char data[BUFSIZE]; + int len; + + /* snarf the data and push into the property */ + if ((len = readfile(fullpath, data, sizeof(data))) < 0) { + PERROR("%s: failed to read data from file %s", __func__, + fullpath); + goto error; + } + ft_prop(cxt, tree->d_name, data, len); + + } + + /* strdup mallocs memory */ + if (basec != NULL ) { + free(basec); + basec = NULL; + } + + } + } + + closedir(dir); + return 0; + +error: + saved_errno = errno; + + /* strdup mallocs memory */ + if (basec != NULL ) { + free(basec); + basec = NULL; + } + + closedir(dir); + + errno = saved_errno; + return -1; +} + +static int find_cpu(char *cpupath, int len) +{ + const char path[] = "/proc/device-tree/cpus"; + const char device[] = "device_type"; + const char dev_cpu[] = "cpu"; + char data[sizeof(dev_cpu)]; + char cpu[MAX_PATH]; + char node[MAX_PATH]; + struct dirent *tree; + struct stat st; + DIR* dir; + int saved_errno; + int found = 0; + + if ((dir = opendir(path)) == NULL) { + PERROR("%s: failed to open directory %s", __func__, path); + return -1; + } + + while (!found) { + + if ((tree = readdir(dir)) == NULL) + break; /* reached end of directory entries */ + + /* ignore ., .. */ + if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0) + continue; + + /* build full path name of the file, for stat() */ + if (snprintf(node, sizeof(node), "%s/%s", path, tree->d_name) <= 0) { + PERROR("%s: failed to concat strings", __func__); + goto error; + } + + /* stat the entry */ + if (stat(node, &st) < 0) { + PERROR("%s: failed to stat file %s", __func__, node); + /* something funny happen in /proc/device-tree, but march onward */ + continue; + } + + /* for each dir, check the device_type property until we find 'cpu'*/ + if (S_ISDIR(st.st_mode)) { + + /* construct path to device_type */ + if (snprintf(cpu, sizeof(cpu), "%s/%s", node, device) <= 0) { + PERROR("%s: failed to concat strings", __func__); + goto error; + } + + /* read device_type into buffer */ + if ((readfile(cpu, data, sizeof(data))) < 0) { + PERROR("%s: failed to read data from file %s", __func__, cpu); + goto error; + } + + /* if the device_type is 'cpu', return the path where we found it */ + if (strcmp(data, "cpu") == 0) { + if (snprintf(cpupath, len, "%s", node) <= 0) { + PERROR("%s: failed to copy cpupath", __func__); + goto error; + } + found = 1; + } + } + } + + closedir(dir); + return 0; + +error: + saved_errno = errno; + closedir(dir); + errno = saved_errno; + return -1; +} + +void free_devtree(struct ft_cxt *root) +{ + if ((root != NULL) && root->bph != NULL) { + free(root->bph); + root->bph = NULL; + } +} + +int make_devtree( + struct ft_cxt *root, + uint32_t domid, uint32_t mem_mb, + unsigned long shadow_mb, + const char *bootargs) +{ + struct boot_param_header *bph = NULL; + uint64_t val[2]; + uint32_t val32[2]; + uint64_t totalmem; + uint64_t rma_bytes; + uint64_t remaining; + uint64_t pft_size; + int64_t shadow_mb_log; + char cpupath[MAX_PATH]; + const char *propfilter[] = { "ibm", "linux,", NULL }; + char *cpupath_copy = NULL; + char *cpuname = NULL; + int saved_errno; + int dtb_fd = -1; + int rma_log; + + /* initialize bph to prevent double free on error path */ + root->bph = NULL; + + /* carve out space for bph */ + if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) { + PERROR("%s: Failed to malloc bph buffer size", __func__); + goto error; + } + + /* NB: struct ft_cxt root defined at top of file */ + /* root = Tree() */ + ft_begin(root, bph, BPH_SIZE); + + /* you MUST set reservations BEFORE _starting_the_tree_ */ + + /* root.reserve(0x1000000, 0x1000) */ + val[0] = cpu_to_be64((u64) 0x1000000); + val[1] = cpu_to_be64((u64) 0x1000); + ft_add_rsvmap(root, val[0], val[1]); + + /* root.reserve(0x3ffc000, 0x4000 */ + val[0] = cpu_to_be64((u64) 0x3ffc000); + val[1] = cpu_to_be64((u64) 0x4000); + ft_add_rsvmap(root, val[0], val[1]); + + /* done with reservations, _starting_the_tree_ */ + ft_begin_tree(root); + + /* make root node */ + ft_begin_node(root, ""); + + /* root.addprop('device_type', 'chrp-but-not-really\0') */ + ft_prop_str(root, "device_type", "chrp-but-not-really"); + + /* root.addprop('#size-cells', 2) */ + ft_prop_int(root, "#size-cells", 2); + + /* root.addprop('#address-cells', 2) */ + ft_prop_int(root, "#address-cells", 2); + + /* root.addprop('model', 'Momentum,Maple-D\0') */ + ft_prop_str(root, "model", "Momentum,Maple-D"); + + /* root.addprop('compatible', 'Momentum,Maple\0') */ + ft_prop_str(root, "compatible", "Momentum,Maple"); + + /* start chosen node */ + ft_begin_node(root, "chosen"); + + /* chosen.addprop('cpu', cpu0.get_phandle()) */ + ft_prop_int(root, "cpu", PHANDLE_CPU0); + + /* chosen.addprop('rma', rma.get_phandle()) */ + ft_prop_int(root, "memory", PHANDLE_RMA); + + /* chosen.addprop('linux,stdout-path', '/xen/console\0') */ + ft_prop_str(root, "linux,stdout-path", "/xen/console"); + + /* chosen.addprop('interrupt-controller, xen.get_phandle()) */ + ft_prop_int(root, "interrupt-controller", PHANDLE_XEN); + + /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */ + if ( bootargs != NULL ) + ft_prop_str(root, "bootargs", bootargs); + + /* xc_linux_load.c will overwrite these 64-bit properties later + * + * chosen.addprop('linux,initrd-start', long(0)) + * chosen.addprop('linux,initrd-end', long(0))) + */ + val[0] = cpu_to_be64((u64) 0); + ft_prop(root, "linux,initrd-start", val, sizeof(val[0])); + ft_prop(root, "linux,initrd-end", val, sizeof(val[0])); + + /* end chosen node */ + ft_end_node(root); + + /* xen = root.addnode('xen') */ + ft_begin_node(root, "xen"); + + /* xen.addprop('start-info', long(0x3ffc000), long(0x1000)) */ + val[0] = cpu_to_be64((u64) 0x3ffc000); + val[1] = cpu_to_be64((u64) 0x1000); + ft_prop(root, "start-info", val, sizeof(val)); + + /* xen.addprop('version', 'Xen-3.0-unstable\0') */ + ft_prop_str(root, "version", "Xen-3.0-unstable"); + + /* xen.addprop('reg', long(imghandler.vm.domid), long(0)) */ + val[0] = cpu_to_be64((u64) domid); + val[1] = cpu_to_be64((u64) 0); + ft_prop(root, "reg", val, sizeof(val)); + + /* xen.addprop('domain-name', imghandler.vm.getName() + '\0') */ + /* libxc doesn't know the domain name, that is purely a xend thing */ + /* ft_prop_str(root, "domain-name", domain_name); */ + + /* add xen/linux,phandle for chosen/interrupt-controller */ + ft_prop_int(root, "linux,phandle", PHANDLE_XEN); + + /* xencons = xen.addnode('console') */ + ft_begin_node(root, "console"); + + /* xencons.addprop('interrupts', 1, 0) */ + val32[0] = cpu_to_be32((u32) 1); + val32[1] = cpu_to_be32((u32) 0); + ft_prop(root, "interrupts", val32, sizeof(val32)); + + /* end of console */ + ft_end_node(root); + + /* end of xen node */ + ft_end_node(root); + + /* add memory nodes */ + totalmem = mem_mb * 1024 * 1024; + rma_log = 26; /* usually a parameter */ + rma_bytes = 1 << rma_log; + remaining = totalmem - rma_bytes; + + /* rma = root.addnode('memory@0') */ + ft_begin_node(root, "memory@0"); + + /* rma.addprop('reg', long(0), long(rma_bytes)) */ + val[0] = cpu_to_be64((u64) 0); + val[1] = cpu_to_be64((u64) rma_bytes); + ft_prop(root, "reg", val, sizeof(val)); + + /* rma.addprop('device_type', 'memory\0') */ + ft_prop_str(root, "device_type", "memory"); + + /* add linux,phandle for chosen/rma node */ + ft_prop_int(root, "linux,phandle", PHANDLE_RMA); + + /* end of memory@0 */ + ft_end_node(root); + + /* memory@1 is all the rest */ + if (remaining > 0) + { + /* mem = root.addnode('memory@1') */ + ft_begin_node(root, "memory@1"); + + /* mem.addprop('reg', long(rma_bytes), long(remaining)) */ + val[0] = cpu_to_be64((u64) rma_bytes); + val[1] = cpu_to_be64((u64) remaining); + ft_prop(root, "reg", val, sizeof(val)); + + /* mem.addprop('device_type', 'memory\0') */ + ft_prop_str(root, "device_type", "memory"); + + /* end memory@1 node */ + ft_end_node(root); + } + + /* add CPU nodes */ + /* cpus = root.addnode('cpus') */ + ft_begin_node(root, "cpus"); + + /* cpus.addprop('smp-enabled') */ + ft_prop(root, "smp-enabled", NULL, 0); + + /* cpus.addprop('#size-cells', 0) */ + ft_prop_int(root, "#size-cells", 0); + + /* cpus.addprop('#address-cells', 1) */ + ft_prop_int(root, "#address-cells", 1); + + /* + * Copy all properties the system firmware gave us from a + * CPU node in the device tree. + */ + if (find_cpu(cpupath, sizeof(cpupath)) < 0) { + PERROR("%s: failed find a cpu device in host devtree", __func__); + goto error; + } + + /* get the basename from path to cpu device */ + if ((cpupath_copy = strdup(cpupath)) == NULL) { + PERROR("%s: failed to dupe string", __func__); + goto error; + } + if ((cpuname = basename(cpupath_copy)) == NULL) { + PERROR("%s: basename() failed", __func__); + goto error; + } + + /* start node for the cpu */ + ft_begin_node(root, cpuname); + + /* strdup() mallocs memory */ + if ( cpupath_copy != NULL ) { + free(cpupath_copy); + cpupath_copy = NULL; + } + + /* copy over most properties from host tree for cpu */ + if (copynode(root, cpupath, propfilter) < 0) { + PERROR("%s: failed to copy node", __func__); + goto error; + } + + /* calculate the pft-size */ + shadow_mb_log = (int)log2((double)shadow_mb); + pft_size = shadow_mb_log + 20; + + val32[0] = cpu_to_be32((u32) 0); + val32[1] = cpu_to_be32((u32) pft_size); + ft_prop(root, "ibm,pft-size", val32, sizeof(val32)); + + /* make phandle for cpu0 */ + ft_prop_int(root, "linux,phandle", PHANDLE_CPU0); + + /* end <cpuname> node */ + ft_end_node(root); + + /* end cpus node */ + ft_end_node(root); + + /* end root node */ + ft_end_node(root); + + /* end of the tree */ + if (ft_end_tree(root) != 0) { + PERROR("%s: failed to end tree", __func__); + goto error; + } + + /* write a copy of the tree to a file */ + if ((dtb_fd = open(DTB_FILE , O_RDWR)) == -1) { + PERROR("%s: failed to open file %s", __func__, DTB_FILE); + goto error; + } + + if (write(dtb_fd, (const void *)bph, bph->totalsize) != bph->totalsize) { + PERROR("%s: failed to write blob to file", __func__); + goto error; + } + + return 0; + +error: + saved_errno = errno; + + /* strdup() mallocs memory */ + if ( cpupath_copy != NULL ) { + free(cpupath_copy); + cpupath_copy = NULL; + } + + /* free bph buffer */ + free_devtree(root); + + if (dtb_fd) + close(dtb_fd); + + errno = saved_errno; + return -1; +} diff -r 3edbfb956864 tools/libxc/powerpc64/mk_flatdevtree.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/powerpc64/mk_flatdevtree.h Fri Jan 12 16:01:06 2007 -0600 @@ -0,0 +1,44 @@ +/* + * 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. + * + * Copyright IBM Corporation 2007 + * + * Authors: Ryan Harper <ryanh@xxxxxxxxxx> + */ + +#ifndef MK_FLATDEVTREE_H +#define MK_FLATDEVTREE_H + +#include "flatdevtree_env.h" +#include "flatdevtree.h" + +extern void free_devtree(struct ft_cxt *root); +extern int make_devtree(struct ft_cxt *root, + uint32_t domid, + uint32_t mem_mb, + unsigned long shadow_mb, + const char *bootargs); + +#define MAX_PATH 200 +#define BUFSIZE 1024 +#define BPH_SIZE 16*1024 + +#define PHANDLE_CPU0 1 +#define PHANDLE_RMA 2 +#define PHANDLE_XEN 3 + +#define DTB_FILE "/tmp/domUoftree.out" + +#endif /* MK_FLATDEVTREE_H */ _______________________________________________ Xen-ppc-devel mailing list Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |