[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XenPPC] [xenppc-unstable] [POWERPC] have tools explicitly allocate domU real mode areas
# HG changeset patch # User Hollis Blanchard <hollisb@xxxxxxxxxx> # Node ID a906930d3c20d0145f86ac34c96534899c481cda # Parent 04cc593ae49eff5e5de1fcf4225ef8018e987a0c [POWERPC] have tools explicitly allocate domU real mode areas - don't allocate RMA in arch_domain_create() - create new DOM0_ALLOC_REAL_MODE_AREA dom0_op - expose dom0 op through libxc and python bindings - move Xend memory allocation code into new allocMem() method - subclass XendDomainInfo to supply a PowerPC allocMem(), which understands about RMAs and calls the new dom0 op - don't try to free_domheap_pages(NULL) (happened when destroying a domain after creation error) - make allocate_rma() free previously allocated RMAs - set domain->shared_info in allocate_rma() - add CPU-specific cpu_rma_valid() accessor to make sure Xend chose a good size - allocate dom0's RMA in __start_xen() Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> --- tools/libxc/powerpc64/Makefile | 2 tools/libxc/powerpc64/xc_memory.c | 43 +++++++++++ tools/libxc/xenctrl.h | 4 + tools/python/xen/lowlevel/xc/xc.c | 28 +++++++ tools/python/xen/xend/XendDomainInfo.py | 121 +++++++++++++++++++++++++------- xen/arch/powerpc/dom0_ops.c | 16 ++++ xen/arch/powerpc/domain.c | 22 ----- xen/arch/powerpc/domain_build.c | 3 xen/arch/powerpc/mm.c | 34 ++++++-- xen/arch/powerpc/powerpc64/ppc970.c | 5 + xen/arch/powerpc/setup.c | 7 + xen/include/asm-powerpc/processor.h | 1 xen/include/public/dom0_ops.h | 9 ++ 13 files changed, 235 insertions(+), 60 deletions(-) diff -r 04cc593ae49e -r a906930d3c20 tools/libxc/powerpc64/Makefile --- a/tools/libxc/powerpc64/Makefile Mon Aug 28 18:29:39 2006 -0400 +++ b/tools/libxc/powerpc64/Makefile Mon Aug 28 18:13:38 2006 -0500 @@ -1,2 +1,4 @@ GUEST_SRCS-y += powerpc64/xc_linux_build GUEST_SRCS-y += powerpc64/xc_linux_build.c GUEST_SRCS-y += powerpc64/ft_build.c + +CTRL_SRCS-y += powerpc64/xc_memory.c diff -r 04cc593ae49e -r a906930d3c20 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Aug 28 18:29:39 2006 -0400 +++ b/tools/libxc/xenctrl.h Mon Aug 28 18:13:38 2006 -0500 @@ -434,6 +434,10 @@ int xc_domain_memory_populate_physmap(in unsigned int address_bits, xen_pfn_t *extent_start); +int xc_alloc_real_mode_area(int xc_handle, + uint32_t domid, + unsigned int log); + int xc_domain_translate_gpfn_list(int xc_handle, uint32_t domid, unsigned long nr_gpfns, diff -r 04cc593ae49e -r a906930d3c20 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Mon Aug 28 18:29:39 2006 -0400 +++ b/tools/python/xen/lowlevel/xc/xc.c Mon Aug 28 18:13:38 2006 -0500 @@ -810,6 +810,26 @@ static PyObject *pyxc_domain_memory_incr return zero; } +static PyObject *pyxc_alloc_real_mode_area(XcObject *self, + PyObject *args, + PyObject *kwds) +{ + uint32_t dom; + unsigned int log; + + static char *kwd_list[] = { "dom", "log", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, + &dom, &log) ) + return NULL; + + if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) ) + return PyErr_SetFromErrno(xc_error); + + Py_INCREF(zero); + return zero; +} + static PyObject *pyxc_domain_ioport_permission(XcObject *self, PyObject *args, PyObject *kwds) @@ -1205,6 +1225,14 @@ static PyMethodDef pyxc_methods[] = { "Increase a domain's memory reservation\n" " dom [int]: Identifier of domain.\n" " mem_kb [long]: .\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + + { "alloc_real_mode_area", + (PyCFunction)pyxc_alloc_real_mode_area, + METH_VARARGS | METH_KEYWORDS, "\n" + "Allocate a domain's real mode area.\n" + " dom [int]: Identifier of domain.\n" + " log [int]: Specifies the area's size.\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "domain_ioport_permission", diff -r 04cc593ae49e -r a906930d3c20 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Aug 28 18:29:39 2006 -0400 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Aug 28 18:13:38 2006 -0500 @@ -35,6 +35,7 @@ from xen.util import asserts from xen.util import asserts from xen.util.blkif import blkdev_uname_to_file from xen.util import security +import arch import balloon import image import sxp @@ -187,7 +188,7 @@ def create(config): log.debug("XendDomainInfo.create(%s)", config) - vm = XendDomainInfo(parseConfig(config)) + vm = findDomainClass()(parseConfig(config)) try: vm.construct() vm.initDomain() @@ -237,13 +238,13 @@ def recreate(xeninfo, priv): 'Uuid in store does not match uuid for existing domain %d: ' '%s != %s' % (domid, uuid2_str, xeninfo['uuid'])) - vm = XendDomainInfo(xeninfo, domid, dompath, True, priv) + vm = findDomainClass()(xeninfo, domid, dompath, True, priv) except Exception, exn: if priv: log.warn(str(exn)) - vm = XendDomainInfo(xeninfo, domid, dompath, True, priv) + vm = findDomainClass()(xeninfo, domid, dompath, True, priv) vm.recreateDom() vm.removeVm() vm.storeVmDetails() @@ -262,7 +263,7 @@ def restore(config): log.debug("XendDomainInfo.restore(%s)", config) - vm = XendDomainInfo(parseConfig(config), None, None, False, False, True) + vm = findDomainClass()(parseConfig(config), None, None, False, False, True) try: vm.construct() vm.storeVmDetails() @@ -1266,6 +1267,9 @@ class XendDomainInfo: self.info['image'], self.info['device']) + + self.allocMem() + localtime = self.info['localtime'] if localtime is not None and localtime == 1: xc.domain_set_time_offset(self.domid) @@ -1279,28 +1283,6 @@ class XendDomainInfo: for v in range(0, self.info['max_vcpu_id']+1): xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) - # set memory limit - maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024) - xc.domain_setmaxmem(self.domid, maxmem) - - mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024) - - # get the domain's shadow memory requirement - shadow_kb = self.image.getRequiredShadowMemory(mem_kb) - shadow_kb_req = self.info['shadow_memory'] * 1024 - if shadow_kb_req > shadow_kb: - shadow_kb = shadow_kb_req - - # Make sure there's enough RAM available for the domain - balloon.free(mem_kb + shadow_kb) - - # Set up the shadow memory - shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb / 1024) - self.info['shadow_memory'] = shadow_cur - - # initial memory allocation - xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0) - self.createChannels() channel_details = self.image.createImage() @@ -1321,6 +1303,28 @@ class XendDomainInfo: except RuntimeError, exn: raise VmError(str(exn)) + def allocMem(self): + # set memory limit + maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024) + xc.domain_setmaxmem(self.domid, maxmem) + + mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024) + + # get the domain's shadow memory requirement + shadow_kb = self.image.getRequiredShadowMemory(mem_kb) + shadow_kb_req = self.info['shadow_memory'] * 1024 + if shadow_kb_req > shadow_kb: + shadow_kb = shadow_kb_req + + # Make sure there's enough RAM available for the domain + balloon.free(mem_kb + shadow_kb) + + # Set up the shadow memory + shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb / 1024) + self.info['shadow_memory'] = shadow_cur + + # initial memory allocation + xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0) ## public: @@ -1694,6 +1698,71 @@ class XendDomainInfo: def infoIsSet(self, name): return name in self.info and self.info[name] is not None +class XendDomainInfoPPC(XendDomainInfo): + _rmaLogs = { + "970": (26, 27, 28, 30, 34, 38), + } + + def getRealModeLogs(self): + """Returns a list of RMA sizes this processor supports.""" + cputype = "970" # XXX extract from cpuinfo or device tree + return self._rmaLogs[cputype] + + def allocMem(self): + try: + # set memory limit + maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024) + xc.domain_setmaxmem(self.domid, maxmem) + + mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024) + + # get the domain's shadow memory requirement + shadow_kb = self.image.getRequiredShadowMemory(mem_kb) + shadow_kb_req = self.info['shadow_memory'] * 1024 + if shadow_kb_req > shadow_kb: + shadow_kb = shadow_kb_req + + # Make sure there's enough RAM available for the domain + balloon.free(mem_kb + shadow_kb) + + # Set up the shadow memory, i.e. the PowerPC hash table + shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb / 1024) + self.info['shadow_memory'] = shadow_cur + + # use smallest RMA size available + rma_log = self.getRealModeLogs()[0] + + rma_kb = (1 << rma_log) / 1024 + if mem_kb < rma_kb: + raise ValueError("Domain memory must be at least %d KB" % \ + rma_kb) + + # allocate the RMA + xc.alloc_real_mode_area(self.domid, rma_log) + + # now allocate the remaining memory as order-0 allocations + mem_kb -= rma_kb + if mem_kb > 0: + log.debug("increase_reservation(%d, %d, %d)", self.domid, + mem_kb, 0) + xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0) + + except RuntimeError, exn: + raise VmError(str(exn)) + + +domainTypes = { + "ia64": XendDomainInfo, + "powerpc": XendDomainInfoPPC, + "x86": XendDomainInfo, +} + +def findDomainClass(): + type = arch.type + try: + return domainTypes[type] + except KeyError: + raise VmError("Unsupported architecture: " + type) #============================================================================ # Register device controllers and their device config types. diff -r 04cc593ae49e -r a906930d3c20 xen/arch/powerpc/dom0_ops.c --- a/xen/arch/powerpc/dom0_ops.c Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/arch/powerpc/dom0_ops.c Mon Aug 28 18:13:38 2006 -0500 @@ -26,6 +26,7 @@ #include <xen/shadow.h> #include <public/xen.h> #include <public/dom0_ops.h> +#include <asm/processor.h> extern void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c); extern long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op); @@ -108,6 +109,21 @@ long arch_do_dom0_op(struct dom0_op *op, } } break; + case DOM0_ALLOC_REAL_MODE_AREA: + { + struct domain *d; + unsigned int log = op->u.alloc_real_mode_area.log; + + d = find_domain_by_id(op->u.alloc_real_mode_area.domain); + if (d == NULL) + return -ESRCH; + + if (!cpu_rma_valid(log)) + return -EINVAL; + + return allocate_rma(d, log - PAGE_SHIFT); + } + break; default: printk("%s: unsupported op: 0x%x\n", __func__, (op->cmd)); diff -r 04cc593ae49e -r a906930d3c20 xen/arch/powerpc/domain.c --- a/xen/arch/powerpc/domain.c Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/arch/powerpc/domain.c Mon Aug 28 18:13:38 2006 -0500 @@ -75,31 +75,12 @@ unsigned long hypercall_create_continuat int arch_domain_create(struct domain *d) { - unsigned long rma_base; - unsigned long rma_sz; - uint rma_order_pages; - int rc; - if (d->domain_id == IDLE_DOMAIN_ID) { d->shared_info = (void *)alloc_xenheap_page(); clear_page(d->shared_info); return 0; } - - /* allocate the real mode area */ - rma_order_pages = cpu_default_rma_order_pages(); - d->max_pages = 1UL << rma_order_pages; - d->tot_pages = 0; - - rc = allocate_rma(d, rma_order_pages); - if (rc) - return rc; - rma_base = page_to_maddr(d->arch.rma_page); - rma_sz = rma_size(rma_order_pages); - - d->shared_info = (shared_info_t *) - (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); d->arch.large_page_sizes = cpu_large_page_orders( d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order)); @@ -264,7 +245,8 @@ void sync_vcpu_execstate(struct vcpu *v) void domain_relinquish_resources(struct domain *d) { - free_domheap_pages(d->arch.rma_page, d->arch.rma_order); + if (d->arch.rma_page) + free_domheap_pages(d->arch.rma_page, d->arch.rma_order); free_extents(d); } diff -r 04cc593ae49e -r a906930d3c20 xen/arch/powerpc/domain_build.c --- a/xen/arch/powerpc/domain_build.c Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/arch/powerpc/domain_build.c Mon Aug 28 18:13:38 2006 -0500 @@ -154,9 +154,6 @@ int construct_dom0(struct domain *d, return -EINVAL; } printk("*** LOADING DOMAIN 0 ***\n"); - - /* By default DOM0 is allocated all available memory. */ - d->max_pages = ~0U; /* default is the max(1/16th of memory, CONFIG_MIN_DOM0_PAGES) */ if (dom0_nrpages == 0) { diff -r 04cc593ae49e -r a906930d3c20 xen/arch/powerpc/mm.c --- a/xen/arch/powerpc/mm.c Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/arch/powerpc/mm.c Mon Aug 28 18:13:38 2006 -0500 @@ -301,26 +301,40 @@ uint allocate_extents(struct domain *d, return total_nrpages; } - -int allocate_rma(struct domain *d, unsigned int order_pages) -{ + +int allocate_rma(struct domain *d, unsigned int order) +{ + struct vcpu *v; ulong rma_base; - ulong rma_sz = rma_size(order_pages); - - d->arch.rma_page = alloc_domheap_pages(d, order_pages, 0); + ulong rma_sz; + + if (d->arch.rma_page) + free_domheap_pages(d->arch.rma_page, d->arch.rma_order); + + d->arch.rma_page = alloc_domheap_pages(d, order, 0); if (d->arch.rma_page == NULL) { - DPRINTK("Could not allocate order_pages=%d RMA for domain %u\n", - order_pages, d->domain_id); + DPRINTK("Could not allocate order=%d RMA for domain %u\n", + order, d->domain_id); return -ENOMEM; } - d->arch.rma_order = order_pages; + d->arch.rma_order = order; rma_base = page_to_maddr(d->arch.rma_page); + rma_sz = rma_size(d->arch.rma_order); BUG_ON(rma_base & (rma_sz - 1)); /* check alignment */ - /* XXX */ + /* XXX shouldn't be needed */ printk("clearing RMA: 0x%lx[0x%lx]\n", rma_base, rma_sz); memset((void *)rma_base, 0, rma_sz); + + d->shared_info = (shared_info_t *) + (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); + + /* if there are already running vcpus, adjust v->vcpu_info */ + /* XXX untested */ + for_each_vcpu(d, v) { + v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id]; + } return 0; } diff -r 04cc593ae49e -r a906930d3c20 xen/arch/powerpc/powerpc64/ppc970.c --- a/xen/arch/powerpc/powerpc64/ppc970.c Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/arch/powerpc/powerpc64/ppc970.c Mon Aug 28 18:13:38 2006 -0500 @@ -66,6 +66,11 @@ unsigned int cpu_default_rma_order_pages unsigned int cpu_default_rma_order_pages(void) { return rma_orders[0].order - PAGE_SHIFT; +} + +int cpu_rma_valid(unsigned int log) +{ + return cpu_find_rma(log) != NULL; } unsigned int cpu_large_page_orders(uint *sizes, uint max) diff -r 04cc593ae49e -r a906930d3c20 xen/arch/powerpc/setup.c --- a/xen/arch/powerpc/setup.c Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/arch/powerpc/setup.c Mon Aug 28 18:13:38 2006 -0500 @@ -349,8 +349,13 @@ static void __init __start_xen(multiboot /* Create initial domain 0. */ dom0 = domain_create(0); - if ((dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL)) + if (dom0 == NULL) panic("Error creating domain 0\n"); + dom0->max_pages = ~0U; + if (0 > allocate_rma(dom0, cpu_default_rma_order_pages())) + panic("Error allocating domain 0 RMA\n"); + if (NULL == alloc_vcpu(dom0, 0, 0)) + panic("Error creating domain 0 vcpu 0\n"); set_bit(_DOMF_privileged, &dom0->domain_flags); /* post-create hooks sets security label */ diff -r 04cc593ae49e -r a906930d3c20 xen/include/asm-powerpc/processor.h --- a/xen/include/asm-powerpc/processor.h Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/include/asm-powerpc/processor.h Mon Aug 28 18:13:38 2006 -0500 @@ -42,6 +42,7 @@ extern void show_backtrace(ulong sp, ulo extern void show_backtrace(ulong sp, ulong lr, ulong pc); extern unsigned int cpu_extent_order(void); extern unsigned int cpu_default_rma_order_pages(void); +extern int cpu_rma_valid(unsigned int log); extern uint cpu_large_page_orders(uint *sizes, uint max); extern void cpu_initialize(int cpuid); extern void cpu_init_vcpu(struct vcpu *); diff -r 04cc593ae49e -r a906930d3c20 xen/include/public/dom0_ops.h --- a/xen/include/public/dom0_ops.h Mon Aug 28 18:29:39 2006 -0400 +++ b/xen/include/public/dom0_ops.h Mon Aug 28 18:13:38 2006 -0500 @@ -556,6 +556,14 @@ struct dom0_settimeoffset { }; typedef struct dom0_settimeoffset dom0_settimeoffset_t; DEFINE_XEN_GUEST_HANDLE(dom0_settimeoffset_t); + +#define DOM0_ALLOC_REAL_MODE_AREA 51 +struct dom0_alloc_real_mode_area { + domid_t domain; + uint32_t log; +}; +typedef struct dom0_alloc_real_mode_area dom0_alloc_real_mode_area_t; +DEFINE_XEN_GUEST_HANDLE(dom0_alloc_real_mode_area_t); struct dom0_op { uint32_t cmd; @@ -600,6 +608,7 @@ struct dom0_op { struct dom0_hypercall_init hypercall_init; struct dom0_domain_setup domain_setup; struct dom0_settimeoffset settimeoffset; + struct dom0_alloc_real_mode_area alloc_real_mode_area; uint8_t pad[128]; } u; }; diff -r 04cc593ae49e -r a906930d3c20 tools/libxc/powerpc64/xc_memory.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/powerpc64/xc_memory.c Mon Aug 28 18:13:38 2006 -0500 @@ -0,0 +1,43 @@ +/* + * 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 (C) IBM Corporation 2006 + * + * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> + */ + +#include "xc_private.h" +#include <xen/dom0_ops.h> +#include <xen/memory.h> + +int xc_alloc_real_mode_area(int xc_handle, + uint32_t domain, + unsigned int log) +{ + DECLARE_DOM0_OP; + int err; + + op.cmd = DOM0_ALLOC_REAL_MODE_AREA; + op.u.alloc_real_mode_area.domain = domain; + op.u.alloc_real_mode_area.log = log; + + err = do_dom0_op(xc_handle, &op); + + if (err > 0) + DPRINTF("Failed real mode area allocation for dom %u (log %u)\n", + domain, log); + + return err; +} _______________________________________________ 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 |