ia64/xen-unstable

view tools/libxc/ia64/xc_ia64_stubs.c @ 19848:5839491bbf20

[IA64] replace MAX_VCPUS with d->max_vcpus where necessary.

don't use MAX_VCPUS, and use vcpu::max_vcpus.
The changeset of 2f9e1348aa98 introduced max_vcpus to allow more vcpus
per guest. This patch is ia64 counter part.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 11:26:05 2009 +0900 (2009-06-29)
parents e02974a95872
children
line source
1 #include "xg_private.h"
2 #include "xc_efi.h"
3 #include "xc_ia64.h"
5 /* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is
6 * mysteriously declared in two places: /usr/include/asm/fpu.h and
7 * /usr/include/bits/sigcontext.h. The former also defines FPSR_DEFAULT,
8 * the latter doesn't but is included (indirectly) by xg_private.h */
9 #define __ASSEMBLY__
10 #include <asm/fpu.h>
11 #undef __IA64_UL
12 #define __IA64_UL(x) ((unsigned long)(x))
13 #undef __ASSEMBLY__
15 unsigned long
16 xc_ia64_fpsr_default(void)
17 {
18 return FPSR_DEFAULT;
19 }
21 static int
22 xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf,
23 unsigned int start_page, unsigned int nr_pages)
24 {
25 DECLARE_DOMCTL;
26 int ret;
28 domctl.cmd = XEN_DOMCTL_getmemlist;
29 domctl.domain = (domid_t)domid;
30 domctl.u.getmemlist.max_pfns = nr_pages;
31 domctl.u.getmemlist.start_pfn = start_page;
32 domctl.u.getmemlist.num_pfns = 0;
33 set_xen_guest_handle(domctl.u.getmemlist.buffer, pfn_buf);
35 if (lock_pages(pfn_buf, nr_pages * sizeof(xen_pfn_t)) != 0) {
36 PERROR("Could not lock pfn list buffer");
37 return -1;
38 }
39 ret = do_domctl(xc_handle, &domctl);
40 unlock_pages(pfn_buf, nr_pages * sizeof(xen_pfn_t));
42 return ret < 0 ? -1 : nr_pages;
43 }
45 int
46 xc_get_pfn_list(int xc_handle, uint32_t domid, uint64_t *pfn_buf,
47 unsigned long max_pfns)
48 {
49 return xc_ia64_get_pfn_list(xc_handle, domid, (xen_pfn_t *)pfn_buf,
50 0, max_pfns);
51 }
53 long
54 xc_get_max_pages(int xc_handle, uint32_t domid)
55 {
56 struct xen_domctl domctl;
57 domctl.cmd = XEN_DOMCTL_getdomaininfo;
58 domctl.domain = (domid_t)domid;
59 return ((do_domctl(xc_handle, &domctl) < 0)
60 ? -1 : domctl.u.getdomaininfo.max_pages);
61 }
63 /* It is possible to get memmap_info and memmap by
64 foreign domain page mapping. But it's racy. Use hypercall to avoid race. */
65 static int
66 xc_ia64_get_memmap(int xc_handle,
67 uint32_t domid, char *buf, unsigned long bufsize)
68 {
69 privcmd_hypercall_t hypercall;
70 int ret;
72 hypercall.op = __HYPERVISOR_ia64_dom0vp_op;
73 hypercall.arg[0] = IA64_DOM0VP_get_memmap;
74 hypercall.arg[1] = domid;
75 hypercall.arg[2] = (unsigned long)buf;
76 hypercall.arg[3] = bufsize;
77 hypercall.arg[4] = 0;
79 if (lock_pages(buf, bufsize) != 0)
80 return -1;
81 ret = do_xen_hypercall(xc_handle, &hypercall);
82 unlock_pages(buf, bufsize);
83 return ret;
84 }
86 int
87 xc_ia64_copy_memmap(int xc_handle, uint32_t domid, shared_info_t *live_shinfo,
88 xen_ia64_memmap_info_t **memmap_info_p,
89 unsigned long *memmap_info_num_pages_p)
90 {
91 unsigned long gpfn_max_prev;
92 unsigned long gpfn_max_post;
94 unsigned long num_pages;
95 unsigned long num_pages_post;
96 unsigned long memmap_size;
97 xen_ia64_memmap_info_t *memmap_info;
99 int ret;
101 gpfn_max_prev = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid);
102 if (gpfn_max_prev < 0)
103 return -1;
105 again:
106 num_pages = live_shinfo->arch.memmap_info_num_pages;
107 if (num_pages == 0) {
108 ERROR("num_pages 0x%x", num_pages);
109 return -1;
110 }
112 memmap_size = num_pages << PAGE_SHIFT;
113 memmap_info = malloc(memmap_size);
114 if (memmap_info == NULL)
115 return -1;
116 ret = xc_ia64_get_memmap(xc_handle,
117 domid, (char*)memmap_info, memmap_size);
118 if (ret != 0) {
119 free(memmap_info);
120 return -1;
121 }
122 xen_rmb();
123 num_pages_post = live_shinfo->arch.memmap_info_num_pages;
124 if (num_pages != num_pages_post) {
125 free(memmap_info);
126 num_pages = num_pages_post;
127 goto again;
128 }
130 gpfn_max_post = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid);
131 if (gpfn_max_prev < 0) {
132 free(memmap_info);
133 return -1;
134 }
135 if (gpfn_max_post > gpfn_max_prev) {
136 free(memmap_info);
137 gpfn_max_prev = gpfn_max_post;
138 goto again;
139 }
141 /* reject unknown memmap */
142 if (memmap_info->efi_memdesc_size != sizeof(efi_memory_desc_t) ||
143 (memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size) == 0 ||
144 memmap_info->efi_memmap_size >
145 (num_pages << PAGE_SHIFT) - sizeof(memmap_info) ||
146 memmap_info->efi_memdesc_version != EFI_MEMORY_DESCRIPTOR_VERSION) {
147 PERROR("unknown memmap header. defaulting to compat mode.");
148 free(memmap_info);
149 return -1;
150 }
152 *memmap_info_p = memmap_info;
153 if (memmap_info_num_pages_p != NULL)
154 *memmap_info_num_pages_p = num_pages;
156 return 0;
157 }
159 /*
160 * XXX from xen/include/asm-ia64/linux-xen/asm/pgtable.h
161 * Should PTRS_PER_PTE be exported by arch-ia64.h?
162 */
163 #define PTRS_PER_PTE (1UL << (PAGE_SHIFT - 3))
165 static void*
166 xc_ia64_map_foreign_p2m(int xc_handle, uint32_t dom,
167 struct xen_ia64_memmap_info *memmap_info,
168 unsigned long flags, unsigned long *p2m_size_p)
169 {
170 unsigned long gpfn_max;
171 unsigned long p2m_size;
172 void *addr;
173 privcmd_hypercall_t hypercall;
174 int ret;
175 int saved_errno;
177 gpfn_max = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom);
178 if (gpfn_max < 0)
179 return NULL;
180 p2m_size =
181 (((gpfn_max + 1) + PTRS_PER_PTE - 1) / PTRS_PER_PTE) << PAGE_SHIFT;
182 addr = mmap(NULL, p2m_size, PROT_READ, MAP_SHARED, xc_handle, 0);
183 if (addr == MAP_FAILED)
184 return NULL;
186 hypercall.op = __HYPERVISOR_ia64_dom0vp_op;
187 hypercall.arg[0] = IA64_DOM0VP_expose_foreign_p2m;
188 hypercall.arg[1] = (unsigned long)addr;
189 hypercall.arg[2] = dom;
190 hypercall.arg[3] = (unsigned long)memmap_info;
191 hypercall.arg[4] = flags;
193 if (lock_pages(memmap_info,
194 sizeof(*memmap_info) + memmap_info->efi_memmap_size) != 0) {
195 saved_errno = errno;
196 munmap(addr, p2m_size);
197 errno = saved_errno;
198 return NULL;
199 }
200 ret = do_xen_hypercall(xc_handle, &hypercall);
201 saved_errno = errno;
202 unlock_pages(memmap_info,
203 sizeof(*memmap_info) + memmap_info->efi_memmap_size);
204 if (ret < 0) {
205 munmap(addr, p2m_size);
206 errno = saved_errno;
207 return NULL;
208 }
210 *p2m_size_p = p2m_size;
211 return addr;
212 }
214 void
215 xc_ia64_p2m_init(struct xen_ia64_p2m_table *p2m_table)
216 {
217 p2m_table->size = 0;
218 p2m_table->p2m = NULL;
219 }
221 int
222 xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, int xc_handle,
223 uint32_t domid, struct xen_ia64_memmap_info *memmap_info,
224 unsigned long flag)
225 {
226 p2m_table->p2m = xc_ia64_map_foreign_p2m(xc_handle, domid, memmap_info,
227 flag, &p2m_table->size);
228 if (p2m_table->p2m == NULL) {
229 PERROR("Could not map foreign p2m. falling back to old method");
230 return -1;
231 }
232 return 0;
233 }
235 void
236 xc_ia64_p2m_unmap(struct xen_ia64_p2m_table *p2m_table)
237 {
238 if (p2m_table->p2m == NULL)
239 return;
240 munmap(p2m_table->p2m, p2m_table->size);
241 //p2m_table->p2m = NULL;
242 //p2m_table->size = 0;
243 }
245 /*
246 * XXX from xen/include/asm-ia64/linux-xen/asm/pgtable.h
247 * Should those be exported by arch-ia64.h?
248 */
249 #define _PAGE_P_BIT 0
250 #define _PAGE_P (1UL << _PAGE_P_BIT) /* page present bit */
251 #define _PAGE_PGC_ALLOCATED_BIT 59 /* _PGC_allocated */
252 #define _PAGE_PGC_ALLOCATED (1UL << _PAGE_PGC_ALLOCATED_BIT)
253 #define _PAGE_IO_BIT 60
254 #define _PAGE_IO (1UL << _PAGE_IO_BIT)
256 #define IA64_MAX_PHYS_BITS 50 /* max. number of physical address bits (architected) */
257 #define _PAGE_PPN_MASK (((1UL << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL)
259 int
260 xc_ia64_p2m_present(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
261 {
262 if (sizeof(p2m_table->p2m[0]) * gpfn < p2m_table->size) {
263 unsigned long pte = p2m_table->p2m[gpfn];
264 return !!((pte & _PAGE_P) && !(pte & _PAGE_IO));
265 }
266 return 0;
267 }
269 int
270 xc_ia64_p2m_allocated(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
271 {
272 if (sizeof(p2m_table->p2m[0]) * gpfn < p2m_table->size) {
273 unsigned long pte = p2m_table->p2m[gpfn];
274 return !!((pte & _PAGE_P) && (pte & _PAGE_PGC_ALLOCATED) &&
275 !(pte & _PAGE_IO));
276 }
277 return 0;
278 }
280 unsigned long
281 xc_ia64_p2m_mfn(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
282 {
283 unsigned long pte;
285 if (sizeof(p2m_table->p2m[0]) * gpfn >= p2m_table->size)
286 return INVALID_MFN;
287 pte = p2m_table->p2m[gpfn];
288 if (pte & _PAGE_IO)
289 return INVALID_MFN;
290 if (!(pte & _PAGE_P))
291 return INVALID_MFN;
292 return (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT;
293 }
295 /*
296 * Local variables:
297 * mode: C
298 * c-set-style: "BSD"
299 * c-basic-offset: 4
300 * tab-width: 4
301 * indent-tabs-mode: nil
302 * End:
303 */