ia64/xen-unstable

view xen/arch/x86/domctl.c @ 12215:46fad06ab0b3

[XEN] Fix x86/64 build.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Nov 01 18:48:57 2006 +0000 (2006-11-01)
parents cf3d69ba5633
children cfb1136ee8f7
line source
1 /******************************************************************************
2 * Arch-specific domctl.c
3 *
4 * Copyright (c) 2002-2006, K A Fraser
5 */
7 #include <xen/config.h>
8 #include <xen/types.h>
9 #include <xen/lib.h>
10 #include <xen/mm.h>
11 #include <xen/guest_access.h>
12 #include <public/domctl.h>
13 #include <xen/sched.h>
14 #include <xen/event.h>
15 #include <xen/domain_page.h>
16 #include <asm/msr.h>
17 #include <xen/trace.h>
18 #include <xen/console.h>
19 #include <xen/iocap.h>
20 #include <asm/shadow.h>
21 #include <asm/irq.h>
22 #include <asm/hvm/hvm.h>
23 #include <asm/hvm/support.h>
24 #include <asm/processor.h>
25 #include <public/hvm/e820.h>
27 long arch_do_domctl(
28 struct xen_domctl *domctl,
29 XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
30 {
31 long ret = 0;
33 switch ( domctl->cmd )
34 {
36 case XEN_DOMCTL_shadow_op:
37 {
38 struct domain *d;
39 ret = -ESRCH;
40 d = find_domain_by_id(domctl->domain);
41 if ( d != NULL )
42 {
43 ret = shadow_domctl(d, &domctl->u.shadow_op, u_domctl);
44 put_domain(d);
45 copy_to_guest(u_domctl, domctl, 1);
46 }
47 }
48 break;
50 case XEN_DOMCTL_ioport_permission:
51 {
52 struct domain *d;
53 unsigned int fp = domctl->u.ioport_permission.first_port;
54 unsigned int np = domctl->u.ioport_permission.nr_ports;
56 ret = -EINVAL;
57 if ( (fp + np) > 65536 )
58 break;
60 ret = -ESRCH;
61 if ( unlikely((d = find_domain_by_id(domctl->domain)) == NULL) )
62 break;
64 if ( np == 0 )
65 ret = 0;
66 else if ( domctl->u.ioport_permission.allow_access )
67 ret = ioports_permit_access(d, fp, fp + np - 1);
68 else
69 ret = ioports_deny_access(d, fp, fp + np - 1);
71 put_domain(d);
72 }
73 break;
75 case XEN_DOMCTL_getpageframeinfo:
76 {
77 struct page_info *page;
78 unsigned long mfn = domctl->u.getpageframeinfo.gmfn;
79 domid_t dom = domctl->domain;
80 struct domain *d;
82 ret = -EINVAL;
84 if ( unlikely(!mfn_valid(mfn)) ||
85 unlikely((d = find_domain_by_id(dom)) == NULL) )
86 break;
88 page = mfn_to_page(mfn);
90 if ( likely(get_page(page, d)) )
91 {
92 ret = 0;
94 domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_NOTAB;
96 if ( (page->u.inuse.type_info & PGT_count_mask) != 0 )
97 {
98 switch ( page->u.inuse.type_info & PGT_type_mask )
99 {
100 case PGT_l1_page_table:
101 domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L1TAB;
102 break;
103 case PGT_l2_page_table:
104 domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L2TAB;
105 break;
106 case PGT_l3_page_table:
107 domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L3TAB;
108 break;
109 case PGT_l4_page_table:
110 domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L4TAB;
111 break;
112 }
113 }
115 put_page(page);
116 }
118 put_domain(d);
120 copy_to_guest(u_domctl, domctl, 1);
121 }
122 break;
124 case XEN_DOMCTL_getpageframeinfo2:
125 {
126 #define GPF2_BATCH (PAGE_SIZE / sizeof(long))
127 int n,j;
128 int num = domctl->u.getpageframeinfo2.num;
129 domid_t dom = domctl->domain;
130 struct domain *d;
131 unsigned long *l_arr;
132 ret = -ESRCH;
134 if ( unlikely((d = find_domain_by_id(dom)) == NULL) )
135 break;
137 if ( unlikely(num > 1024) )
138 {
139 ret = -E2BIG;
140 put_domain(d);
141 break;
142 }
144 l_arr = alloc_xenheap_page();
146 ret = 0;
147 for ( n = 0; n < num; )
148 {
149 int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n);
151 if ( copy_from_guest_offset(l_arr,
152 domctl->u.getpageframeinfo2.array,
153 n, k) )
154 {
155 ret = -EINVAL;
156 break;
157 }
159 for ( j = 0; j < k; j++ )
160 {
161 struct page_info *page;
162 unsigned long mfn = l_arr[j];
164 page = mfn_to_page(mfn);
166 if ( likely(mfn_valid(mfn) && get_page(page, d)) )
167 {
168 unsigned long type = 0;
170 switch( page->u.inuse.type_info & PGT_type_mask )
171 {
172 case PGT_l1_page_table:
173 type = XEN_DOMCTL_PFINFO_L1TAB;
174 break;
175 case PGT_l2_page_table:
176 type = XEN_DOMCTL_PFINFO_L2TAB;
177 break;
178 case PGT_l3_page_table:
179 type = XEN_DOMCTL_PFINFO_L3TAB;
180 break;
181 case PGT_l4_page_table:
182 type = XEN_DOMCTL_PFINFO_L4TAB;
183 break;
184 }
186 if ( page->u.inuse.type_info & PGT_pinned )
187 type |= XEN_DOMCTL_PFINFO_LPINTAB;
188 l_arr[j] |= type;
189 put_page(page);
190 }
191 else
192 l_arr[j] |= XEN_DOMCTL_PFINFO_XTAB;
194 }
196 if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array,
197 n, l_arr, k) )
198 {
199 ret = -EINVAL;
200 break;
201 }
203 n += k;
204 }
206 free_xenheap_page(l_arr);
208 put_domain(d);
209 }
210 break;
212 case XEN_DOMCTL_getmemlist:
213 {
214 int i;
215 struct domain *d = find_domain_by_id(domctl->domain);
216 unsigned long max_pfns = domctl->u.getmemlist.max_pfns;
217 unsigned long mfn;
218 struct list_head *list_ent;
220 ret = -EINVAL;
221 if ( d != NULL )
222 {
223 ret = 0;
225 spin_lock(&d->page_alloc_lock);
227 list_ent = d->page_list.next;
228 for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
229 {
230 mfn = page_to_mfn(list_entry(
231 list_ent, struct page_info, list));
232 if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
233 i, &mfn, 1) )
234 {
235 ret = -EFAULT;
236 break;
237 }
238 list_ent = mfn_to_page(mfn)->list.next;
239 }
241 spin_unlock(&d->page_alloc_lock);
243 domctl->u.getmemlist.num_pfns = i;
244 copy_to_guest(u_domctl, domctl, 1);
246 put_domain(d);
247 }
248 }
249 break;
251 case XEN_DOMCTL_hypercall_init:
252 {
253 struct domain *d = find_domain_by_id(domctl->domain);
254 unsigned long gmfn = domctl->u.hypercall_init.gmfn;
255 unsigned long mfn;
256 void *hypercall_page;
258 ret = -ESRCH;
259 if ( unlikely(d == NULL) )
260 break;
262 mfn = gmfn_to_mfn(d, gmfn);
264 ret = -EACCES;
265 if ( !mfn_valid(mfn) ||
266 !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
267 {
268 put_domain(d);
269 break;
270 }
272 ret = 0;
274 hypercall_page = map_domain_page(mfn);
275 hypercall_page_initialise(d, hypercall_page);
276 unmap_domain_page(hypercall_page);
278 put_page_and_type(mfn_to_page(mfn));
280 put_domain(d);
281 }
282 break;
284 default:
285 ret = -ENOSYS;
286 break;
287 }
289 return ret;
290 }
292 void arch_getdomaininfo_ctxt(
293 struct vcpu *v, struct vcpu_guest_context *c)
294 {
295 memcpy(c, &v->arch.guest_context, sizeof(*c));
297 if ( is_hvm_vcpu(v) )
298 {
299 hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg);
300 }
301 else
302 {
303 /* IOPL privileges are virtualised: merge back into returned eflags. */
304 BUG_ON((c->user_regs.eflags & EF_IOPL) != 0);
305 c->user_regs.eflags |= v->arch.iopl << 12;
306 }
308 c->flags = 0;
309 if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
310 c->flags |= VGCF_i387_valid;
311 if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
312 c->flags |= VGCF_in_kernel;
313 if ( is_hvm_vcpu(v) )
314 c->flags |= VGCF_hvm_guest;
316 c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
318 c->vm_assist = v->domain->vm_assist;
319 }
321 /*
322 * Local variables:
323 * mode: C
324 * c-set-style: "BSD"
325 * c-basic-offset: 4
326 * tab-width: 4
327 * indent-tabs-mode: nil
328 * End:
329 */