ia64/xen-unstable

changeset 11385:e07281779b88

[XEN][POWERPC] 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 <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Sun Aug 27 20:48:06 2006 -0400 (2006-08-27)
parents bc349d862a5d
children 91fd23533210
files xen/arch/powerpc/Makefile xen/arch/powerpc/domain.c xen/arch/powerpc/domain_build.c xen/arch/powerpc/htab.c xen/arch/powerpc/shadow.c xen/include/asm-powerpc/htab.h xen/include/asm-powerpc/shadow.h
line diff
     1.1 --- a/xen/arch/powerpc/Makefile	Sun Aug 27 16:12:00 2006 -0400
     1.2 +++ b/xen/arch/powerpc/Makefile	Sun Aug 27 20:48:06 2006 -0400
     1.3 @@ -20,7 +20,6 @@ obj-y += exceptions.o
     1.4  obj-y += external.o
     1.5  obj-y += float.o
     1.6  obj-y += hcalls.o
     1.7 -obj-y += htab.o
     1.8  obj-y += iommu.o
     1.9  obj-y += irq.o
    1.10  obj-y += mambo.o
     2.1 --- a/xen/arch/powerpc/domain.c	Sun Aug 27 16:12:00 2006 -0400
     2.2 +++ b/xen/arch/powerpc/domain.c	Sun Aug 27 20:48:06 2006 -0400
     2.3 @@ -27,6 +27,7 @@
     2.4  #include <xen/domain.h>
     2.5  #include <xen/console.h>
     2.6  #include <xen/shutdown.h>
     2.7 +#include <xen/shadow.h>
     2.8  #include <xen/mm.h>
     2.9  #include <asm/htab.h>
    2.10  #include <asm/current.h>
    2.11 @@ -77,7 +78,6 @@ int arch_domain_create(struct domain *d)
    2.12      unsigned long rma_base;
    2.13      unsigned long rma_sz;
    2.14      uint rma_order_pages;
    2.15 -    uint htab_order_pages;
    2.16      int rc;
    2.17  
    2.18      if (d->domain_id == IDLE_DOMAIN_ID) {
    2.19 @@ -104,16 +104,6 @@ int arch_domain_create(struct domain *d)
    2.20      d->arch.large_page_sizes = cpu_large_page_orders(
    2.21          d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order));
    2.22  
    2.23 -    /* FIXME: we need to the the maximum addressible memory for this
    2.24 -     * domain to calculate this correctly. It should probably be set
    2.25 -     * by the managment tools */
    2.26 -    htab_order_pages = rma_order_pages - 6; /* (1/64) */
    2.27 -    if (test_bit(_DOMF_privileged, &d->domain_flags)) {
    2.28 -        /* bump the htab size of privleged domains */
    2.29 -        ++htab_order_pages;
    2.30 -    }
    2.31 -    htab_alloc(d, htab_order_pages);
    2.32 -
    2.33      INIT_LIST_HEAD(&d->arch.extent_list);
    2.34  
    2.35      return 0;
    2.36 @@ -121,7 +111,7 @@ int arch_domain_create(struct domain *d)
    2.37  
    2.38  void arch_domain_destroy(struct domain *d)
    2.39  {
    2.40 -    htab_free(d);
    2.41 +    shadow_teardown(d);
    2.42  }
    2.43  
    2.44  void machine_halt(void)
    2.45 @@ -163,6 +153,16 @@ int arch_set_info_guest(struct vcpu *v, 
    2.46  { 
    2.47      memcpy(&v->arch.ctxt, &c->user_regs, sizeof(c->user_regs));
    2.48  
    2.49 +    printf("Domain[%d].%d: initializing\n",
    2.50 +           v->domain->domain_id, v->vcpu_id);
    2.51 +
    2.52 +    if (v->domain->arch.htab.order == 0)
    2.53 +        panic("Page table never allocated for Domain: %d\n",
    2.54 +              v->domain->domain_id);
    2.55 +    if (v->domain->arch.rma_order == 0)
    2.56 +        panic("RMA never allocated for Domain: %d\n",
    2.57 +              v->domain->domain_id);
    2.58 +
    2.59      set_bit(_VCPUF_initialised, &v->vcpu_flags);
    2.60  
    2.61      cpu_init_vcpu(v);
    2.62 @@ -253,12 +253,13 @@ void context_switch(struct vcpu *prev, s
    2.63  void continue_running(struct vcpu *same)
    2.64  {
    2.65      /* nothing to do */
    2.66 +    return;
    2.67  }
    2.68  
    2.69  void sync_vcpu_execstate(struct vcpu *v)
    2.70  {
    2.71 -    /* XXX for now, for domain destruction, make this non-fatal */
    2.72 -    printf("%s: called\n", __func__);
    2.73 +    /* do nothing */
    2.74 +    return;
    2.75  }
    2.76  
    2.77  void domain_relinquish_resources(struct domain *d)
     3.1 --- a/xen/arch/powerpc/domain_build.c	Sun Aug 27 16:12:00 2006 -0400
     3.2 +++ b/xen/arch/powerpc/domain_build.c	Sun Aug 27 20:48:06 2006 -0400
     3.3 @@ -25,13 +25,12 @@
     3.4  #include <xen/init.h>
     3.5  #include <xen/ctype.h>
     3.6  #include <xen/iocap.h>
     3.7 +#include <xen/shadow.h>
     3.8  #include <xen/version.h>
     3.9  #include <asm/processor.h>
    3.10  #include <asm/papr.h>
    3.11  #include "oftree.h"
    3.12  
    3.13 -#define log2(x) ffz(~(x))
    3.14 -
    3.15  extern int parseelfimage_32(struct domain_setup_info *dsi);
    3.16  extern int loadelfimage_32(struct domain_setup_info *dsi);
    3.17  
    3.18 @@ -114,10 +113,10 @@ int construct_dom0(struct domain *d,
    3.19      uint rma_nrpages = 1 << d->arch.rma_order;
    3.20      ulong rma_sz = rma_size(d->arch.rma_order);
    3.21      ulong rma = page_to_maddr(d->arch.rma_page);
    3.22 -    uint htab_order;
    3.23      start_info_t *si;
    3.24      ulong eomem;
    3.25      int am64 = 1;
    3.26 +    int preempt = 0;
    3.27      ulong msr;
    3.28      ulong pc;
    3.29      ulong r2;
    3.30 @@ -170,21 +169,20 @@ int construct_dom0(struct domain *d,
    3.31          dom0_nrpages = allocate_extents(d, dom0_nrpages, rma_nrpages);
    3.32  
    3.33      d->tot_pages = dom0_nrpages;
    3.34 -    ASSERT(d->tot_pages > 0);
    3.35 -    
    3.36 -    htab_order = log2(d->tot_pages) - 6;
    3.37 -    if (d->arch.htab.order > 0) {
    3.38 -        /* we incorrectly allocate this too early so lets adjust if
    3.39 -         * necessary */
    3.40 -        printk("WARNING: htab allocated to early\n");
    3.41 -        if (d->arch.htab.order < htab_order) {
    3.42 -            printk("WARNING: htab reallocated for more memory: 0x%x\n",
    3.43 -                htab_order);
    3.44 -            htab_free(d);
    3.45 -            htab_alloc(d, htab_order);
    3.46 -        }
    3.47 +    ASSERT(d->tot_pages >= rma_nrpages);
    3.48 +
    3.49 +    if (opt_dom0_shadow == 0) {
    3.50 +        /* 1/64 of memory  */
    3.51 +        opt_dom0_shadow = (d->tot_pages >> 6) >> (20 - PAGE_SHIFT);
    3.52      }
    3.53  
    3.54 +    do {
    3.55 +        shadow_set_allocation(d, opt_dom0_shadow, &preempt);
    3.56 +    } while (preempt);
    3.57 +    if (shadow_get_allocation(d) == 0)
    3.58 +        panic("shadow allocation failed 0x%x < 0x%x\n",
    3.59 +              shadow_get_allocation(d), opt_dom0_shadow);
    3.60 +
    3.61      ASSERT( image_len < rma_sz );
    3.62  
    3.63      si = (start_info_t *)(rma_addr(&d->arch, RMA_START_INFO) + rma);
     4.1 --- a/xen/arch/powerpc/htab.c	Sun Aug 27 16:12:00 2006 -0400
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,68 +0,0 @@
     4.4 -/*
     4.5 - * This program is free software; you can redistribute it and/or modify
     4.6 - * it under the terms of the GNU General Public License as published by
     4.7 - * the Free Software Foundation; either version 2 of the License, or
     4.8 - * (at your option) any later version.
     4.9 - *
    4.10 - * This program is distributed in the hope that it will be useful,
    4.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.13 - * GNU General Public License for more details.
    4.14 - *
    4.15 - * You should have received a copy of the GNU General Public License
    4.16 - * along with this program; if not, write to the Free Software
    4.17 - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    4.18 - *
    4.19 - * Copyright (C) IBM Corp. 2005
    4.20 - *
    4.21 - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
    4.22 - */
    4.23 -
    4.24 -#include <xen/config.h>
    4.25 -#include <xen/sched.h>
    4.26 -
    4.27 -static ulong htab_calc_sdr1(ulong htab_addr, ulong log_htab_size)
    4.28 -{
    4.29 -    ulong sdr1_htabsize;
    4.30 -
    4.31 -    ASSERT((htab_addr & ((1UL << log_htab_size) - 1)) == 0);
    4.32 -    ASSERT(log_htab_size <= SDR1_HTABSIZE_MAX);
    4.33 -    ASSERT(log_htab_size >= HTAB_MIN_LOG_SIZE);
    4.34 -
    4.35 -    sdr1_htabsize = log_htab_size - LOG_PTEG_SIZE - SDR1_HTABSIZE_BASEBITS;
    4.36 -
    4.37 -    return (htab_addr | (sdr1_htabsize & SDR1_HTABSIZE_MASK));
    4.38 -}
    4.39 -
    4.40 -void htab_alloc(struct domain *d, uint order)
    4.41 -{
    4.42 -    ulong htab_raddr;
    4.43 -    ulong log_htab_bytes = order + PAGE_SHIFT;
    4.44 -    ulong htab_bytes = 1UL << log_htab_bytes;
    4.45 -
    4.46 -    /* XXX use alloc_domheap_pages instead? */
    4.47 -    htab_raddr = (ulong)alloc_xenheap_pages(order);
    4.48 -    ASSERT(htab_raddr != 0);
    4.49 -    /* XXX check alignment guarantees */
    4.50 -    ASSERT((htab_raddr & (htab_bytes - 1)) == 0);
    4.51 -
    4.52 -    /* XXX slow. move memset out to service partition? */
    4.53 -    memset((void *)htab_raddr, 0, htab_bytes);
    4.54 -
    4.55 -    d->arch.htab.order = order;
    4.56 -    d->arch.htab.log_num_ptes = log_htab_bytes - LOG_PTE_SIZE;
    4.57 -    d->arch.htab.sdr1 = htab_calc_sdr1(htab_raddr, log_htab_bytes);
    4.58 -    d->arch.htab.map = (union pte *)htab_raddr;
    4.59 -    d->arch.htab.shadow = xmalloc_array(ulong,
    4.60 -                                        1UL << d->arch.htab.log_num_ptes);
    4.61 -    ASSERT(d->arch.htab.shadow != NULL);
    4.62 -}
    4.63 -
    4.64 -void htab_free(struct domain *d)
    4.65 -{
    4.66 -    ulong htab_raddr = GET_HTAB(d);
    4.67 -
    4.68 -    free_xenheap_pages((void *)htab_raddr, d->arch.htab.order);
    4.69 -    xfree(d->arch.htab.shadow);
    4.70 -}
    4.71 -
     5.1 --- a/xen/arch/powerpc/shadow.c	Sun Aug 27 16:12:00 2006 -0400
     5.2 +++ b/xen/arch/powerpc/shadow.c	Sun Aug 27 20:48:06 2006 -0400
     5.3 @@ -23,6 +23,99 @@
     5.4  #include <xen/shadow.h>
     5.5  #include <public/dom0_ops.h>
     5.6  
     5.7 +static ulong htab_calc_sdr1(ulong htab_addr, ulong log_htab_size)
     5.8 +{
     5.9 +    ulong sdr1_htabsize;
    5.10 +
    5.11 +    ASSERT((htab_addr & ((1UL << log_htab_size) - 1)) == 0);
    5.12 +    ASSERT(log_htab_size <= SDR1_HTABSIZE_MAX);
    5.13 +    ASSERT(log_htab_size >= HTAB_MIN_LOG_SIZE);
    5.14 +
    5.15 +    sdr1_htabsize = log_htab_size - LOG_PTEG_SIZE - SDR1_HTABSIZE_BASEBITS;
    5.16 +
    5.17 +    return (htab_addr | (sdr1_htabsize & SDR1_HTABSIZE_MASK));
    5.18 +}
    5.19 +
    5.20 +static ulong htab_alloc(struct domain *d, uint order)
    5.21 +{
    5.22 +    ulong htab_raddr;
    5.23 +    uint log_htab_bytes = order + PAGE_SHIFT;
    5.24 +    uint htab_bytes = 1UL << log_htab_bytes;
    5.25 +
    5.26 +    /* we use xenheap pages to keep domheap pages usefull for domains */
    5.27 +
    5.28 +    if (order < 6)
    5.29 +        order = 6;              /* architectural minimum is 2^18 */
    5.30 +    if (order < 34)
    5.31 +        order = 34;             /* architectural minimum is 2^46 */
    5.32 +
    5.33 +    htab_raddr = (ulong)alloc_xenheap_pages(order);
    5.34 +    if (htab_raddr > 0) {
    5.35 +        ASSERT((htab_raddr & (htab_bytes - 1)) == 0);
    5.36 +
    5.37 +        d->arch.htab.order = order;
    5.38 +        d->arch.htab.log_num_ptes = log_htab_bytes - LOG_PTE_SIZE;
    5.39 +        d->arch.htab.sdr1 = htab_calc_sdr1(htab_raddr, log_htab_bytes);
    5.40 +        d->arch.htab.map = (union pte *)htab_raddr;
    5.41 +    }
    5.42 +    return htab_raddr;
    5.43 +}
    5.44 +
    5.45 +static void htab_free(struct domain *d)
    5.46 +{
    5.47 +    ulong htab_raddr = GET_HTAB(d);
    5.48 +
    5.49 +    free_xenheap_pages((void *)htab_raddr, d->arch.htab.order);
    5.50 +}
    5.51 +
    5.52 +
    5.53 +unsigned int shadow_teardown(struct domain *d)
    5.54 +{
    5.55 +    htab_free(d);
    5.56 +    return 0;
    5.57 +}
    5.58 +
    5.59 +unsigned int shadow_set_allocation(struct domain *d, 
    5.60 +                                    unsigned int megabytes,
    5.61 +                                    int *preempted)
    5.62 +{
    5.63 +    unsigned int rc;
    5.64 +    uint pages;
    5.65 +    uint p;
    5.66 +    uint order;
    5.67 +    ulong addr;
    5.68 +    
    5.69 +
    5.70 +    if (d->arch.htab.order)
    5.71 +        return -EBUSY;
    5.72 +
    5.73 +    if (megabytes == 0) {
    5.74 +        /* old management tools */
    5.75 +        megabytes = 1;          /* 1/64th of 64M */
    5.76 +        printk("%s: Fix management tools to set and get shadow/htab values\n"
    5.77 +               "    using %d MiB htab\n",
    5.78 +               __func__, megabytes);
    5.79 +    }
    5.80 +    pages = megabytes << (20 - PAGE_SHIFT);
    5.81 +    order = fls(pages) - 1;     /* log2 truncated */
    5.82 +    if (pages & ((1 << order) - 1))
    5.83 +        ++order;                /* round up */
    5.84 +
    5.85 +    addr = htab_alloc(d, order);
    5.86 +
    5.87 +    printk("%s: ibm,fpt-size should be: 0x%x\n", __func__,
    5.88 +           d->arch.htab.log_num_ptes + LOG_PTE_SIZE);
    5.89 +
    5.90 +    if (addr == 0)
    5.91 +        return -ENOMEM;
    5.92 +
    5.93 +    /* XXX make this a continuation */
    5.94 +    for (p = 0; p < (1 << order); p++)
    5.95 +        clear_page((void *)(addr + (p << PAGE_SHIFT)));
    5.96 +
    5.97 +    return rc;
    5.98 +}
    5.99 +
   5.100  int shadow_control_op(struct domain *d, 
   5.101                        dom0_shadow_control_t *sc,
   5.102                        XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
   5.103 @@ -36,17 +129,28 @@ int shadow_control_op(struct domain *d,
   5.104      switch ( sc->op )
   5.105      {
   5.106      case DOM0_SHADOW_CONTROL_OP_OFF:
   5.107 -        return 0;
   5.108 +         DPRINTK("Shadow is mandatory!\n");
   5.109 +         return -EINVAL;
   5.110  
   5.111      case DOM0_SHADOW2_CONTROL_OP_GET_ALLOCATION:
   5.112 -        sc->mb = 0;
   5.113 +        sc->mb = shadow_get_allocation(d);
   5.114          return 0;
   5.115 -    case DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION:
   5.116 -        if (sc->mb > 0) {
   5.117 -            BUG();
   5.118 -            return -ENOMEM;
   5.119 -        }
   5.120 -        return 0;
   5.121 +
   5.122 +    case DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION: {
   5.123 +        int rc;
   5.124 +        int preempted = 0;
   5.125 +
   5.126 +        rc = shadow_set_allocation(d, sc->mb, &preempted);
   5.127 +
   5.128 +        if (preempted)
   5.129 +            /* Not finished.  Set up to re-run the call. */
   5.130 +            rc = hypercall_create_continuation(
   5.131 +                __HYPERVISOR_dom0_op, "h", u_dom0_op);
   5.132 +        else 
   5.133 +            /* Finished.  Return the new allocation */
   5.134 +            sc->mb = shadow_get_allocation(d);
   5.135 +        return rc;
   5.136 +    }
   5.137  
   5.138      default:
   5.139          printk("Bad shadow op %u\n", sc->op);
     6.1 --- a/xen/include/asm-powerpc/htab.h	Sun Aug 27 16:12:00 2006 -0400
     6.2 +++ b/xen/include/asm-powerpc/htab.h	Sun Aug 27 20:48:06 2006 -0400
     6.3 @@ -133,8 +133,4 @@ struct domain_htab {
     6.4      union pte *map;     /* access the htab like an array */
     6.5      ulong *shadow;      /* idx -> logical translation array */
     6.6  };
     6.7 -
     6.8 -struct domain;
     6.9 -extern void htab_alloc(struct domain *d, uint order);
    6.10 -extern void htab_free(struct domain *d);
    6.11  #endif
     7.1 --- a/xen/include/asm-powerpc/shadow.h	Sun Aug 27 16:12:00 2006 -0400
     7.2 +++ b/xen/include/asm-powerpc/shadow.h	Sun Aug 27 20:48:06 2006 -0400
     7.3 @@ -60,4 +60,13 @@ static inline void mark_dirty(struct dom
     7.4  extern int shadow_control_op(struct domain *d, 
     7.5                               dom0_shadow_control_t *sc,
     7.6                               XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op);
     7.7 +extern unsigned int shadow_teardown(struct domain *d);
     7.8 +extern unsigned int shadow_set_allocation(
     7.9 +    struct domain *d, unsigned int megabytes, int *preempted);
    7.10 +
    7.11 +/* Return the size of the shadow2 pool, rounded up to the nearest MB */
    7.12 +static inline unsigned int shadow_get_allocation(struct domain *d)
    7.13 +{
    7.14 +    return (1ULL << (d->arch.htab.order + PAGE_SHIFT)) >> 20;
    7.15 +}
    7.16  #endif