# HG changeset patch
# User Jimi Xenidis <[EMAIL PROTECTED]>
# Node ID 1811cc5022fb30b40d241c1742eb5f5eb1928fe3
# Parent  f8233165fb80982c36cc8a124c6e017821805843
[POWERPC][XEN] allocate HTAB using shadow calls

This patch will use the shadow_ops call to allocate the domains Hashed
Page-table.  This allows for the management tools to customize its size
for the domain.

Warning! The management tools have yet to be updated to use this
properly and update the devtree accordingly so code will assume 64M
RAM and 1M HTAB while the shadow up continues to receive a 0 request.

Signed-off-by: Jimi Xenidis <[EMAIL PROTECTED]>
---
 xen/arch/powerpc/htab.c          |   68 ---------------------
 xen/arch/powerpc/Makefile        |    1 
 xen/arch/powerpc/domain.c        |   29 ++++-----
 xen/arch/powerpc/domain_build.c  |   32 ++++------
 xen/arch/powerpc/shadow.c        |  122 ++++++++++++++++++++++++++++++++++++---
 xen/include/asm-powerpc/htab.h   |    4 -
 xen/include/asm-powerpc/shadow.h |    9 ++
 7 files changed, 152 insertions(+), 113 deletions(-)

diff -r f8233165fb80 -r 1811cc5022fb xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Sun Aug 27 16:12:00 2006 -0400
+++ b/xen/arch/powerpc/Makefile Sun Aug 27 20:48:06 2006 -0400
@@ -20,7 +20,6 @@ obj-y += external.o
 obj-y += external.o
 obj-y += float.o
 obj-y += hcalls.o
-obj-y += htab.o
 obj-y += iommu.o
 obj-y += irq.o
 obj-y += mambo.o
diff -r f8233165fb80 -r 1811cc5022fb xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Sun Aug 27 16:12:00 2006 -0400
+++ b/xen/arch/powerpc/domain.c Sun Aug 27 20:48:06 2006 -0400
@@ -27,6 +27,7 @@
 #include <xen/domain.h>
 #include <xen/console.h>
 #include <xen/shutdown.h>
+#include <xen/shadow.h>
 #include <xen/mm.h>
 #include <asm/htab.h>
 #include <asm/current.h>
@@ -77,7 +78,6 @@ int arch_domain_create(struct domain *d)
     unsigned long rma_base;
     unsigned long rma_sz;
     uint rma_order_pages;
-    uint htab_order_pages;
     int rc;
 
     if (d->domain_id == IDLE_DOMAIN_ID) {
@@ -104,16 +104,6 @@ int arch_domain_create(struct domain *d)
     d->arch.large_page_sizes = cpu_large_page_orders(
         d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order));
 
-    /* FIXME: we need to the the maximum addressible memory for this
-     * domain to calculate this correctly. It should probably be set
-     * by the managment tools */
-    htab_order_pages = rma_order_pages - 6; /* (1/64) */
-    if (test_bit(_DOMF_privileged, &d->domain_flags)) {
-        /* bump the htab size of privleged domains */
-        ++htab_order_pages;
-    }
-    htab_alloc(d, htab_order_pages);
-
     INIT_LIST_HEAD(&d->arch.extent_list);
 
     return 0;
@@ -121,7 +111,7 @@ int arch_domain_create(struct domain *d)
 
 void arch_domain_destroy(struct domain *d)
 {
-    htab_free(d);
+    shadow_teardown(d);
 }
 
 void machine_halt(void)
@@ -162,6 +152,16 @@ int arch_set_info_guest(struct vcpu *v, 
 int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_t *c)
 { 
     memcpy(&v->arch.ctxt, &c->user_regs, sizeof(c->user_regs));
+
+    printf("Domain[%d].%d: initializing\n",
+           v->domain->domain_id, v->vcpu_id);
+
+    if (v->domain->arch.htab.order == 0)
+        panic("Page table never allocated for Domain: %d\n",
+              v->domain->domain_id);
+    if (v->domain->arch.rma_order == 0)
+        panic("RMA never allocated for Domain: %d\n",
+              v->domain->domain_id);
 
     set_bit(_VCPUF_initialised, &v->vcpu_flags);
 
@@ -253,12 +253,13 @@ void continue_running(struct vcpu *same)
 void continue_running(struct vcpu *same)
 {
     /* nothing to do */
+    return;
 }
 
 void sync_vcpu_execstate(struct vcpu *v)
 {
-    /* XXX for now, for domain destruction, make this non-fatal */
-    printf("%s: called\n", __func__);
+    /* do nothing */
+    return;
 }
 
 void domain_relinquish_resources(struct domain *d)
diff -r f8233165fb80 -r 1811cc5022fb xen/arch/powerpc/domain_build.c
--- a/xen/arch/powerpc/domain_build.c   Sun Aug 27 16:12:00 2006 -0400
+++ b/xen/arch/powerpc/domain_build.c   Sun Aug 27 20:48:06 2006 -0400
@@ -25,12 +25,11 @@
 #include <xen/init.h>
 #include <xen/ctype.h>
 #include <xen/iocap.h>
+#include <xen/shadow.h>
 #include <xen/version.h>
 #include <asm/processor.h>
 #include <asm/papr.h>
 #include "oftree.h"
-
-#define log2(x) ffz(~(x))
 
 extern int parseelfimage_32(struct domain_setup_info *dsi);
 extern int loadelfimage_32(struct domain_setup_info *dsi);
@@ -114,10 +113,10 @@ int construct_dom0(struct domain *d,
     uint rma_nrpages = 1 << d->arch.rma_order;
     ulong rma_sz = rma_size(d->arch.rma_order);
     ulong rma = page_to_maddr(d->arch.rma_page);
-    uint htab_order;
     start_info_t *si;
     ulong eomem;
     int am64 = 1;
+    int preempt = 0;
     ulong msr;
     ulong pc;
     ulong r2;
@@ -174,20 +173,19 @@ int construct_dom0(struct domain *d,
         dom0_nrpages = allocate_extents(d, dom0_nrpages, rma_nrpages);
 
     d->tot_pages = dom0_nrpages;
-    ASSERT(d->tot_pages > 0);
-    
-    htab_order = log2(d->tot_pages) - 6;
-    if (d->arch.htab.order > 0) {
-        /* we incorrectly allocate this too early so lets adjust if
-         * necessary */
-        printk("WARNING: htab allocated to early\n");
-        if (d->arch.htab.order < htab_order) {
-            printk("WARNING: htab reallocated for more memory: 0x%x\n",
-                htab_order);
-            htab_free(d);
-            htab_alloc(d, htab_order);
-        }
-    }
+    ASSERT(d->tot_pages >= rma_nrpages);
+
+    if (opt_dom0_shadow == 0) {
+        /* 1/64 of memory  */
+        opt_dom0_shadow = (d->tot_pages >> 6) >> (20 - PAGE_SHIFT);
+    }
+
+    do {
+        shadow_set_allocation(d, opt_dom0_shadow, &preempt);
+    } while (preempt);
+    if (shadow_get_allocation(d) == 0)
+        panic("shadow allocation failed 0x%x < 0x%x\n",
+              shadow_get_allocation(d), opt_dom0_shadow);
 
     ASSERT( image_len < rma_sz );
 
diff -r f8233165fb80 -r 1811cc5022fb xen/arch/powerpc/shadow.c
--- a/xen/arch/powerpc/shadow.c Sun Aug 27 16:12:00 2006 -0400
+++ b/xen/arch/powerpc/shadow.c Sun Aug 27 20:48:06 2006 -0400
@@ -23,6 +23,99 @@
 #include <xen/shadow.h>
 #include <public/dom0_ops.h>
 
+static ulong htab_calc_sdr1(ulong htab_addr, ulong log_htab_size)
+{
+    ulong sdr1_htabsize;
+
+    ASSERT((htab_addr & ((1UL << log_htab_size) - 1)) == 0);
+    ASSERT(log_htab_size <= SDR1_HTABSIZE_MAX);
+    ASSERT(log_htab_size >= HTAB_MIN_LOG_SIZE);
+
+    sdr1_htabsize = log_htab_size - LOG_PTEG_SIZE - SDR1_HTABSIZE_BASEBITS;
+
+    return (htab_addr | (sdr1_htabsize & SDR1_HTABSIZE_MASK));
+}
+
+static ulong htab_alloc(struct domain *d, uint order)
+{
+    ulong htab_raddr;
+    uint log_htab_bytes = order + PAGE_SHIFT;
+    uint htab_bytes = 1UL << log_htab_bytes;
+
+    /* we use xenheap pages to keep domheap pages usefull for domains */
+
+    if (order < 6)
+        order = 6;              /* architectural minimum is 2^18 */
+    if (order < 34)
+        order = 34;             /* architectural minimum is 2^46 */
+
+    htab_raddr = (ulong)alloc_xenheap_pages(order);
+    if (htab_raddr > 0) {
+        ASSERT((htab_raddr & (htab_bytes - 1)) == 0);
+
+        d->arch.htab.order = order;
+        d->arch.htab.log_num_ptes = log_htab_bytes - LOG_PTE_SIZE;
+        d->arch.htab.sdr1 = htab_calc_sdr1(htab_raddr, log_htab_bytes);
+        d->arch.htab.map = (union pte *)htab_raddr;
+    }
+    return htab_raddr;
+}
+
+static void htab_free(struct domain *d)
+{
+    ulong htab_raddr = GET_HTAB(d);
+
+    free_xenheap_pages((void *)htab_raddr, d->arch.htab.order);
+}
+
+
+unsigned int shadow_teardown(struct domain *d)
+{
+    htab_free(d);
+    return 0;
+}
+
+unsigned int shadow_set_allocation(struct domain *d, 
+                                    unsigned int megabytes,
+                                    int *preempted)
+{
+    unsigned int rc;
+    uint pages;
+    uint p;
+    uint order;
+    ulong addr;
+    
+
+    if (d->arch.htab.order)
+        return -EBUSY;
+
+    if (megabytes == 0) {
+        /* old management tools */
+        megabytes = 1;          /* 1/64th of 64M */
+        printk("%s: Fix management tools to set and get shadow/htab values\n"
+               "    using %d MiB htab\n",
+               __func__, megabytes);
+    }
+    pages = megabytes << (20 - PAGE_SHIFT);
+    order = fls(pages) - 1;     /* log2 truncated */
+    if (pages & ((1 << order) - 1))
+        ++order;                /* round up */
+
+    addr = htab_alloc(d, order);
+
+    printk("%s: ibm,fpt-size should be: 0x%x\n", __func__,
+           d->arch.htab.log_num_ptes + LOG_PTE_SIZE);
+
+    if (addr == 0)
+        return -ENOMEM;
+
+    /* XXX make this a continuation */
+    for (p = 0; p < (1 << order); p++)
+        clear_page((void *)(addr + (p << PAGE_SHIFT)));
+
+    return rc;
+}
+
 int shadow_control_op(struct domain *d, 
                       dom0_shadow_control_t *sc,
                       XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
@@ -36,17 +129,28 @@ int shadow_control_op(struct domain *d,
     switch ( sc->op )
     {
     case DOM0_SHADOW_CONTROL_OP_OFF:
+         DPRINTK("Shadow is mandatory!\n");
+         return -EINVAL;
+
+    case DOM0_SHADOW2_CONTROL_OP_GET_ALLOCATION:
+        sc->mb = shadow_get_allocation(d);
         return 0;
 
-    case DOM0_SHADOW2_CONTROL_OP_GET_ALLOCATION:
-        sc->mb = 0;
-        return 0;
-    case DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION:
-        if (sc->mb > 0) {
-            BUG();
-            return -ENOMEM;
-        }
-        return 0;
+    case DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION: {
+        int rc;
+        int preempted = 0;
+
+        rc = shadow_set_allocation(d, sc->mb, &preempted);
+
+        if (preempted)
+            /* Not finished.  Set up to re-run the call. */
+            rc = hypercall_create_continuation(
+                __HYPERVISOR_dom0_op, "h", u_dom0_op);
+        else 
+            /* Finished.  Return the new allocation */
+            sc->mb = shadow_get_allocation(d);
+        return rc;
+    }
 
     default:
         printk("Bad shadow op %u\n", sc->op);
diff -r f8233165fb80 -r 1811cc5022fb xen/include/asm-powerpc/htab.h
--- a/xen/include/asm-powerpc/htab.h    Sun Aug 27 16:12:00 2006 -0400
+++ b/xen/include/asm-powerpc/htab.h    Sun Aug 27 20:48:06 2006 -0400
@@ -133,8 +133,4 @@ struct domain_htab {
     union pte *map;     /* access the htab like an array */
     ulong *shadow;      /* idx -> logical translation array */
 };
-
-struct domain;
-extern void htab_alloc(struct domain *d, uint order);
-extern void htab_free(struct domain *d);
 #endif
diff -r f8233165fb80 -r 1811cc5022fb xen/include/asm-powerpc/shadow.h
--- a/xen/include/asm-powerpc/shadow.h  Sun Aug 27 16:12:00 2006 -0400
+++ b/xen/include/asm-powerpc/shadow.h  Sun Aug 27 20:48:06 2006 -0400
@@ -60,4 +60,13 @@ extern int shadow_control_op(struct doma
 extern int shadow_control_op(struct domain *d, 
                              dom0_shadow_control_t *sc,
                              XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op);
+extern unsigned int shadow_teardown(struct domain *d);
+extern unsigned int shadow_set_allocation(
+    struct domain *d, unsigned int megabytes, int *preempted);
+
+/* Return the size of the shadow2 pool, rounded up to the nearest MB */
+static inline unsigned int shadow_get_allocation(struct domain *d)
+{
+    return (1ULL << (d->arch.htab.order + PAGE_SHIFT)) >> 20;
+}
 #endif
diff -r f8233165fb80 -r 1811cc5022fb xen/arch/powerpc/htab.c
--- a/xen/arch/powerpc/htab.c   Sun Aug 27 16:12:00 2006 -0400
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Copyright (C) IBM Corp. 2005
- *
- * Authors: Hollis Blanchard <[EMAIL PROTECTED]>
- */
-
-#include <xen/config.h>
-#include <xen/sched.h>
-
-static ulong htab_calc_sdr1(ulong htab_addr, ulong log_htab_size)
-{
-    ulong sdr1_htabsize;
-
-    ASSERT((htab_addr & ((1UL << log_htab_size) - 1)) == 0);
-    ASSERT(log_htab_size <= SDR1_HTABSIZE_MAX);
-    ASSERT(log_htab_size >= HTAB_MIN_LOG_SIZE);
-
-    sdr1_htabsize = log_htab_size - LOG_PTEG_SIZE - SDR1_HTABSIZE_BASEBITS;
-
-    return (htab_addr | (sdr1_htabsize & SDR1_HTABSIZE_MASK));
-}
-
-void htab_alloc(struct domain *d, uint order)
-{
-    ulong htab_raddr;
-    ulong log_htab_bytes = order + PAGE_SHIFT;
-    ulong htab_bytes = 1UL << log_htab_bytes;
-
-    /* XXX use alloc_domheap_pages instead? */
-    htab_raddr = (ulong)alloc_xenheap_pages(order);
-    ASSERT(htab_raddr != 0);
-    /* XXX check alignment guarantees */
-    ASSERT((htab_raddr & (htab_bytes - 1)) == 0);
-
-    /* XXX slow. move memset out to service partition? */
-    memset((void *)htab_raddr, 0, htab_bytes);
-
-    d->arch.htab.order = order;
-    d->arch.htab.log_num_ptes = log_htab_bytes - LOG_PTE_SIZE;
-    d->arch.htab.sdr1 = htab_calc_sdr1(htab_raddr, log_htab_bytes);
-    d->arch.htab.map = (union pte *)htab_raddr;
-    d->arch.htab.shadow = xmalloc_array(ulong,
-                                        1UL << d->arch.htab.log_num_ptes);
-    ASSERT(d->arch.htab.shadow != NULL);
-}
-
-void htab_free(struct domain *d)
-{
-    ulong htab_raddr = GET_HTAB(d);
-
-    free_xenheap_pages((void *)htab_raddr, d->arch.htab.order);
-    xfree(d->arch.htab.shadow);
-}
-

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to