debuggers.hg

view tools/libxc/xc_misc.c @ 20929:a7546e45ca83

libxc: Export do_mca hypercall to user space tools.

This is mainly for software trigger MCE operation, so that test suites
can trigger software MCE.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Feb 03 09:38:57 2010 +0000 (2010-02-03)
parents 9c6ba538ce75
children 3c3759296796
line source
1 /******************************************************************************
2 * xc_misc.c
3 *
4 * Miscellaneous control interface functions.
5 */
7 #include "xc_private.h"
8 #include <xen/hvm/hvm_op.h>
10 int xc_readconsolering(int xc_handle,
11 char **pbuffer,
12 unsigned int *pnr_chars,
13 int clear, int incremental, uint32_t *pindex)
14 {
15 int ret;
16 DECLARE_SYSCTL;
17 char *buffer = *pbuffer;
18 unsigned int nr_chars = *pnr_chars;
20 sysctl.cmd = XEN_SYSCTL_readconsole;
21 set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer);
22 sysctl.u.readconsole.count = nr_chars;
23 sysctl.u.readconsole.clear = clear;
24 sysctl.u.readconsole.incremental = 0;
25 if ( pindex )
26 {
27 sysctl.u.readconsole.index = *pindex;
28 sysctl.u.readconsole.incremental = incremental;
29 }
31 if ( (ret = lock_pages(buffer, nr_chars)) != 0 )
32 return ret;
34 if ( (ret = do_sysctl(xc_handle, &sysctl)) == 0 )
35 {
36 *pnr_chars = sysctl.u.readconsole.count;
37 if ( pindex )
38 *pindex = sysctl.u.readconsole.index;
39 }
41 unlock_pages(buffer, nr_chars);
43 return ret;
44 }
46 int xc_send_debug_keys(int xc_handle, char *keys)
47 {
48 int ret, len = strlen(keys);
49 DECLARE_SYSCTL;
51 sysctl.cmd = XEN_SYSCTL_debug_keys;
52 set_xen_guest_handle(sysctl.u.debug_keys.keys, keys);
53 sysctl.u.debug_keys.nr_keys = len;
55 if ( (ret = lock_pages(keys, len)) != 0 )
56 return ret;
58 ret = do_sysctl(xc_handle, &sysctl);
60 unlock_pages(keys, len);
62 return ret;
63 }
65 int xc_physinfo(int xc_handle,
66 xc_physinfo_t *put_info)
67 {
68 int ret;
69 DECLARE_SYSCTL;
71 sysctl.cmd = XEN_SYSCTL_physinfo;
73 memcpy(&sysctl.u.physinfo, put_info, sizeof(*put_info));
75 if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
76 return ret;
78 memcpy(put_info, &sysctl.u.physinfo, sizeof(*put_info));
80 return 0;
81 }
83 int xc_sched_id(int xc_handle,
84 int *sched_id)
85 {
86 int ret;
87 DECLARE_SYSCTL;
89 sysctl.cmd = XEN_SYSCTL_sched_id;
91 if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
92 return ret;
94 *sched_id = sysctl.u.sched_id.sched_id;
96 return 0;
97 }
99 #if defined(__i386__) || defined(__x86_64__)
100 int xc_mca_op(int xc_handle, struct xen_mc *mc)
101 {
102 int ret = 0;
103 DECLARE_HYPERCALL;
105 mc->interface_version = XEN_MCA_INTERFACE_VERSION;
106 if ( lock_pages(mc, sizeof(mc)) )
107 {
108 PERROR("Could not lock xen_mc memory\n");
109 return -EINVAL;
110 }
112 hypercall.op = __HYPERVISOR_mca;
113 hypercall.arg[0] = (unsigned long)mc;
114 ret = do_xen_hypercall(xc_handle, &hypercall);
115 unlock_pages(mc, sizeof(mc));
116 return ret;
117 }
118 #endif
120 int xc_perfc_control(int xc_handle,
121 uint32_t opcode,
122 xc_perfc_desc_t *desc,
123 xc_perfc_val_t *val,
124 int *nbr_desc,
125 int *nbr_val)
126 {
127 int rc;
128 DECLARE_SYSCTL;
130 sysctl.cmd = XEN_SYSCTL_perfc_op;
131 sysctl.u.perfc_op.cmd = opcode;
132 set_xen_guest_handle(sysctl.u.perfc_op.desc, desc);
133 set_xen_guest_handle(sysctl.u.perfc_op.val, val);
135 rc = do_sysctl(xc_handle, &sysctl);
137 if ( nbr_desc )
138 *nbr_desc = sysctl.u.perfc_op.nr_counters;
139 if ( nbr_val )
140 *nbr_val = sysctl.u.perfc_op.nr_vals;
142 return rc;
143 }
145 int xc_lockprof_control(int xc_handle,
146 uint32_t opcode,
147 uint32_t *n_elems,
148 uint64_t *time,
149 xc_lockprof_data_t *data)
150 {
151 int rc;
152 DECLARE_SYSCTL;
154 sysctl.cmd = XEN_SYSCTL_lockprof_op;
155 sysctl.u.lockprof_op.cmd = opcode;
156 sysctl.u.lockprof_op.max_elem = n_elems ? *n_elems : 0;
157 set_xen_guest_handle(sysctl.u.lockprof_op.data, data);
159 rc = do_sysctl(xc_handle, &sysctl);
161 if (n_elems)
162 *n_elems = sysctl.u.lockprof_op.nr_elem;
163 if (time)
164 *time = sysctl.u.lockprof_op.time;
166 return rc;
167 }
169 int xc_getcpuinfo(int xc_handle, int max_cpus,
170 xc_cpuinfo_t *info, int *nr_cpus)
171 {
172 int rc;
173 DECLARE_SYSCTL;
175 sysctl.cmd = XEN_SYSCTL_getcpuinfo;
176 sysctl.u.getcpuinfo.max_cpus = max_cpus;
177 set_xen_guest_handle(sysctl.u.getcpuinfo.info, info);
179 if ( (rc = lock_pages(info, max_cpus*sizeof(*info))) != 0 )
180 return rc;
182 rc = do_sysctl(xc_handle, &sysctl);
184 unlock_pages(info, max_cpus*sizeof(*info));
186 if ( nr_cpus )
187 *nr_cpus = sysctl.u.getcpuinfo.nr_cpus;
189 return rc;
190 }
193 int xc_hvm_set_pci_intx_level(
194 int xc_handle, domid_t dom,
195 uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
196 unsigned int level)
197 {
198 DECLARE_HYPERCALL;
199 struct xen_hvm_set_pci_intx_level _arg, *arg = &_arg;
200 int rc;
202 if ( (rc = hcall_buf_prep((void **)&arg, sizeof(*arg))) != 0 )
203 {
204 PERROR("Could not lock memory");
205 return rc;
206 }
208 hypercall.op = __HYPERVISOR_hvm_op;
209 hypercall.arg[0] = HVMOP_set_pci_intx_level;
210 hypercall.arg[1] = (unsigned long)arg;
212 arg->domid = dom;
213 arg->domain = domain;
214 arg->bus = bus;
215 arg->device = device;
216 arg->intx = intx;
217 arg->level = level;
219 rc = do_xen_hypercall(xc_handle, &hypercall);
221 hcall_buf_release((void **)&arg, sizeof(*arg));
223 return rc;
224 }
226 int xc_hvm_set_isa_irq_level(
227 int xc_handle, domid_t dom,
228 uint8_t isa_irq,
229 unsigned int level)
230 {
231 DECLARE_HYPERCALL;
232 struct xen_hvm_set_isa_irq_level _arg, *arg = &_arg;
233 int rc;
235 if ( (rc = hcall_buf_prep((void **)&arg, sizeof(*arg))) != 0 )
236 {
237 PERROR("Could not lock memory");
238 return rc;
239 }
241 hypercall.op = __HYPERVISOR_hvm_op;
242 hypercall.arg[0] = HVMOP_set_isa_irq_level;
243 hypercall.arg[1] = (unsigned long)arg;
245 arg->domid = dom;
246 arg->isa_irq = isa_irq;
247 arg->level = level;
249 rc = do_xen_hypercall(xc_handle, &hypercall);
251 hcall_buf_release((void **)&arg, sizeof(*arg));
253 return rc;
254 }
256 int xc_hvm_set_pci_link_route(
257 int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq)
258 {
259 DECLARE_HYPERCALL;
260 struct xen_hvm_set_pci_link_route arg;
261 int rc;
263 hypercall.op = __HYPERVISOR_hvm_op;
264 hypercall.arg[0] = HVMOP_set_pci_link_route;
265 hypercall.arg[1] = (unsigned long)&arg;
267 arg.domid = dom;
268 arg.link = link;
269 arg.isa_irq = isa_irq;
271 if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 )
272 {
273 PERROR("Could not lock memory");
274 return rc;
275 }
277 rc = do_xen_hypercall(xc_handle, &hypercall);
279 unlock_pages(&arg, sizeof(arg));
281 return rc;
282 }
284 int xc_hvm_track_dirty_vram(
285 int xc_handle, domid_t dom,
286 uint64_t first_pfn, uint64_t nr,
287 unsigned long *dirty_bitmap)
288 {
289 DECLARE_HYPERCALL;
290 struct xen_hvm_track_dirty_vram arg;
291 int rc;
293 hypercall.op = __HYPERVISOR_hvm_op;
294 hypercall.arg[0] = HVMOP_track_dirty_vram;
295 hypercall.arg[1] = (unsigned long)&arg;
297 arg.domid = dom;
298 arg.first_pfn = first_pfn;
299 arg.nr = nr;
300 set_xen_guest_handle(arg.dirty_bitmap, (uint8_t *)dirty_bitmap);
302 if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 )
303 {
304 PERROR("Could not lock memory");
305 return rc;
306 }
308 rc = do_xen_hypercall(xc_handle, &hypercall);
310 unlock_pages(&arg, sizeof(arg));
312 return rc;
313 }
315 int xc_hvm_modified_memory(
316 int xc_handle, domid_t dom, uint64_t first_pfn, uint64_t nr)
317 {
318 DECLARE_HYPERCALL;
319 struct xen_hvm_modified_memory arg;
320 int rc;
322 hypercall.op = __HYPERVISOR_hvm_op;
323 hypercall.arg[0] = HVMOP_modified_memory;
324 hypercall.arg[1] = (unsigned long)&arg;
326 arg.domid = dom;
327 arg.first_pfn = first_pfn;
328 arg.nr = nr;
330 if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 )
331 {
332 PERROR("Could not lock memory");
333 return rc;
334 }
336 rc = do_xen_hypercall(xc_handle, &hypercall);
338 unlock_pages(&arg, sizeof(arg));
340 return rc;
341 }
343 int xc_hvm_set_mem_type(
344 int xc_handle, domid_t dom, hvmmem_type_t mem_type, uint64_t first_pfn, uint64_t nr)
345 {
346 DECLARE_HYPERCALL;
347 struct xen_hvm_set_mem_type arg;
348 int rc;
350 hypercall.op = __HYPERVISOR_hvm_op;
351 hypercall.arg[0] = HVMOP_set_mem_type;
352 hypercall.arg[1] = (unsigned long)&arg;
354 arg.domid = dom;
355 arg.hvmmem_type = mem_type;
356 arg.first_pfn = first_pfn;
357 arg.nr = nr;
359 if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 )
360 {
361 PERROR("Could not lock memory");
362 return rc;
363 }
365 rc = do_xen_hypercall(xc_handle, &hypercall);
367 unlock_pages(&arg, sizeof(arg));
369 return rc;
370 }
373 void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
374 const xen_pfn_t *arr, int num)
375 {
376 void *res;
377 int i, *err;
379 if (num < 0) {
380 errno = -EINVAL;
381 return NULL;
382 }
384 err = malloc(num * sizeof(*err));
385 if (!err)
386 return NULL;
388 res = xc_map_foreign_bulk(xc_handle, dom, prot, arr, err, num);
389 if (res) {
390 for (i = 0; i < num; i++) {
391 if (err[i]) {
392 errno = -err[i];
393 munmap(res, num * PAGE_SIZE);
394 res = NULL;
395 break;
396 }
397 }
398 }
400 free(err);
401 return res;
402 }
404 /* stub for all not yet converted OSes */
405 void *
406 #ifdef __GNUC__
407 __attribute__((__weak__))
408 #endif
409 xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
410 const xen_pfn_t *arr, int *err, unsigned int num)
411 {
412 xen_pfn_t *pfn;
413 unsigned int i;
414 void *ret;
416 if ((int)num <= 0) {
417 errno = EINVAL;
418 return NULL;
419 }
421 pfn = malloc(num * sizeof(*pfn));
422 if (!pfn) {
423 errno = ENOMEM;
424 return NULL;
425 }
427 memcpy(pfn, arr, num * sizeof(*arr));
428 ret = xc_map_foreign_batch(xc_handle, dom, prot, pfn, num);
430 if (ret) {
431 for (i = 0; i < num; ++i)
432 switch (pfn[i] ^ arr[i]) {
433 case 0:
434 err[i] = 0;
435 break;
436 default:
437 err[i] = -EINVAL;
438 break;
439 }
440 } else
441 memset(err, 0, num * sizeof(*err));
443 free(pfn);
445 return ret;
446 }
448 /*
449 * Local variables:
450 * mode: C
451 * c-set-style: "BSD"
452 * c-basic-offset: 4
453 * tab-width: 4
454 * indent-tabs-mode: nil
455 * End:
456 */