ia64/xen-unstable

view xen/arch/powerpc/shadow.c @ 11386:91fd23533210

[XEN][POWERPC] correct HTAB allocation typo
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 Mon Aug 28 11:52:17 2006 -0400 (2006-08-28)
parents e07281779b88
children 18ce855ff594
line source
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright (C) IBM Corp. 2006
17 *
18 * Authors: Jimi Xenidis <jimix@watson.ibm.com>
19 */
21 #include <xen/config.h>
22 #include <xen/types.h>
23 #include <xen/shadow.h>
24 #include <public/dom0_ops.h>
26 static ulong htab_calc_sdr1(ulong htab_addr, ulong log_htab_size)
27 {
28 ulong sdr1_htabsize;
30 ASSERT((htab_addr & ((1UL << log_htab_size) - 1)) == 0);
31 ASSERT(log_htab_size <= SDR1_HTABSIZE_MAX);
32 ASSERT(log_htab_size >= HTAB_MIN_LOG_SIZE);
34 sdr1_htabsize = log_htab_size - LOG_PTEG_SIZE - SDR1_HTABSIZE_BASEBITS;
36 return (htab_addr | (sdr1_htabsize & SDR1_HTABSIZE_MASK));
37 }
39 static ulong htab_alloc(struct domain *d, uint order)
40 {
41 ulong htab_raddr;
42 uint log_htab_bytes = order + PAGE_SHIFT;
43 uint htab_bytes = 1UL << log_htab_bytes;
45 /* we use xenheap pages to keep domheap pages usefull for domains */
47 if (order < 6)
48 order = 6; /* architectural minimum is 2^18 */
49 if (order > 34)
50 order = 34; /* architectural minimum is 2^46 */
52 htab_raddr = (ulong)alloc_xenheap_pages(order);
53 if (htab_raddr > 0) {
54 ASSERT((htab_raddr & (htab_bytes - 1)) == 0);
56 d->arch.htab.order = order;
57 d->arch.htab.log_num_ptes = log_htab_bytes - LOG_PTE_SIZE;
58 d->arch.htab.sdr1 = htab_calc_sdr1(htab_raddr, log_htab_bytes);
59 d->arch.htab.map = (union pte *)htab_raddr;
60 }
61 return htab_raddr;
62 }
64 static void htab_free(struct domain *d)
65 {
66 ulong htab_raddr = GET_HTAB(d);
68 free_xenheap_pages((void *)htab_raddr, d->arch.htab.order);
69 }
72 unsigned int shadow_teardown(struct domain *d)
73 {
74 htab_free(d);
75 return 0;
76 }
78 unsigned int shadow_set_allocation(struct domain *d,
79 unsigned int megabytes,
80 int *preempted)
81 {
82 unsigned int rc;
83 uint pages;
84 uint p;
85 uint order;
86 ulong addr;
89 if (d->arch.htab.order)
90 return -EBUSY;
92 if (megabytes == 0) {
93 /* old management tools */
94 megabytes = 1; /* 1/64th of 64M */
95 printk("%s: Fix management tools to set and get shadow/htab values\n"
96 " using %d MiB htab\n",
97 __func__, megabytes);
98 }
99 pages = megabytes << (20 - PAGE_SHIFT);
100 order = fls(pages) - 1; /* log2 truncated */
101 if (pages & ((1 << order) - 1))
102 ++order; /* round up */
104 addr = htab_alloc(d, order);
106 printk("%s: ibm,fpt-size should be: 0x%x\n", __func__,
107 d->arch.htab.log_num_ptes + LOG_PTE_SIZE);
109 if (addr == 0)
110 return -ENOMEM;
112 /* XXX make this a continuation */
113 for (p = 0; p < (1 << order); p++)
114 clear_page((void *)(addr + (p << PAGE_SHIFT)));
116 return rc;
117 }
119 int shadow_control_op(struct domain *d,
120 dom0_shadow_control_t *sc,
121 XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
122 {
123 if ( unlikely(d == current->domain) )
124 {
125 DPRINTK("Don't try to do a shadow op on yourself!\n");
126 return -EINVAL;
127 }
129 switch ( sc->op )
130 {
131 case DOM0_SHADOW_CONTROL_OP_OFF:
132 DPRINTK("Shadow is mandatory!\n");
133 return -EINVAL;
135 case DOM0_SHADOW2_CONTROL_OP_GET_ALLOCATION:
136 sc->mb = shadow_get_allocation(d);
137 return 0;
139 case DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION: {
140 int rc;
141 int preempted = 0;
143 rc = shadow_set_allocation(d, sc->mb, &preempted);
145 if (preempted)
146 /* Not finished. Set up to re-run the call. */
147 rc = hypercall_create_continuation(
148 __HYPERVISOR_dom0_op, "h", u_dom0_op);
149 else
150 /* Finished. Return the new allocation */
151 sc->mb = shadow_get_allocation(d);
152 return rc;
153 }
155 default:
156 printk("Bad shadow op %u\n", sc->op);
157 BUG();
158 return -EINVAL;
159 }
160 }