direct-io.hg

view xen/arch/ia64/xen/dom0_ops.c @ 12425:5c5af79e7272

[IA64] IA64 counter part of the change 12204:e6fdb32b786c of xen-unstable.hg

Remove xc_ia64_get_pfn_list() from setup_guest() in xc_linux_build.c,
use xc_domain_populate_physmap() and xc_domain_translate_gpfn_list().

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Fri Nov 10 11:14:32 2006 -0700 (2006-11-10)
parents 36679b74e24a
children 8ab9b43ad557
line source
1 /******************************************************************************
2 * Arch-specific dom0_ops.c
3 *
4 * Process command requests from domain-0 guest OS.
5 *
6 * Copyright (c) 2002, K A Fraser
7 */
9 #include <xen/config.h>
10 #include <xen/types.h>
11 #include <xen/lib.h>
12 #include <xen/mm.h>
13 #include <public/domctl.h>
14 #include <public/sysctl.h>
15 #include <xen/sched.h>
16 #include <xen/event.h>
17 #include <asm/pdb.h>
18 #include <xen/trace.h>
19 #include <xen/console.h>
20 #include <xen/guest_access.h>
21 #include <asm/vmx.h>
22 #include <asm/dom_fw.h>
23 #include <xen/iocap.h>
24 #include <xen/errno.h>
25 #include <xen/nodemask.h>
27 #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
29 extern unsigned long total_pages;
31 long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
32 {
33 long ret = 0;
35 if ( !IS_PRIV(current->domain) )
36 return -EPERM;
38 switch ( op->cmd )
39 {
40 case XEN_DOMCTL_getmemlist:
41 {
42 unsigned long i;
43 struct domain *d = find_domain_by_id(op->domain);
44 unsigned long start_page = op->u.getmemlist.start_pfn;
45 unsigned long nr_pages = op->u.getmemlist.max_pfns;
46 unsigned long mfn;
48 if ( d == NULL ) {
49 ret = -EINVAL;
50 break;
51 }
52 for (i = 0 ; i < nr_pages ; i++) {
53 pte_t *pte;
55 pte = (pte_t *)lookup_noalloc_domain_pte(d,
56 (start_page + i) << PAGE_SHIFT);
57 if (pte && pte_present(*pte))
58 mfn = pte_pfn(*pte);
59 else
60 mfn = INVALID_MFN;
62 if ( copy_to_guest_offset(op->u.getmemlist.buffer, i, &mfn, 1) ) {
63 ret = -EFAULT;
64 break;
65 }
66 }
68 op->u.getmemlist.num_pfns = i;
69 if (copy_to_guest(u_domctl, op, 1))
70 ret = -EFAULT;
72 put_domain(d);
73 }
74 break;
76 case XEN_DOMCTL_arch_setup:
77 {
78 xen_domctl_arch_setup_t *ds = &op->u.arch_setup;
79 struct domain *d = find_domain_by_id(op->domain);
81 if ( d == NULL) {
82 ret = -EINVAL;
83 break;
84 }
86 if (ds->flags & XEN_DOMAINSETUP_query) {
87 /* Set flags. */
88 if (d->arch.is_vti)
89 ds->flags |= XEN_DOMAINSETUP_hvm_guest;
90 /* Set params. */
91 ds->bp = 0; /* unknown. */
92 ds->maxmem = 0; /* unknown. */
93 ds->xsi_va = d->arch.shared_info_va;
94 ds->hypercall_imm = d->arch.breakimm;
95 /* Copy back. */
96 if ( copy_to_guest(u_domctl, op, 1) )
97 ret = -EFAULT;
98 }
99 else {
100 if (ds->flags & XEN_DOMAINSETUP_hvm_guest) {
101 if (!vmx_enabled) {
102 printk("No VMX hardware feature for vmx domain.\n");
103 ret = -EINVAL;
104 break;
105 }
106 if (!d->arch.is_vti) {
107 struct vcpu *v;
108 for_each_vcpu(d, v) {
109 BUG_ON(v->arch.privregs == NULL);
110 free_domheap_pages(virt_to_page(v->arch.privregs),
111 get_order_from_shift(XMAPPEDREGS_SHIFT));
112 relinquish_vcpu_resources(v);
113 }
114 }
115 d->arch.is_vti = 1;
116 vmx_setup_platform(d);
117 }
118 else {
119 dom_fw_setup(d, ds->bp, ds->maxmem);
120 if (ds->xsi_va)
121 d->arch.shared_info_va = ds->xsi_va;
122 if (ds->hypercall_imm) {
123 struct vcpu *v;
124 d->arch.breakimm = ds->hypercall_imm;
125 for_each_vcpu (d, v)
126 v->arch.breakimm = d->arch.breakimm;
127 }
128 }
129 }
131 put_domain(d);
132 }
133 break;
135 case XEN_DOMCTL_shadow_op:
136 {
137 struct domain *d;
138 ret = -ESRCH;
139 d = find_domain_by_id(op->domain);
140 if ( d != NULL )
141 {
142 ret = shadow_mode_control(d, &op->u.shadow_op);
143 put_domain(d);
144 copy_to_guest(u_domctl, op, 1);
145 }
146 }
147 break;
149 case XEN_DOMCTL_ioport_permission:
150 {
151 struct domain *d;
152 unsigned int fp = op->u.ioport_permission.first_port;
153 unsigned int np = op->u.ioport_permission.nr_ports;
154 unsigned int lp = fp + np - 1;
156 ret = -ESRCH;
157 d = find_domain_by_id(op->domain);
158 if (unlikely(d == NULL))
159 break;
161 if (np == 0)
162 ret = 0;
163 else {
164 if (op->u.ioport_permission.allow_access)
165 ret = ioports_permit_access(d, fp, lp);
166 else
167 ret = ioports_deny_access(d, fp, lp);
168 }
170 put_domain(d);
171 }
172 break;
173 default:
174 printk("arch_do_domctl: unrecognized domctl: %d!!!\n",op->cmd);
175 ret = -ENOSYS;
177 }
179 return ret;
180 }
182 /*
183 * Temporarily disable the NUMA PHYSINFO code until the rest of the
184 * changes are upstream.
185 */
186 #undef IA64_NUMA_PHYSINFO
188 long arch_do_sysctl(xen_sysctl_t *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
189 {
190 long ret = 0;
192 switch ( op->cmd )
193 {
194 case XEN_SYSCTL_physinfo:
195 {
196 #ifdef IA64_NUMA_PHYSINFO
197 int i;
198 node_data_t *chunks;
199 u64 *map, cpu_to_node_map[MAX_NUMNODES];
200 #endif
202 xen_sysctl_physinfo_t *pi = &op->u.physinfo;
204 pi->threads_per_core =
205 cpus_weight(cpu_sibling_map[0]);
206 pi->cores_per_socket =
207 cpus_weight(cpu_core_map[0]) / pi->threads_per_core;
208 pi->sockets_per_node =
209 num_online_cpus() / cpus_weight(cpu_core_map[0]);
210 #ifndef IA64_NUMA_PHYSINFO
211 pi->nr_nodes = 1;
212 #endif
213 pi->total_pages = total_pages;
214 pi->free_pages = avail_domheap_pages();
215 pi->cpu_khz = local_cpu_data->proc_freq / 1000;
216 memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
217 //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
218 ret = 0;
220 #ifdef IA64_NUMA_PHYSINFO
221 /* fetch memory_chunk pointer from guest */
222 get_xen_guest_handle(chunks, pi->memory_chunks);
224 printk("chunks=%p, num_node_memblks=%u\n", chunks, num_node_memblks);
225 /* if it is set, fill out memory chunk array */
226 if (chunks != NULL) {
227 if (num_node_memblks == 0) {
228 /* Non-NUMA machine. Put pseudo-values. */
229 node_data_t data;
230 data.node_start_pfn = 0;
231 data.node_spanned_pages = total_pages;
232 data.node_id = 0;
233 /* copy memory chunk structs to guest */
234 if (copy_to_guest_offset(pi->memory_chunks, 0, &data, 1)) {
235 ret = -EFAULT;
236 break;
237 }
238 } else {
239 for (i = 0; i < num_node_memblks && i < PUBLIC_MAXCHUNKS; i++) {
240 node_data_t data;
241 data.node_start_pfn = node_memblk[i].start_paddr >>
242 PAGE_SHIFT;
243 data.node_spanned_pages = node_memblk[i].size >> PAGE_SHIFT;
244 data.node_id = node_memblk[i].nid;
245 /* copy memory chunk structs to guest */
246 if (copy_to_guest_offset(pi->memory_chunks, i, &data, 1)) {
247 ret = -EFAULT;
248 break;
249 }
250 }
251 }
252 }
253 /* set number of notes */
254 pi->nr_nodes = num_online_nodes();
256 /* fetch cpu_to_node pointer from guest */
257 get_xen_guest_handle(map, pi->cpu_to_node);
259 /* if set, fill out cpu_to_node array */
260 if (map != NULL) {
261 /* copy cpu to node mapping to domU */
262 memset(cpu_to_node_map, 0, sizeof(cpu_to_node_map));
263 for (i = 0; i < num_online_cpus(); i++) {
264 cpu_to_node_map[i] = cpu_to_node(i);
265 if (copy_to_guest_offset(pi->cpu_to_node, i,
266 &(cpu_to_node_map[i]), 1)) {
267 ret = -EFAULT;
268 break;
269 }
270 }
271 }
272 #endif
274 if ( copy_to_guest(u_sysctl, op, 1) )
275 ret = -EFAULT;
276 }
277 break;
279 default:
280 printk("arch_do_sysctl: unrecognized sysctl: %d!!!\n",op->cmd);
281 ret = -ENOSYS;
283 }
285 return ret;
286 }
288 static unsigned long
289 dom0vp_ioremap(struct domain *d, unsigned long mpaddr, unsigned long size)
290 {
291 unsigned long end;
293 /* Linux may use a 0 size! */
294 if (size == 0)
295 size = PAGE_SIZE;
297 end = PAGE_ALIGN(mpaddr + size);
299 if (!iomem_access_permitted(d, mpaddr >> PAGE_SHIFT,
300 (end >> PAGE_SHIFT) - 1))
301 return -EPERM;
303 return assign_domain_mmio_page(d, mpaddr, size);
304 }
306 unsigned long
307 do_dom0vp_op(unsigned long cmd,
308 unsigned long arg0, unsigned long arg1, unsigned long arg2,
309 unsigned long arg3)
310 {
311 unsigned long ret = 0;
312 struct domain *d = current->domain;
314 switch (cmd) {
315 case IA64_DOM0VP_ioremap:
316 ret = dom0vp_ioremap(d, arg0, arg1);
317 break;
318 case IA64_DOM0VP_phystomach:
319 ret = ____lookup_domain_mpa(d, arg0 << PAGE_SHIFT);
320 if (ret == INVALID_MFN) {
321 dprintk(XENLOG_INFO, "%s: INVALID_MFN ret: 0x%lx\n",
322 __func__, ret);
323 } else {
324 ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
325 }
326 perfc_incrc(dom0vp_phystomach);
327 break;
328 case IA64_DOM0VP_machtophys:
329 if (!mfn_valid(arg0)) {
330 ret = INVALID_M2P_ENTRY;
331 break;
332 }
333 ret = get_gpfn_from_mfn(arg0);
334 perfc_incrc(dom0vp_machtophys);
335 break;
336 case IA64_DOM0VP_zap_physmap:
337 ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
338 break;
339 case IA64_DOM0VP_add_physmap:
340 ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2,
341 (domid_t)arg3);
342 break;
343 case IA64_DOM0VP_expose_p2m:
344 ret = dom0vp_expose_p2m(d, arg0, arg1, arg2, arg3);
345 break;
346 default:
347 ret = -1;
348 printk("unknown dom0_vp_op 0x%lx\n", cmd);
349 break;
350 }
352 return ret;
353 }
355 /*
356 * Local variables:
357 * mode: C
358 * c-set-style: "BSD"
359 * c-basic-offset: 4
360 * tab-width: 4
361 * indent-tabs-mode: nil
362 * End:
363 */