debuggers.hg

view tools/libxc/xc_misc.c @ 22906:700ac6445812

Now add KDB to the non-kdb tree
author Mukesh Rathor
date Thu Feb 03 15:42:41 2011 -0800 (2011-02-03)
parents 32ec2fab6ea4
children
line source
1 /******************************************************************************
2 * xc_misc.c
3 *
4 * Miscellaneous control interface functions.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation;
9 * version 2.1 of the License.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
21 #include "xc_private.h"
22 #include <xen/hvm/hvm_op.h>
24 int xc_get_max_cpus(xc_interface *xch)
25 {
26 static int max_cpus = 0;
27 xc_physinfo_t physinfo;
29 if ( max_cpus )
30 return max_cpus;
32 if ( !xc_physinfo(xch, &physinfo) )
33 max_cpus = physinfo.max_cpu_id + 1;
35 return max_cpus;
36 }
38 int xc_get_cpumap_size(xc_interface *xch)
39 {
40 return (xc_get_max_cpus(xch) + 7) / 8;
41 }
43 xc_cpumap_t xc_cpumap_alloc(xc_interface *xch)
44 {
45 int sz;
47 sz = xc_get_cpumap_size(xch);
48 if (sz == 0)
49 return NULL;
50 return calloc(1, sz);
51 }
53 int xc_readconsolering(xc_interface *xch,
54 char *buffer,
55 unsigned int *pnr_chars,
56 int clear, int incremental, uint32_t *pindex)
57 {
58 int ret;
59 unsigned int nr_chars = *pnr_chars;
60 DECLARE_SYSCTL;
61 DECLARE_HYPERCALL_BOUNCE(buffer, nr_chars, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
63 if ( xc_hypercall_bounce_pre(xch, buffer) )
64 return -1;
66 sysctl.cmd = XEN_SYSCTL_readconsole;
67 set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer);
68 sysctl.u.readconsole.count = nr_chars;
69 sysctl.u.readconsole.clear = clear;
70 sysctl.u.readconsole.incremental = 0;
71 if ( pindex )
72 {
73 sysctl.u.readconsole.index = *pindex;
74 sysctl.u.readconsole.incremental = incremental;
75 }
77 if ( (ret = do_sysctl(xch, &sysctl)) == 0 )
78 {
79 *pnr_chars = sysctl.u.readconsole.count;
80 if ( pindex )
81 *pindex = sysctl.u.readconsole.index;
82 }
84 xc_hypercall_bounce_post(xch, buffer);
86 return ret;
87 }
89 int xc_send_debug_keys(xc_interface *xch, char *keys)
90 {
91 int ret, len = strlen(keys);
92 DECLARE_SYSCTL;
93 DECLARE_HYPERCALL_BOUNCE(keys, len, XC_HYPERCALL_BUFFER_BOUNCE_IN);
95 if ( xc_hypercall_bounce_pre(xch, keys) )
96 return -1;
98 sysctl.cmd = XEN_SYSCTL_debug_keys;
99 set_xen_guest_handle(sysctl.u.debug_keys.keys, keys);
100 sysctl.u.debug_keys.nr_keys = len;
102 ret = do_sysctl(xch, &sysctl);
104 xc_hypercall_bounce_post(xch, keys);
106 return ret;
107 }
109 int xc_physinfo(xc_interface *xch,
110 xc_physinfo_t *put_info)
111 {
112 int ret;
113 DECLARE_SYSCTL;
115 sysctl.cmd = XEN_SYSCTL_physinfo;
117 memcpy(&sysctl.u.physinfo, put_info, sizeof(*put_info));
119 if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
120 return ret;
122 memcpy(put_info, &sysctl.u.physinfo, sizeof(*put_info));
124 return 0;
125 }
127 int xc_topologyinfo(xc_interface *xch,
128 xc_topologyinfo_t *put_info)
129 {
130 int ret;
131 DECLARE_SYSCTL;
133 sysctl.cmd = XEN_SYSCTL_topologyinfo;
135 memcpy(&sysctl.u.topologyinfo, put_info, sizeof(*put_info));
137 if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
138 return ret;
140 memcpy(put_info, &sysctl.u.topologyinfo, sizeof(*put_info));
142 return 0;
143 }
145 int xc_numainfo(xc_interface *xch,
146 xc_numainfo_t *put_info)
147 {
148 int ret;
149 DECLARE_SYSCTL;
151 sysctl.cmd = XEN_SYSCTL_numainfo;
153 memcpy(&sysctl.u.numainfo, put_info, sizeof(*put_info));
155 if ((ret = do_sysctl(xch, &sysctl)) != 0)
156 return ret;
158 memcpy(put_info, &sysctl.u.numainfo, sizeof(*put_info));
160 return 0;
161 }
164 int xc_sched_id(xc_interface *xch,
165 int *sched_id)
166 {
167 int ret;
168 DECLARE_SYSCTL;
170 sysctl.cmd = XEN_SYSCTL_sched_id;
172 if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
173 return ret;
175 *sched_id = sysctl.u.sched_id.sched_id;
177 return 0;
178 }
180 #if defined(__i386__) || defined(__x86_64__)
181 int xc_mca_op(xc_interface *xch, struct xen_mc *mc)
182 {
183 int ret = 0;
184 DECLARE_HYPERCALL;
185 DECLARE_HYPERCALL_BOUNCE(mc, sizeof(*mc), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
187 if ( xc_hypercall_bounce_pre(xch, mc) )
188 {
189 PERROR("Could not bounce xen_mc memory buffer");
190 return -1;
191 }
192 mc->interface_version = XEN_MCA_INTERFACE_VERSION;
194 hypercall.op = __HYPERVISOR_mca;
195 hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(mc);
196 ret = do_xen_hypercall(xch, &hypercall);
197 xc_hypercall_bounce_post(xch, mc);
198 return ret;
199 }
200 #endif
202 int xc_perfc_reset(xc_interface *xch)
203 {
204 DECLARE_SYSCTL;
206 sysctl.cmd = XEN_SYSCTL_perfc_op;
207 sysctl.u.perfc_op.cmd = XEN_SYSCTL_PERFCOP_reset;
208 set_xen_guest_handle(sysctl.u.perfc_op.desc, HYPERCALL_BUFFER_NULL);
209 set_xen_guest_handle(sysctl.u.perfc_op.val, HYPERCALL_BUFFER_NULL);
211 return do_sysctl(xch, &sysctl);
212 }
214 int xc_perfc_query_number(xc_interface *xch,
215 int *nbr_desc,
216 int *nbr_val)
217 {
218 int rc;
219 DECLARE_SYSCTL;
221 sysctl.cmd = XEN_SYSCTL_perfc_op;
222 sysctl.u.perfc_op.cmd = XEN_SYSCTL_PERFCOP_query;
223 set_xen_guest_handle(sysctl.u.perfc_op.desc, HYPERCALL_BUFFER_NULL);
224 set_xen_guest_handle(sysctl.u.perfc_op.val, HYPERCALL_BUFFER_NULL);
226 rc = do_sysctl(xch, &sysctl);
228 if ( nbr_desc )
229 *nbr_desc = sysctl.u.perfc_op.nr_counters;
230 if ( nbr_val )
231 *nbr_val = sysctl.u.perfc_op.nr_vals;
233 return rc;
234 }
236 int xc_perfc_query(xc_interface *xch,
237 struct xc_hypercall_buffer *desc,
238 struct xc_hypercall_buffer *val)
239 {
240 DECLARE_SYSCTL;
241 DECLARE_HYPERCALL_BUFFER_ARGUMENT(desc);
242 DECLARE_HYPERCALL_BUFFER_ARGUMENT(val);
244 sysctl.cmd = XEN_SYSCTL_perfc_op;
245 sysctl.u.perfc_op.cmd = XEN_SYSCTL_PERFCOP_query;
246 set_xen_guest_handle(sysctl.u.perfc_op.desc, desc);
247 set_xen_guest_handle(sysctl.u.perfc_op.val, val);
249 return do_sysctl(xch, &sysctl);
250 }
252 int xc_lockprof_reset(xc_interface *xch)
253 {
254 DECLARE_SYSCTL;
256 sysctl.cmd = XEN_SYSCTL_lockprof_op;
257 sysctl.u.lockprof_op.cmd = XEN_SYSCTL_LOCKPROF_reset;
258 set_xen_guest_handle(sysctl.u.lockprof_op.data, HYPERCALL_BUFFER_NULL);
260 return do_sysctl(xch, &sysctl);
261 }
263 int xc_lockprof_query_number(xc_interface *xch,
264 uint32_t *n_elems)
265 {
266 int rc;
267 DECLARE_SYSCTL;
269 sysctl.cmd = XEN_SYSCTL_lockprof_op;
270 sysctl.u.lockprof_op.cmd = XEN_SYSCTL_LOCKPROF_query;
271 set_xen_guest_handle(sysctl.u.lockprof_op.data, HYPERCALL_BUFFER_NULL);
273 rc = do_sysctl(xch, &sysctl);
275 *n_elems = sysctl.u.lockprof_op.nr_elem;
277 return rc;
278 }
280 int xc_lockprof_query(xc_interface *xch,
281 uint32_t *n_elems,
282 uint64_t *time,
283 struct xc_hypercall_buffer *data)
284 {
285 int rc;
286 DECLARE_SYSCTL;
287 DECLARE_HYPERCALL_BUFFER_ARGUMENT(data);
289 sysctl.cmd = XEN_SYSCTL_lockprof_op;
290 sysctl.u.lockprof_op.cmd = XEN_SYSCTL_LOCKPROF_query;
291 sysctl.u.lockprof_op.max_elem = *n_elems;
292 set_xen_guest_handle(sysctl.u.lockprof_op.data, data);
294 rc = do_sysctl(xch, &sysctl);
296 *n_elems = sysctl.u.lockprof_op.nr_elem;
298 return rc;
299 }
301 int xc_getcpuinfo(xc_interface *xch, int max_cpus,
302 xc_cpuinfo_t *info, int *nr_cpus)
303 {
304 int rc;
305 DECLARE_SYSCTL;
306 DECLARE_HYPERCALL_BOUNCE(info, max_cpus*sizeof(*info), XC_HYPERCALL_BUFFER_BOUNCE_OUT);
308 if ( xc_hypercall_bounce_pre(xch, info) )
309 return -1;
311 sysctl.cmd = XEN_SYSCTL_getcpuinfo;
312 sysctl.u.getcpuinfo.max_cpus = max_cpus;
313 set_xen_guest_handle(sysctl.u.getcpuinfo.info, info);
315 rc = do_sysctl(xch, &sysctl);
317 xc_hypercall_bounce_post(xch, info);
319 if ( nr_cpus )
320 *nr_cpus = sysctl.u.getcpuinfo.nr_cpus;
322 return rc;
323 }
326 int xc_hvm_set_pci_intx_level(
327 xc_interface *xch, domid_t dom,
328 uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
329 unsigned int level)
330 {
331 DECLARE_HYPERCALL;
332 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_pci_intx_level, arg);
333 int rc;
335 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
336 if ( arg == NULL )
337 {
338 PERROR("Could not allocate memory for xc_hvm_set_pci_intx_level hypercall");
339 return -1;
340 }
342 hypercall.op = __HYPERVISOR_hvm_op;
343 hypercall.arg[0] = HVMOP_set_pci_intx_level;
344 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
346 arg->domid = dom;
347 arg->domain = domain;
348 arg->bus = bus;
349 arg->device = device;
350 arg->intx = intx;
351 arg->level = level;
353 rc = do_xen_hypercall(xch, &hypercall);
355 xc_hypercall_buffer_free(xch, arg);
357 return rc;
358 }
360 int xc_hvm_set_isa_irq_level(
361 xc_interface *xch, domid_t dom,
362 uint8_t isa_irq,
363 unsigned int level)
364 {
365 DECLARE_HYPERCALL;
366 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_isa_irq_level, arg);
367 int rc;
369 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
370 if ( arg == NULL )
371 {
372 PERROR("Could not allocate memory for xc_hvm_set_isa_irq_level hypercall");
373 return -1;
374 }
376 hypercall.op = __HYPERVISOR_hvm_op;
377 hypercall.arg[0] = HVMOP_set_isa_irq_level;
378 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
380 arg->domid = dom;
381 arg->isa_irq = isa_irq;
382 arg->level = level;
384 rc = do_xen_hypercall(xch, &hypercall);
386 xc_hypercall_buffer_free(xch, arg);
388 return rc;
389 }
391 int xc_hvm_set_pci_link_route(
392 xc_interface *xch, domid_t dom, uint8_t link, uint8_t isa_irq)
393 {
394 DECLARE_HYPERCALL;
395 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_pci_link_route, arg);
396 int rc;
398 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
399 if ( arg == NULL )
400 {
401 PERROR("Could not allocate memory for xc_hvm_set_pci_link_route hypercall");
402 return -1;
403 }
405 hypercall.op = __HYPERVISOR_hvm_op;
406 hypercall.arg[0] = HVMOP_set_pci_link_route;
407 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
409 arg->domid = dom;
410 arg->link = link;
411 arg->isa_irq = isa_irq;
413 rc = do_xen_hypercall(xch, &hypercall);
415 xc_hypercall_buffer_free(xch, arg);
417 return rc;
418 }
420 int xc_hvm_track_dirty_vram(
421 xc_interface *xch, domid_t dom,
422 uint64_t first_pfn, uint64_t nr,
423 unsigned long *dirty_bitmap)
424 {
425 DECLARE_HYPERCALL;
426 DECLARE_HYPERCALL_BOUNCE(dirty_bitmap, (nr+7) / 8, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
427 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_track_dirty_vram, arg);
428 int rc;
430 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
431 if ( arg == NULL || xc_hypercall_bounce_pre(xch, dirty_bitmap) )
432 {
433 PERROR("Could not bounce memory for xc_hvm_track_dirty_vram hypercall");
434 rc = -1;
435 goto out;
436 }
438 hypercall.op = __HYPERVISOR_hvm_op;
439 hypercall.arg[0] = HVMOP_track_dirty_vram;
440 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
442 arg->domid = dom;
443 arg->first_pfn = first_pfn;
444 arg->nr = nr;
445 set_xen_guest_handle(arg->dirty_bitmap, dirty_bitmap);
447 rc = do_xen_hypercall(xch, &hypercall);
449 out:
450 xc_hypercall_buffer_free(xch, arg);
451 xc_hypercall_bounce_post(xch, dirty_bitmap);
452 return rc;
453 }
455 int xc_hvm_modified_memory(
456 xc_interface *xch, domid_t dom, uint64_t first_pfn, uint64_t nr)
457 {
458 DECLARE_HYPERCALL;
459 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_modified_memory, arg);
460 int rc;
462 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
463 if ( arg == NULL )
464 {
465 PERROR("Could not allocate memory for xc_hvm_modified_memory hypercall");
466 return -1;
467 }
469 hypercall.op = __HYPERVISOR_hvm_op;
470 hypercall.arg[0] = HVMOP_modified_memory;
471 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
473 arg->domid = dom;
474 arg->first_pfn = first_pfn;
475 arg->nr = nr;
477 rc = do_xen_hypercall(xch, &hypercall);
479 xc_hypercall_buffer_free(xch, arg);
481 return rc;
482 }
484 int xc_hvm_set_mem_type(
485 xc_interface *xch, domid_t dom, hvmmem_type_t mem_type, uint64_t first_pfn, uint64_t nr)
486 {
487 DECLARE_HYPERCALL;
488 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_mem_type, arg);
489 int rc;
491 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
492 if ( arg == NULL )
493 {
494 PERROR("Could not allocate memory for xc_hvm_set_mem_type hypercall");
495 return -1;
496 }
498 arg->domid = dom;
499 arg->hvmmem_type = mem_type;
500 arg->first_pfn = first_pfn;
501 arg->nr = nr;
503 hypercall.op = __HYPERVISOR_hvm_op;
504 hypercall.arg[0] = HVMOP_set_mem_type;
505 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
507 rc = do_xen_hypercall(xch, &hypercall);
509 xc_hypercall_buffer_free(xch, arg);
511 return rc;
512 }
514 int xc_hvm_set_mem_access(
515 xc_interface *xch, domid_t dom, hvmmem_access_t mem_access, uint64_t first_pfn, uint64_t nr)
516 {
517 DECLARE_HYPERCALL;
518 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_mem_access, arg);
519 int rc;
521 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
522 if ( arg == NULL )
523 {
524 PERROR("Could not allocate memory for xc_hvm_set_mem_access hypercall");
525 return -1;
526 }
528 arg->domid = dom;
529 arg->hvmmem_access = mem_access;
530 arg->first_pfn = first_pfn;
531 arg->nr = nr;
533 hypercall.op = __HYPERVISOR_hvm_op;
534 hypercall.arg[0] = HVMOP_set_mem_access;
535 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
537 rc = do_xen_hypercall(xch, &hypercall);
539 xc_hypercall_buffer_free(xch, arg);
541 return rc;
542 }
544 int xc_hvm_get_mem_access(
545 xc_interface *xch, domid_t dom, uint64_t pfn, hvmmem_access_t* mem_access)
546 {
547 DECLARE_HYPERCALL;
548 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_get_mem_access, arg);
549 int rc;
551 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
552 if ( arg == NULL )
553 {
554 PERROR("Could not allocate memory for xc_hvm_get_mem_access hypercall");
555 return -1;
556 }
558 arg->domid = dom;
559 arg->pfn = pfn;
561 hypercall.op = __HYPERVISOR_hvm_op;
562 hypercall.arg[0] = HVMOP_get_mem_access;
563 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
565 rc = do_xen_hypercall(xch, &hypercall);
567 if ( !rc )
568 *mem_access = arg->hvmmem_access;
570 xc_hypercall_buffer_free(xch, arg);
572 return rc;
573 }
575 int xc_hvm_inject_trap(
576 xc_interface *xch, domid_t dom, int vcpu, uint32_t trap, uint32_t error_code,
577 uint64_t cr2)
578 {
579 DECLARE_HYPERCALL;
580 DECLARE_HYPERCALL_BUFFER(struct xen_hvm_inject_trap, arg);
581 int rc;
583 arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
584 if ( arg == NULL )
585 {
586 PERROR("Could not allocate memory for xc_hvm_inject_trap hypercall");
587 return -1;
588 }
590 arg->domid = dom;
591 arg->vcpuid = vcpu;
592 arg->trap = trap;
593 arg->error_code = error_code;
594 arg->cr2 = cr2;
596 hypercall.op = __HYPERVISOR_hvm_op;
597 hypercall.arg[0] = HVMOP_inject_trap;
598 hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
600 rc = do_xen_hypercall(xch, &hypercall);
602 xc_hypercall_buffer_free(xch, arg);
604 return rc;
605 }
607 /*
608 * Local variables:
609 * mode: C
610 * c-set-style: "BSD"
611 * c-basic-offset: 4
612 * tab-width: 4
613 * indent-tabs-mode: nil
614 * End:
615 */