blob: 9b2c71d2cfcc4fab606c0b610e9cb7a0c6bfe6e4 [file] [log] [blame]
bart0ab84fe2012-09-09 18:30:17 +00001
2/*--------------------------------------------------------------------*/
3/*--- Xen Hypercalls syswrap-xen.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2012 Citrix Systems
11 ian.campbell@citrix.com
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#include "pub_core_basics.h"
32#include "pub_core_vki.h"
bart51e61da2012-10-23 18:03:28 +000033
34#if defined(ENABLE_XEN)
35
bart0ab84fe2012-09-09 18:30:17 +000036#include "pub_core_vkiscnums.h"
37#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
38#include "pub_core_threadstate.h"
39#include "pub_core_aspacemgr.h"
40#include "pub_core_debuginfo.h" // VG_(di_notify_*)
41#include "pub_core_transtab.h" // VG_(discard_translations)
42#include "pub_core_xarray.h"
43#include "pub_core_clientstate.h"
44#include "pub_core_debuglog.h"
45#include "pub_core_libcbase.h"
46#include "pub_core_libcassert.h"
47#include "pub_core_libcfile.h"
48#include "pub_core_libcprint.h"
49#include "pub_core_libcproc.h"
50#include "pub_core_libcsignal.h"
51#include "pub_core_mallocfree.h"
52#include "pub_core_tooliface.h"
53#include "pub_core_options.h"
54#include "pub_core_scheduler.h"
55#include "pub_core_signals.h"
56#include "pub_core_syscall.h"
57#include "pub_core_syswrap.h"
58#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
59
60#include "priv_types_n_macros.h"
61#include "priv_syswrap-generic.h"
62#include "priv_syswrap-xen.h"
63
barta8f524c2012-10-15 18:44:18 +000064#include <inttypes.h>
bart0ab84fe2012-09-09 18:30:17 +000065
bart0ab84fe2012-09-09 18:30:17 +000066#define PRE(name) static DEFN_PRE_TEMPLATE(xen, name)
67#define POST(name) static DEFN_POST_TEMPLATE(xen, name)
68
69static void bad_subop ( ThreadId tid,
70 SyscallArgLayout* layout,
71 /*MOD*/SyscallArgs* args,
72 /*OUT*/SyscallStatus* status,
73 /*OUT*/UWord* flags,
florian6bd9dc12012-11-23 16:17:43 +000074 const HChar* hypercall,
bart0ab84fe2012-09-09 18:30:17 +000075 UWord subop)
76{
77 VG_(dmsg)("WARNING: unhandled %s subop: %ld\n",
78 hypercall, subop);
79 if (VG_(clo_verbosity) > 1) {
80 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
81 }
82 VG_(dmsg)("You may be able to write your own handler.\n");
83 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
84 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n");
85 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
86 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
87
88 SET_STATUS_Failure(VKI_ENOSYS);
89}
90
91PRE(memory_op)
92{
93 PRINT("__HYPERVISOR_memory_op ( %ld, %lx )", ARG1, ARG2);
94
95 switch (ARG1) {
bartbc8d9bd2013-12-01 10:53:05 +000096
97 case VKI_XENMEM_maximum_ram_page:
98 /* No inputs */
99 break;
100
bart3b700272013-12-01 10:53:34 +0000101 case VKI_XENMEM_maximum_gpfn:
102 PRE_MEM_READ("XENMEM_maximum_gpfn domid",
103 (Addr)ARG2, sizeof(vki_xen_domid_t));
104 break;
105
bart1d528a72013-12-01 10:54:06 +0000106 case VKI_XENMEM_machphys_mfn_list: {
107 struct vki_xen_machphys_mfn_list *arg =
108 (struct vki_xen_machphys_mfn_list *)ARG2;
109 PRE_MEM_READ("XENMEM_machphys_mfn_list max_extents",
110 (Addr)&arg->max_extents, sizeof(arg->max_extents));
111 PRE_MEM_READ("XENMEM_machphys_mfn_list extent_start",
112 (Addr)&arg->extent_start, sizeof(arg->extent_start));
113 break;
114 }
115
bart51e61da2012-10-23 18:03:28 +0000116 case VKI_XENMEM_set_memory_map: {
117 struct vki_xen_foreign_memory_map *arg =
118 (struct vki_xen_foreign_memory_map *)ARG2;
bart4409c9c2012-10-15 18:46:08 +0000119 PRE_MEM_READ("XENMEM_set_memory_map domid",
bart0ab84fe2012-09-09 18:30:17 +0000120 (Addr)&arg->domid, sizeof(arg->domid));
bart4409c9c2012-10-15 18:46:08 +0000121 PRE_MEM_READ("XENMEM_set_memory_map map",
bart0ab84fe2012-09-09 18:30:17 +0000122 (Addr)&arg->map, sizeof(arg->map));
123 break;
124 }
bart51e61da2012-10-23 18:03:28 +0000125 case VKI_XENMEM_increase_reservation:
126 case VKI_XENMEM_decrease_reservation:
bart68495eb2013-06-30 07:58:19 +0000127 case VKI_XENMEM_populate_physmap:
128 case VKI_XENMEM_claim_pages: {
bart0ab84fe2012-09-09 18:30:17 +0000129 struct xen_memory_reservation *memory_reservation =
bartda0a6c72012-10-15 18:45:28 +0000130 (struct xen_memory_reservation *)ARG2;
florian6bd9dc12012-11-23 16:17:43 +0000131 const HChar *which;
bart0ab84fe2012-09-09 18:30:17 +0000132
133 switch (ARG1) {
bart51e61da2012-10-23 18:03:28 +0000134 case VKI_XENMEM_increase_reservation:
bart0ab84fe2012-09-09 18:30:17 +0000135 which = "XENMEM_increase_reservation";
136 break;
bart51e61da2012-10-23 18:03:28 +0000137 case VKI_XENMEM_decrease_reservation:
bart0ab84fe2012-09-09 18:30:17 +0000138 which = "XENMEM_decrease_reservation";
139 PRE_MEM_READ(which,
140 (Addr)memory_reservation->extent_start.p,
bart51e61da2012-10-23 18:03:28 +0000141 sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
bartf68ba112012-10-15 18:44:59 +0000142 break;
bart51e61da2012-10-23 18:03:28 +0000143 case VKI_XENMEM_populate_physmap:
bart0ab84fe2012-09-09 18:30:17 +0000144 which = "XENMEM_populate_physmap";
145 PRE_MEM_READ(which,
146 (Addr)memory_reservation->extent_start.p,
bart51e61da2012-10-23 18:03:28 +0000147 sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
bart0ab84fe2012-09-09 18:30:17 +0000148 break;
bart68495eb2013-06-30 07:58:19 +0000149 case VKI_XENMEM_claim_pages:
150 which = "XENMEM_claim_pages";
151 break;
bart0ab84fe2012-09-09 18:30:17 +0000152 default:
153 which = "XENMEM_unknown";
154 break;
155 }
156
157 PRE_MEM_READ(which,
158 (Addr)&memory_reservation->extent_start,
159 sizeof(memory_reservation->extent_start));
160 PRE_MEM_READ(which,
161 (Addr)&memory_reservation->nr_extents,
162 sizeof(memory_reservation->nr_extents));
163 PRE_MEM_READ(which,
164 (Addr)&memory_reservation->extent_order,
165 sizeof(memory_reservation->extent_order));
166 PRE_MEM_READ(which,
167 (Addr)&memory_reservation->mem_flags,
168 sizeof(memory_reservation->mem_flags));
169 PRE_MEM_READ(which,
170 (Addr)&memory_reservation->domid,
171 sizeof(memory_reservation->domid));
172 break;
173 }
174
bart39d4ba52013-12-01 10:54:42 +0000175 case VKI_XENMEM_add_to_physmap: {
176 struct vki_xen_add_to_physmap *arg =
177 (struct vki_xen_add_to_physmap *)ARG2;
178 PRE_MEM_READ("XENMEM_add_to_physmap domid",
179 (Addr)&arg->domid, sizeof(arg->domid));
180 PRE_MEM_READ("XENMEM_add_to_physmap size",
181 (Addr)&arg->size, sizeof(arg->size));
182 PRE_MEM_READ("XENMEM_add_to_physmap space",
183 (Addr)&arg->space, sizeof(arg->space));
184 PRE_MEM_READ("XENMEM_add_to_physmap idx",
185 (Addr)&arg->idx, sizeof(arg->idx));
186 PRE_MEM_READ("XENMEM_add_to_physmap gpfn",
187 (Addr)&arg->gpfn, sizeof(arg->gpfn));
188 break;
189 };
190
bart9bd4cfc2013-12-01 10:55:13 +0000191 case VKI_XENMEM_remove_from_physmap: {
192 struct vki_xen_remove_from_physmap *arg =
193 (struct vki_xen_remove_from_physmap *)ARG2;
194 PRE_MEM_READ("XENMEM_remove_from_physmap domid",
195 (Addr)&arg->domid, sizeof(arg->domid));
196 PRE_MEM_READ("XENMEM_remove_from_physmap gpfn",
197 (Addr)&arg->gpfn, sizeof(arg->gpfn));
198 }
199
barta25a2bf2013-06-30 07:59:50 +0000200 case VKI_XENMEM_get_sharing_freed_pages:
201 case VKI_XENMEM_get_sharing_shared_pages:
202 break;
203
bart0ab84fe2012-09-09 18:30:17 +0000204 default:
205 bad_subop(tid, layout, arrghs, status, flags,
206 "__HYPERVISOR_memory_op", ARG1);
207 break;
208 }
209}
210
211PRE(mmuext_op)
212{
bart51e61da2012-10-23 18:03:28 +0000213 struct vki_xen_mmuext_op *ops = (struct vki_xen_mmuext_op *)ARG1;
bart0ab84fe2012-09-09 18:30:17 +0000214 unsigned int i, nr = ARG2;
215
bart0ab84fe2012-09-09 18:30:17 +0000216 for (i=0; i<nr; i++) {
bart51e61da2012-10-23 18:03:28 +0000217 struct vki_xen_mmuext_op *op = ops + i;
bart4409c9c2012-10-15 18:46:08 +0000218 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP cmd",
bart0ab84fe2012-09-09 18:30:17 +0000219 (Addr)&op->cmd, sizeof(op->cmd));
220 switch(op->cmd) {
bart51e61da2012-10-23 18:03:28 +0000221 case VKI_XEN_MMUEXT_PIN_L1_TABLE:
222 case VKI_XEN_MMUEXT_PIN_L2_TABLE:
223 case VKI_XEN_MMUEXT_PIN_L3_TABLE:
224 case VKI_XEN_MMUEXT_PIN_L4_TABLE:
225 case VKI_XEN_MMUEXT_UNPIN_TABLE:
226 case VKI_XEN_MMUEXT_NEW_BASEPTR:
227 case VKI_XEN_MMUEXT_CLEAR_PAGE:
228 case VKI_XEN_MMUEXT_COPY_PAGE:
229 case VKI_XEN_MMUEXT_MARK_SUPER:
230 case VKI_XEN_MMUEXT_UNMARK_SUPER:
bart0ab84fe2012-09-09 18:30:17 +0000231 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn",
232 (Addr)&op->arg1.mfn,
233 sizeof(op->arg1.mfn));
234 break;
235
bart51e61da2012-10-23 18:03:28 +0000236 case VKI_XEN_MMUEXT_INVLPG_LOCAL:
237 case VKI_XEN_MMUEXT_INVLPG_ALL:
238 case VKI_XEN_MMUEXT_SET_LDT:
bart0ab84fe2012-09-09 18:30:17 +0000239 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn",
240 (Addr)&op->arg1.linear_addr,
241 sizeof(op->arg1.linear_addr));
242 break;
243
bart51e61da2012-10-23 18:03:28 +0000244 case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL:
245 case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI:
246 case VKI_XEN_MMUEXT_INVLPG_MULTI:
247 case VKI_XEN_MMUEXT_TLB_FLUSH_ALL:
248 case VKI_XEN_MMUEXT_FLUSH_CACHE:
249 case VKI_XEN_MMUEXT_NEW_USER_BASEPTR:
250 case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL:
bart0ab84fe2012-09-09 18:30:17 +0000251 /* None */
252 break;
253 }
254
255 switch(op->cmd) {
bart51e61da2012-10-23 18:03:28 +0000256 case VKI_XEN_MMUEXT_SET_LDT:
bart0ab84fe2012-09-09 18:30:17 +0000257 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.nr_ents",
258 (Addr)&op->arg2.nr_ents,
259 sizeof(op->arg2.nr_ents));
260 break;
261
bart51e61da2012-10-23 18:03:28 +0000262 case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI:
263 case VKI_XEN_MMUEXT_INVLPG_MULTI:
bart0ab84fe2012-09-09 18:30:17 +0000264 /* How many??? */
265 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.vcpumask",
266 (Addr)&op->arg2.vcpumask,
267 sizeof(op->arg2.vcpumask));
268 break;
269
bart51e61da2012-10-23 18:03:28 +0000270 case VKI_XEN_MMUEXT_COPY_PAGE:
bart0ab84fe2012-09-09 18:30:17 +0000271 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.src_mfn",
272 (Addr)&op->arg2.src_mfn,
273 sizeof(op->arg2.src_mfn));
274 break;
275
bart51e61da2012-10-23 18:03:28 +0000276 case VKI_XEN_MMUEXT_PIN_L1_TABLE:
277 case VKI_XEN_MMUEXT_PIN_L2_TABLE:
278 case VKI_XEN_MMUEXT_PIN_L3_TABLE:
279 case VKI_XEN_MMUEXT_PIN_L4_TABLE:
280 case VKI_XEN_MMUEXT_UNPIN_TABLE:
281 case VKI_XEN_MMUEXT_NEW_BASEPTR:
282 case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL:
283 case VKI_XEN_MMUEXT_INVLPG_LOCAL:
284 case VKI_XEN_MMUEXT_TLB_FLUSH_ALL:
285 case VKI_XEN_MMUEXT_INVLPG_ALL:
286 case VKI_XEN_MMUEXT_FLUSH_CACHE:
287 case VKI_XEN_MMUEXT_NEW_USER_BASEPTR:
288 case VKI_XEN_MMUEXT_CLEAR_PAGE:
289 case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL:
290 case VKI_XEN_MMUEXT_MARK_SUPER:
291 case VKI_XEN_MMUEXT_UNMARK_SUPER:
bart0ab84fe2012-09-09 18:30:17 +0000292 /* None */
293 break;
294 }
295 }
296}
297
298static void pre_evtchn_op(ThreadId tid,
299 SyscallArgLayout* layout,
300 /*MOD*/SyscallArgs* arrghs,
301 /*OUT*/SyscallStatus* status,
302 /*OUT*/UWord* flags,
303 __vki_u32 cmd, void *arg, int compat)
304{
305 PRINT("__HYPERVISOR_event_channel_op%s ( %d, %p )",
306 compat ? "_compat" : "", cmd, arg);
307
308 switch (cmd) {
bart51e61da2012-10-23 18:03:28 +0000309 case VKI_XEN_EVTCHNOP_alloc_unbound: {
310 struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg;
bart4409c9c2012-10-15 18:46:08 +0000311 PRE_MEM_READ("EVTCHNOP_alloc_unbound dom",
bart0ab84fe2012-09-09 18:30:17 +0000312 (Addr)&alloc_unbound->dom, sizeof(alloc_unbound->dom));
bart4409c9c2012-10-15 18:46:08 +0000313 PRE_MEM_READ("EVTCHNOP_alloc_unbound remote_dom",
bart0ab84fe2012-09-09 18:30:17 +0000314 (Addr)&alloc_unbound->remote_dom,
315 sizeof(alloc_unbound->remote_dom));
316 break;
317 }
318 default:
319 if ( compat )
320 bad_subop(tid, layout, arrghs, status, flags,
321 "__HYPERVISOR_event_channel_op_compat", cmd);
322 else
323 bad_subop(tid, layout, arrghs, status, flags,
324 "__HYPERVISOR_event_channel_op", cmd);
325 break;
326 }
327}
328
329PRE(evtchn_op)
330{
331 pre_evtchn_op(tid, layout, arrghs, status, flags,
bartda0a6c72012-10-15 18:45:28 +0000332 ARG1, (void *)ARG2, 0);
bart0ab84fe2012-09-09 18:30:17 +0000333}
334
335PRE(evtchn_op_compat)
336{
bart51e61da2012-10-23 18:03:28 +0000337 struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1;
bart0ab84fe2012-09-09 18:30:17 +0000338 PRE_MEM_READ("__HYPERVISOR_event_channel_op_compat",
339 ARG1, sizeof(*evtchn));
340
341 pre_evtchn_op(tid, layout, arrghs, status, flags,
342 evtchn->cmd, &evtchn->u, 1);
343}
344
345PRE(xen_version)
346{
347 PRINT("__HYPERVISOR_xen_version ( %ld, %lx )", ARG1, ARG2);
348
349 switch (ARG1) {
bart51e61da2012-10-23 18:03:28 +0000350 case VKI_XENVER_version:
351 case VKI_XENVER_extraversion:
352 case VKI_XENVER_compile_info:
353 case VKI_XENVER_capabilities:
354 case VKI_XENVER_changeset:
355 case VKI_XENVER_platform_parameters:
356 case VKI_XENVER_get_features:
357 case VKI_XENVER_pagesize:
358 case VKI_XENVER_guest_handle:
359 case VKI_XENVER_commandline:
bart0ab84fe2012-09-09 18:30:17 +0000360 /* No inputs */
361 break;
362
363 default:
364 bad_subop(tid, layout, arrghs, status, flags,
365 "__HYPERVISOR_xen_version", ARG1);
366 break;
367 }
368}
369
370PRE(grant_table_op)
371{
372 PRINT("__HYPERVISOR_grant_table_op ( %ld, 0x%lx, %ld )", ARG1, ARG2, ARG3);
373 switch (ARG1) {
bart51e61da2012-10-23 18:03:28 +0000374 case VKI_XEN_GNTTABOP_setup_table: {
375 struct vki_xen_gnttab_setup_table *gst =
376 (struct vki_xen_gnttab_setup_table*)ARG2;
377 PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table dom",
bart4409c9c2012-10-15 18:46:08 +0000378 (Addr)&gst->dom, sizeof(gst->dom));
bart51e61da2012-10-23 18:03:28 +0000379 PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table nr_frames",
bart0ab84fe2012-09-09 18:30:17 +0000380 (Addr)&gst->nr_frames, sizeof(gst->nr_frames));
381 break;
382 }
383 default:
384 bad_subop(tid, layout, arrghs, status, flags,
385 "__HYPERVISOR_grant_table_op", ARG1);
386 break;
387 }
388}
389
390PRE(sysctl) {
bart51e61da2012-10-23 18:03:28 +0000391 struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1;
bart0ab84fe2012-09-09 18:30:17 +0000392
393 PRINT("__HYPERVISOR_sysctl ( %d )", sysctl->cmd);
394
395 /*
396 * Common part of xen_sysctl:
397 * uint32_t cmd;
398 * uint32_t interface_version;
399 */
400 PRE_MEM_READ("__HYPERVISOR_sysctl", ARG1,
bart51e61da2012-10-23 18:03:28 +0000401 sizeof(vki_uint32_t) + sizeof(vki_uint32_t));
bart0ab84fe2012-09-09 18:30:17 +0000402
barta8f524c2012-10-15 18:44:18 +0000403 if (!sysctl)
bart0ab84fe2012-09-09 18:30:17 +0000404 return;
405
bart51e61da2012-10-23 18:03:28 +0000406 switch (sysctl->interface_version)
407 {
408 case 0x00000008:
409 case 0x00000009:
bart68495eb2013-06-30 07:58:19 +0000410 case 0x0000000a:
bart51e61da2012-10-23 18:03:28 +0000411 break;
412 default:
413 VG_(dmsg)("WARNING: sysctl version %"PRIx32" not supported\n",
414 sysctl->interface_version);
barta8f524c2012-10-15 18:44:18 +0000415 if (VG_(clo_verbosity) > 1) {
416 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
417 }
418 VG_(dmsg)("You may be able to write your own handler.\n");
419 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
420 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n");
421 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
422 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
423
424 SET_STATUS_Failure(VKI_EINVAL);
425 return;
426 }
427
bart4409c9c2012-10-15 18:46:08 +0000428#define __PRE_XEN_SYSCTL_READ(_sysctl, _union, _field) \
429 PRE_MEM_READ("XEN_SYSCTL_" #_sysctl " u." #_union "." #_field, \
430 (Addr)&sysctl->u._union._field, \
bart0ab84fe2012-09-09 18:30:17 +0000431 sizeof(sysctl->u._union._field))
432#define PRE_XEN_SYSCTL_READ(_sysctl, _field) \
433 __PRE_XEN_SYSCTL_READ(_sysctl, _sysctl, _field)
434
435 switch (sysctl->cmd) {
bart029d48f2013-12-01 10:58:11 +0000436 case VKI_XEN_SYSCTL_readconsole:
437 /* These are all unconditionally read */
438 PRE_XEN_SYSCTL_READ(readconsole, clear);
439 PRE_XEN_SYSCTL_READ(readconsole, incremental);
440 PRE_XEN_SYSCTL_READ(readconsole, buffer);
441 PRE_XEN_SYSCTL_READ(readconsole, count);
442
443 /* 'index' only read if 'incremental' is nonzero */
444 if (sysctl->u.readconsole.incremental)
445 PRE_XEN_SYSCTL_READ(readconsole, index);
446 break;
447
bart51e61da2012-10-23 18:03:28 +0000448 case VKI_XEN_SYSCTL_getdomaininfolist:
449 switch (sysctl->interface_version)
450 {
451 case 0x00000008:
452 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, first_domain);
453 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, max_domains);
454 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, buffer);
455 break;
456 case 0x00000009:
457 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, first_domain);
458 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, max_domains);
459 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, buffer);
460 break;
bart5be3aec2013-12-01 10:51:19 +0000461 case 0x0000000a:
462 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, first_domain);
463 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, max_domains);
464 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, buffer);
465 break;
466 default:
467 VG_(dmsg)("WARNING: XEN_SYSCTL_getdomaininfolist for sysctl version "
468 "%"PRIx32" not implemented yet\n",
469 sysctl->interface_version);
470 SET_STATUS_Failure(VKI_EINVAL);
471 return;
bart51e61da2012-10-23 18:03:28 +0000472 }
bart0ab84fe2012-09-09 18:30:17 +0000473 break;
474
bart4cf567e2013-12-01 10:58:38 +0000475 case VKI_XEN_SYSCTL_debug_keys:
476 PRE_XEN_SYSCTL_READ(debug_keys, keys);
477 PRE_XEN_SYSCTL_READ(debug_keys, nr_keys);
478 PRE_MEM_READ("XEN_SYSCTL_debug_keys *keys",
479 (Addr)sysctl->u.debug_keys.keys.p,
480 sysctl->u.debug_keys.nr_keys * sizeof(char));
481 break;
482
bart431bad02013-06-30 07:59:09 +0000483 case VKI_XEN_SYSCTL_sched_id:
484 /* No inputs */
485 break;
486
bart51e61da2012-10-23 18:03:28 +0000487 case VKI_XEN_SYSCTL_cpupool_op:
bart0ab84fe2012-09-09 18:30:17 +0000488 PRE_XEN_SYSCTL_READ(cpupool_op, op);
489
490 switch(sysctl->u.cpupool_op.op) {
bart51e61da2012-10-23 18:03:28 +0000491 case VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE:
492 case VKI_XEN_SYSCTL_CPUPOOL_OP_DESTROY:
493 case VKI_XEN_SYSCTL_CPUPOOL_OP_INFO:
494 case VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU:
495 case VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU:
496 case VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN:
bart0ab84fe2012-09-09 18:30:17 +0000497 PRE_XEN_SYSCTL_READ(cpupool_op, cpupool_id);
498 }
499
bart51e61da2012-10-23 18:03:28 +0000500 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE)
bart0ab84fe2012-09-09 18:30:17 +0000501 PRE_XEN_SYSCTL_READ(cpupool_op, sched_id);
502
bart51e61da2012-10-23 18:03:28 +0000503 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN)
bart0ab84fe2012-09-09 18:30:17 +0000504 PRE_XEN_SYSCTL_READ(cpupool_op, domid);
505
bart51e61da2012-10-23 18:03:28 +0000506 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU ||
507 sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU)
bart0ab84fe2012-09-09 18:30:17 +0000508 PRE_XEN_SYSCTL_READ(cpupool_op, cpu);
509
510 break;
511
bart51e61da2012-10-23 18:03:28 +0000512 case VKI_XEN_SYSCTL_physinfo:
bart0ab84fe2012-09-09 18:30:17 +0000513 /* No input params */
514 break;
515
bart51e61da2012-10-23 18:03:28 +0000516 case VKI_XEN_SYSCTL_topologyinfo:
bart0ab84fe2012-09-09 18:30:17 +0000517 PRE_XEN_SYSCTL_READ(topologyinfo, max_cpu_index);
518 PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_core);
519 PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_socket);
520 PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_node);
521 break;
522
bart51e61da2012-10-23 18:03:28 +0000523 case VKI_XEN_SYSCTL_numainfo:
bart0ab84fe2012-09-09 18:30:17 +0000524 PRE_XEN_SYSCTL_READ(numainfo, max_node_index);
525 PRE_XEN_SYSCTL_READ(numainfo, node_to_memsize);
526 PRE_XEN_SYSCTL_READ(numainfo, node_to_memfree);
527 PRE_XEN_SYSCTL_READ(numainfo, node_to_node_distance);
528 break;
529
530 default:
531 bad_subop(tid, layout, arrghs, status, flags,
532 "__HYPERVISOR_sysctl", sysctl->cmd);
533 break;
534 }
535#undef PRE_XEN_SYSCTL_READ
536#undef __PRE_XEN_SYSCTL_READ
537}
538
539PRE(domctl)
540{
bart51e61da2012-10-23 18:03:28 +0000541 struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1;
bart0ab84fe2012-09-09 18:30:17 +0000542
543 PRINT("__HYPERVISOR_domctl ( %d ) on dom%d", domctl->cmd, domctl->domain);
544
545 /*
546 * Common part of xen_domctl:
bart51e61da2012-10-23 18:03:28 +0000547 * vki_uint32_t cmd;
548 * vki_uint32_t interface_version;
549 * vki_xen_domid_t domain;
bart0ab84fe2012-09-09 18:30:17 +0000550 */
551 PRE_MEM_READ("__HYPERVISOR_domctl", ARG1,
bart51e61da2012-10-23 18:03:28 +0000552 sizeof(vki_uint32_t) + sizeof(vki_uint32_t)
553 + sizeof(vki_xen_domid_t));
bart0ab84fe2012-09-09 18:30:17 +0000554
barta8f524c2012-10-15 18:44:18 +0000555 if (!domctl)
bart0ab84fe2012-09-09 18:30:17 +0000556 return;
557
bart51e61da2012-10-23 18:03:28 +0000558 switch (domctl->interface_version)
559 {
560 case 0x00000007:
561 case 0x00000008:
bart68495eb2013-06-30 07:58:19 +0000562 case 0x00000009:
bart51e61da2012-10-23 18:03:28 +0000563 break;
564 default:
565 VG_(dmsg)("WARNING: domctl version %"PRIx32" not supported\n",
566 domctl->interface_version);
barta8f524c2012-10-15 18:44:18 +0000567 if (VG_(clo_verbosity) > 1) {
568 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
569 }
570 VG_(dmsg)("You may be able to write your own handler.\n");
571 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
572 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n");
573 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
574 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
575
576 SET_STATUS_Failure(VKI_EINVAL);
577 return;
578 }
579
bart4409c9c2012-10-15 18:46:08 +0000580#define __PRE_XEN_DOMCTL_READ(_domctl, _union, _field) \
581 PRE_MEM_READ("XEN_DOMCTL_" #_domctl " u." #_union "." #_field, \
582 (Addr)&domctl->u._union._field, \
bart0ab84fe2012-09-09 18:30:17 +0000583 sizeof(domctl->u._union._field))
584#define PRE_XEN_DOMCTL_READ(_domctl, _field) \
585 __PRE_XEN_DOMCTL_READ(_domctl, _domctl, _field)
586
587 switch (domctl->cmd) {
bart51e61da2012-10-23 18:03:28 +0000588 case VKI_XEN_DOMCTL_destroydomain:
589 case VKI_XEN_DOMCTL_pausedomain:
590 case VKI_XEN_DOMCTL_max_vcpus:
591 case VKI_XEN_DOMCTL_get_address_size:
592 case VKI_XEN_DOMCTL_gettscinfo:
593 case VKI_XEN_DOMCTL_getdomaininfo:
594 case VKI_XEN_DOMCTL_unpausedomain:
bart0ab84fe2012-09-09 18:30:17 +0000595 /* No input fields. */
596 break;
597
bart51e61da2012-10-23 18:03:28 +0000598 case VKI_XEN_DOMCTL_createdomain:
bart0ab84fe2012-09-09 18:30:17 +0000599 PRE_XEN_DOMCTL_READ(createdomain, ssidref);
600 PRE_XEN_DOMCTL_READ(createdomain, handle);
601 PRE_XEN_DOMCTL_READ(createdomain, flags);
602 break;
603
barte65212e2013-12-01 10:55:54 +0000604 case VKI_XEN_DOMCTL_gethvmcontext:
605 /* Xen unconditionally reads the 'buffer' pointer */
606 __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, buffer);
607 /* Xen only consumes 'size' if 'buffer' is non NULL. A NULL
608 * buffer is a request for the required size. */
609 if ( domctl->u.hvmcontext.buffer.p )
610 __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, size);
611 break;
612
bart8583a2a2013-12-01 10:57:14 +0000613 case VKI_XEN_DOMCTL_sethvmcontext:
614 __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, size);
615 __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, buffer);
616 PRE_MEM_READ("XEN_DOMCTL_sethvmcontext *buffer",
617 (Addr)domctl->u.hvmcontext.buffer.p,
618 domctl->u.hvmcontext.size);
619 break;
620
bart51e61da2012-10-23 18:03:28 +0000621 case VKI_XEN_DOMCTL_max_mem:
bart0ab84fe2012-09-09 18:30:17 +0000622 PRE_XEN_DOMCTL_READ(max_mem, max_memkb);
623 break;
624
bart51e61da2012-10-23 18:03:28 +0000625 case VKI_XEN_DOMCTL_set_address_size:
bart0ab84fe2012-09-09 18:30:17 +0000626 __PRE_XEN_DOMCTL_READ(set_address_size, address_size, size);
627 break;
628
bart51e61da2012-10-23 18:03:28 +0000629 case VKI_XEN_DOMCTL_settscinfo:
bart0ab84fe2012-09-09 18:30:17 +0000630 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.tsc_mode);
631 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.gtsc_khz);
632 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.incarnation);
633 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.elapsed_nsec);
634 break;
635
bart51e61da2012-10-23 18:03:28 +0000636 case VKI_XEN_DOMCTL_hypercall_init:
bart0ab84fe2012-09-09 18:30:17 +0000637 PRE_XEN_DOMCTL_READ(hypercall_init, gmfn);
638 break;
639
bart51e61da2012-10-23 18:03:28 +0000640 case VKI_XEN_DOMCTL_getvcpuinfo:
bart0ab84fe2012-09-09 18:30:17 +0000641 PRE_XEN_DOMCTL_READ(getvcpuinfo, vcpu);
642 break;
643
bart51e61da2012-10-23 18:03:28 +0000644 case VKI_XEN_DOMCTL_scheduler_op:
bart0ab84fe2012-09-09 18:30:17 +0000645 PRE_XEN_DOMCTL_READ(scheduler_op, sched_id);
646 PRE_XEN_DOMCTL_READ(scheduler_op, cmd);
bart51e61da2012-10-23 18:03:28 +0000647 if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_putinfo ) {
bart0ab84fe2012-09-09 18:30:17 +0000648 switch(domctl->u.scheduler_op.sched_id) {
bart51e61da2012-10-23 18:03:28 +0000649 case VKI_XEN_SCHEDULER_SEDF:
bart0ab84fe2012-09-09 18:30:17 +0000650 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.period);
651 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.slice);
652 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.latency);
653 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.extratime);
654 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.weight);
655 break;
bart51e61da2012-10-23 18:03:28 +0000656 case VKI_XEN_SCHEDULER_CREDIT:
bart0ab84fe2012-09-09 18:30:17 +0000657 PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.weight);
658 PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.cap);
659 break;
bart51e61da2012-10-23 18:03:28 +0000660 case VKI_XEN_SCHEDULER_CREDIT2:
bart0ab84fe2012-09-09 18:30:17 +0000661 PRE_XEN_DOMCTL_READ(scheduler_op, u.credit2.weight);
662 break;
bart51e61da2012-10-23 18:03:28 +0000663 case VKI_XEN_SCHEDULER_ARINC653:
bart0ab84fe2012-09-09 18:30:17 +0000664 break;
665 }
666 }
667 break;
668
bart51e61da2012-10-23 18:03:28 +0000669 case VKI_XEN_DOMCTL_getvcpuaffinity:
bart0ab84fe2012-09-09 18:30:17 +0000670 __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity, vcpu);
671 break;
672
bart51e61da2012-10-23 18:03:28 +0000673 case VKI_XEN_DOMCTL_setvcpuaffinity:
bart0ab84fe2012-09-09 18:30:17 +0000674 __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity, vcpu);
bart4409c9c2012-10-15 18:46:08 +0000675 PRE_MEM_READ("XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap.bitmap",
bart0ab84fe2012-09-09 18:30:17 +0000676 (Addr)domctl->u.vcpuaffinity.cpumap.bitmap.p,
bart68495eb2013-06-30 07:58:19 +0000677 domctl->u.vcpuaffinity.cpumap.nr_bits / 8);
678 break;
679
680 case VKI_XEN_DOMCTL_getnodeaffinity:
681 __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
682 break;
683 case VKI_XEN_DOMCTL_setnodeaffinity:
684 __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
685 PRE_MEM_READ("XEN_DOMCTL_setnodeaffinity u.nodeaffinity.cpumap.bitmap",
686 (Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
687 domctl->u.nodeaffinity.nodemap.nr_bits / 8);
bart0ab84fe2012-09-09 18:30:17 +0000688 break;
689
bart51e61da2012-10-23 18:03:28 +0000690 case VKI_XEN_DOMCTL_getvcpucontext:
bart0ab84fe2012-09-09 18:30:17 +0000691 __PRE_XEN_DOMCTL_READ(getvcpucontext, vcpucontext, vcpu);
692 break;
693
bart51e61da2012-10-23 18:03:28 +0000694 case VKI_XEN_DOMCTL_setvcpucontext:
bart0ab84fe2012-09-09 18:30:17 +0000695 __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, vcpu);
696 __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, ctxt.p);
697 break;
698
bart51e61da2012-10-23 18:03:28 +0000699 case VKI_XEN_DOMCTL_set_cpuid:
bart4409c9c2012-10-15 18:46:08 +0000700 PRE_MEM_READ("XEN_DOMCTL_set_cpuid u.cpuid",
bart0ab84fe2012-09-09 18:30:17 +0000701 (Addr)&domctl->u.cpuid, sizeof(domctl->u.cpuid));
702 break;
703
bart14c44a92013-12-01 10:56:28 +0000704 case VKI_XEN_DOMCTL_getpageframeinfo3:
705 PRE_XEN_DOMCTL_READ(getpageframeinfo3, num);
706 PRE_XEN_DOMCTL_READ(getpageframeinfo3, array.p);
707 PRE_MEM_READ("XEN_DOMCTL_getpageframeinfo3 *u.getpageframeinfo3.array.p",
708 (Addr)domctl->u.getpageframeinfo3.array.p,
709 domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
710 break;
711
bart51e61da2012-10-23 18:03:28 +0000712 case VKI_XEN_DOMCTL_getvcpuextstate:
bart0ab84fe2012-09-09 18:30:17 +0000713 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, vcpu);
714 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, xfeature_mask);
715 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, size);
716 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, buffer);
717 break;
718
bart189ade72013-12-01 10:57:43 +0000719 case VKI_XEN_DOMCTL_shadow_op:
720 PRE_XEN_DOMCTL_READ(shadow_op, op);
721
722 switch(domctl->u.shadow_op.op)
723 {
724 case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
725 /* No further inputs */
726 break;
727
728 case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE:
729 PRE_XEN_DOMCTL_READ(shadow_op, mode);
730 switch(domctl->u.shadow_op.mode)
731 {
732 case XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY:
733 goto domctl_shadow_op_enable_logdirty;
734
735
736 default:
737 bad_subop(tid, layout, arrghs, status, flags,
738 "__HYPERVISOR_domctl shadowop mode",
739 domctl->u.shadow_op.mode);
740 break;
741 }
742
743 case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:
744 domctl_shadow_op_enable_logdirty:
745 /* No further inputs */
746 break;
747
748 case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
749 case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
750 PRE_XEN_DOMCTL_READ(shadow_op, dirty_bitmap);
751 PRE_XEN_DOMCTL_READ(shadow_op, pages);
752 break;
753
754 default:
755 bad_subop(tid, layout, arrghs, status, flags,
756 "__HYPERVISOR_domctl shadow(10)",
757 domctl->u.shadow_op.op);
758 break;
759 }
760 break;
761
bart03f77d22013-12-01 10:59:07 +0000762 case VKI_XEN_DOMCTL_set_max_evtchn:
763 PRE_XEN_DOMCTL_READ(set_max_evtchn, max_port);
764 break;
765
bart0ab84fe2012-09-09 18:30:17 +0000766 default:
767 bad_subop(tid, layout, arrghs, status, flags,
768 "__HYPERVISOR_domctl", domctl->cmd);
769 break;
770 }
771#undef PRE_XEN_DOMCTL_READ
772#undef __PRE_XEN_DOMCTL_READ
773}
774
775PRE(hvm_op)
776{
777 unsigned long op = ARG1;
778 void *arg = (void *)(unsigned long)ARG2;
779
780 PRINT("__HYPERVISOR_hvm_op ( %ld, %p )", op, arg);
781
782#define __PRE_XEN_HVMOP_READ(_hvm_op, _type, _field) \
bart4409c9c2012-10-15 18:46:08 +0000783 PRE_MEM_READ("XEN_HVMOP_" # _hvm_op " " #_field, \
bart0ab84fe2012-09-09 18:30:17 +0000784 (Addr)&((_type*)arg)->_field, \
785 sizeof(((_type*)arg)->_field))
786#define PRE_XEN_HVMOP_READ(_hvm_op, _field) \
bartb1055aa2014-05-01 08:02:39 +0000787 __PRE_XEN_HVMOP_READ(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
bart0ab84fe2012-09-09 18:30:17 +0000788
789 switch (op) {
bart51e61da2012-10-23 18:03:28 +0000790 case VKI_XEN_HVMOP_set_param:
791 __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, domid);
792 __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, index);
793 __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, value);
bart0ab84fe2012-09-09 18:30:17 +0000794 break;
795
bart51e61da2012-10-23 18:03:28 +0000796 case VKI_XEN_HVMOP_get_param:
797 __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, domid);
798 __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, index);
bart0ab84fe2012-09-09 18:30:17 +0000799 break;
800
801 default:
802 bad_subop(tid, layout, arrghs, status, flags,
803 "__HYPERVISOR_hvm_op", op);
804 break;
805 }
806#undef __PRE_XEN_HVMOP_READ
807#undef PRE_XEN_HVMOP_READ
808}
809
bart3b35a082013-12-01 10:52:22 +0000810PRE(tmem_op)
811{
812 struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
813
814 PRINT("__HYPERVISOR_tmem_op ( %d )", tmem->cmd);
815
816 /* Common part for xen_tmem_op:
817 * vki_uint32_t cmd;
818 */
819 PRE_MEM_READ("__HYPERVISOR_tmem_op cmd", ARG1, sizeof(vki_uint32_t));
820
821
822#define __PRE_XEN_TMEMOP_READ(_tmem, _union, _field) \
823 PRE_MEM_READ("XEN_tmem_op_" #_tmem " u." #_union "." #_field, \
824 (Addr)&tmem->u._union._field, \
825 sizeof(tmem->u._union._field))
826#define PRE_XEN_TMEMOP_READ(_tmem, _field) \
827 __PRE_XEN_TMEMOP_READ(_tmem, _tmem, _field)
828
829 switch(tmem->cmd) {
830
831 case VKI_XEN_TMEM_control:
832
833 /* Common part for control hypercall:
834 * vki_int32_t pool_id;
835 * vki_uint32_t subop;
836 */
837 PRE_MEM_READ("__HYPERVISOR_tmem_op pool_id",
838 (Addr)&tmem->pool_id, sizeof(&tmem->pool_id));
839 PRE_XEN_TMEMOP_READ(ctrl, subop);
840
841 switch (tmem->u.ctrl.subop) {
842
843 case VKI_XEN_TMEMC_save_begin:
844 PRE_XEN_TMEMOP_READ(ctrl, cli_id);
845 PRE_XEN_TMEMOP_READ(ctrl, arg1);
846 PRE_XEN_TMEMOP_READ(ctrl, buf);
847 break;
848
849 default:
850 bad_subop(tid, layout, arrghs, status, flags,
851 "__HYPERVISOR_tmem_op_control", tmem->u.ctrl.subop);
852 }
853
854 break;
855
856 default:
857 bad_subop(tid, layout, arrghs, status, flags,
858 "__HYPERVISOR_tmem_op", ARG1);
859 }
860
861#undef PRE_XEN_TMEMOP_READ
862#undef __PRE_XEN_TMEMOP_READ
863}
864
bart0ab84fe2012-09-09 18:30:17 +0000865POST(memory_op)
866{
867 switch (ARG1) {
bartbc8d9bd2013-12-01 10:53:05 +0000868 case VKI_XENMEM_maximum_ram_page:
bart51e61da2012-10-23 18:03:28 +0000869 case VKI_XENMEM_set_memory_map:
870 case VKI_XENMEM_decrease_reservation:
bart68495eb2013-06-30 07:58:19 +0000871 case VKI_XENMEM_claim_pages:
bart3b700272013-12-01 10:53:34 +0000872 case VKI_XENMEM_maximum_gpfn:
bart9bd4cfc2013-12-01 10:55:13 +0000873 case VKI_XENMEM_remove_from_physmap:
bart0ab84fe2012-09-09 18:30:17 +0000874 /* No outputs */
875 break;
bart51e61da2012-10-23 18:03:28 +0000876 case VKI_XENMEM_increase_reservation:
877 case VKI_XENMEM_populate_physmap: {
bart0ab84fe2012-09-09 18:30:17 +0000878 struct xen_memory_reservation *memory_reservation =
bartda0a6c72012-10-15 18:45:28 +0000879 (struct xen_memory_reservation *)ARG2;
bart0ab84fe2012-09-09 18:30:17 +0000880
881 POST_MEM_WRITE((Addr)memory_reservation->extent_start.p,
bart51e61da2012-10-23 18:03:28 +0000882 sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
bart0ab84fe2012-09-09 18:30:17 +0000883 break;
884 }
barta25a2bf2013-06-30 07:59:50 +0000885
bart1d528a72013-12-01 10:54:06 +0000886 case VKI_XENMEM_machphys_mfn_list: {
887 struct vki_xen_machphys_mfn_list *arg =
888 (struct vki_xen_machphys_mfn_list *)ARG2;
889 POST_MEM_WRITE((Addr)&arg->nr_extents, sizeof(arg->nr_extents));
890 POST_MEM_WRITE((Addr)arg->extent_start.p,
891 sizeof(vki_xen_pfn_t) * arg->nr_extents);
892 break;
893 }
894
bart39d4ba52013-12-01 10:54:42 +0000895 case VKI_XENMEM_add_to_physmap: {
896 struct vki_xen_add_to_physmap *arg =
897 (struct vki_xen_add_to_physmap *)ARG2;
898 if (arg->space == VKI_XENMAPSPACE_gmfn_range)
899 POST_MEM_WRITE(ARG2, sizeof(*arg));
900 }
901
barta25a2bf2013-06-30 07:59:50 +0000902 case VKI_XENMEM_get_sharing_freed_pages:
903 case VKI_XENMEM_get_sharing_shared_pages:
904 /* No outputs */
905 break;
bart0ab84fe2012-09-09 18:30:17 +0000906 }
907}
908
909POST(mmuext_op)
910{
bartda0a6c72012-10-15 18:45:28 +0000911 unsigned int *pdone = (unsigned int *)ARG3;
bart0ab84fe2012-09-09 18:30:17 +0000912 /* simplistic */
913 POST_MEM_WRITE((Addr)pdone, sizeof(*pdone));
914}
915
916static void post_evtchn_op(ThreadId tid, __vki_u32 cmd, void *arg, int compat)
917{
918 switch (cmd) {
bart51e61da2012-10-23 18:03:28 +0000919 case VKI_XEN_EVTCHNOP_alloc_unbound: {
920 struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg;
bart0ab84fe2012-09-09 18:30:17 +0000921 POST_MEM_WRITE((Addr)&alloc_unbound->port, sizeof(alloc_unbound->port));
922 break;
923 }
924 }
925}
926
927POST(evtchn_op)
928{
bartda0a6c72012-10-15 18:45:28 +0000929 post_evtchn_op(tid, ARG1, (void *)ARG2, 0);
bart0ab84fe2012-09-09 18:30:17 +0000930}
931
932POST(evtchn_op_compat)
933{
bart51e61da2012-10-23 18:03:28 +0000934 struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1;
bart0ab84fe2012-09-09 18:30:17 +0000935 post_evtchn_op(tid, evtchn->cmd, &evtchn->u, 1);
936}
937
938POST(xen_version)
939{
940 switch (ARG1) {
bart51e61da2012-10-23 18:03:28 +0000941 case VKI_XENVER_version:
bart0ab84fe2012-09-09 18:30:17 +0000942 /* No outputs */
943 break;
bart51e61da2012-10-23 18:03:28 +0000944 case VKI_XENVER_extraversion:
945 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_extraversion_t));
bart0ab84fe2012-09-09 18:30:17 +0000946 break;
bart51e61da2012-10-23 18:03:28 +0000947 case VKI_XENVER_compile_info:
948 POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_compile_info));
bart0ab84fe2012-09-09 18:30:17 +0000949 break;
bart51e61da2012-10-23 18:03:28 +0000950 case VKI_XENVER_capabilities:
951 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_capabilities_info_t));
bart0ab84fe2012-09-09 18:30:17 +0000952 break;
bart51e61da2012-10-23 18:03:28 +0000953 case VKI_XENVER_changeset:
954 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_changeset_info_t));
bart0ab84fe2012-09-09 18:30:17 +0000955 break;
bart51e61da2012-10-23 18:03:28 +0000956 case VKI_XENVER_platform_parameters:
957 POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_platform_parameters));
bart0ab84fe2012-09-09 18:30:17 +0000958 break;
bart51e61da2012-10-23 18:03:28 +0000959 case VKI_XENVER_get_features:
960 POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_feature_info));
bart0ab84fe2012-09-09 18:30:17 +0000961 break;
bart51e61da2012-10-23 18:03:28 +0000962 case VKI_XENVER_pagesize:
bart0ab84fe2012-09-09 18:30:17 +0000963 /* No outputs */
964 break;
bart51e61da2012-10-23 18:03:28 +0000965 case VKI_XENVER_guest_handle:
966 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_domain_handle_t));
bart0ab84fe2012-09-09 18:30:17 +0000967 break;
bart51e61da2012-10-23 18:03:28 +0000968 case VKI_XENVER_commandline:
969 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_commandline_t));
bart0ab84fe2012-09-09 18:30:17 +0000970 break;
971 }
972}
973
974POST(grant_table_op)
975{
976 switch (ARG1) {
bart51e61da2012-10-23 18:03:28 +0000977 case VKI_XEN_GNTTABOP_setup_table: {
978 struct vki_xen_gnttab_setup_table *gst =
979 (struct vki_xen_gnttab_setup_table*)ARG2;
980 PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
bart0ab84fe2012-09-09 18:30:17 +0000981 (Addr)&gst->status, sizeof(gst->status));
bart51e61da2012-10-23 18:03:28 +0000982 PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
bart0ab84fe2012-09-09 18:30:17 +0000983 (Addr)gst->frame_list.p,
984 sizeof(*gst->frame_list.p) & gst->nr_frames);
985 break;
986 }
987 }
988}
989
990POST(sysctl)
991{
bart51e61da2012-10-23 18:03:28 +0000992 struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1;
bart0ab84fe2012-09-09 18:30:17 +0000993
bart51e61da2012-10-23 18:03:28 +0000994 switch (sysctl->interface_version)
995 {
996 case 0x00000008:
997 case 0x00000009:
bart68495eb2013-06-30 07:58:19 +0000998 case 0x0000000a:
bart51e61da2012-10-23 18:03:28 +0000999 break;
1000 default:
bart0ab84fe2012-09-09 18:30:17 +00001001 return;
bart51e61da2012-10-23 18:03:28 +00001002 }
bart0ab84fe2012-09-09 18:30:17 +00001003
1004#define __POST_XEN_SYSCTL_WRITE(_sysctl, _union, _field) \
1005 POST_MEM_WRITE((Addr)&sysctl->u._union._field, \
1006 sizeof(sysctl->u._union._field))
1007#define POST_XEN_SYSCTL_WRITE(_sysctl, _field) \
1008 __POST_XEN_SYSCTL_WRITE(_sysctl, _sysctl, _field)
1009
1010 switch (sysctl->cmd) {
bart029d48f2013-12-01 10:58:11 +00001011 case VKI_XEN_SYSCTL_readconsole:
1012 POST_MEM_WRITE((Addr)sysctl->u.readconsole.buffer.p,
1013 sysctl->u.readconsole.count * sizeof(char));
1014 break;
1015
bart51e61da2012-10-23 18:03:28 +00001016 case VKI_XEN_SYSCTL_getdomaininfolist:
1017 switch (sysctl->interface_version)
1018 {
1019 case 0x00000008:
1020 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000008, num_domains);
1021 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000008.buffer.p,
1022 sizeof(*sysctl->u.getdomaininfolist_00000008.buffer.p)
1023 * sysctl->u.getdomaininfolist_00000008.num_domains);
1024 break;
1025 case 0x00000009:
1026 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000009, num_domains);
1027 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000009.buffer.p,
1028 sizeof(*sysctl->u.getdomaininfolist_00000009.buffer.p)
1029 * sysctl->u.getdomaininfolist_00000009.num_domains);
1030 break;
bart5be3aec2013-12-01 10:51:19 +00001031 case 0x0000000a:
1032 POST_XEN_SYSCTL_WRITE(getdomaininfolist_0000000a, num_domains);
1033 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_0000000a.buffer.p,
1034 sizeof(*sysctl->u.getdomaininfolist_0000000a.buffer.p)
1035 * sysctl->u.getdomaininfolist_0000000a.num_domains);
1036 break;
bart51e61da2012-10-23 18:03:28 +00001037 }
bart0ab84fe2012-09-09 18:30:17 +00001038 break;
1039
bart431bad02013-06-30 07:59:09 +00001040 case VKI_XEN_SYSCTL_sched_id:
1041 POST_XEN_SYSCTL_WRITE(sched_id, sched_id);
1042 break;
1043
bart51e61da2012-10-23 18:03:28 +00001044 case VKI_XEN_SYSCTL_cpupool_op:
1045 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE ||
1046 sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO)
bart0ab84fe2012-09-09 18:30:17 +00001047 POST_XEN_SYSCTL_WRITE(cpupool_op, cpupool_id);
bart51e61da2012-10-23 18:03:28 +00001048 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO) {
bart0ab84fe2012-09-09 18:30:17 +00001049 POST_XEN_SYSCTL_WRITE(cpupool_op, sched_id);
1050 POST_XEN_SYSCTL_WRITE(cpupool_op, n_dom);
1051 }
bart51e61da2012-10-23 18:03:28 +00001052 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO ||
1053 sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_FREEINFO)
bart0ab84fe2012-09-09 18:30:17 +00001054 POST_XEN_SYSCTL_WRITE(cpupool_op, cpumap);
1055 break;
1056
bart51e61da2012-10-23 18:03:28 +00001057 case VKI_XEN_SYSCTL_physinfo:
bart68495eb2013-06-30 07:58:19 +00001058 switch (sysctl->interface_version)
1059 {
1060 case 0x00000008:
1061 case 0x00000009: /* Unchanged from version 8 */
1062 POST_XEN_SYSCTL_WRITE(physinfo_00000008, threads_per_core);
1063 POST_XEN_SYSCTL_WRITE(physinfo_00000008, cores_per_socket);
1064 POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_cpus);
1065 POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_cpu_id);
1066 POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_nodes);
1067 POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_node_id);
1068 POST_XEN_SYSCTL_WRITE(physinfo_00000008, cpu_khz);
1069 POST_XEN_SYSCTL_WRITE(physinfo_00000008, total_pages);
1070 POST_XEN_SYSCTL_WRITE(physinfo_00000008, free_pages);
1071 POST_XEN_SYSCTL_WRITE(physinfo_00000008, scrub_pages);
1072 POST_XEN_SYSCTL_WRITE(physinfo_00000008, hw_cap[8]);
1073 POST_XEN_SYSCTL_WRITE(physinfo_00000008, capabilities);
1074 break;
1075 case 0x0000000a:
1076 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, threads_per_core);
1077 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cores_per_socket);
1078 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_cpus);
1079 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_cpu_id);
1080 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_nodes);
1081 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_node_id);
1082 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cpu_khz);
1083 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, total_pages);
1084 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, free_pages);
1085 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, scrub_pages);
1086 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, outstanding_pages);
1087 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, hw_cap[8]);
1088 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, capabilities);
1089 break;
1090 }
bart0ab84fe2012-09-09 18:30:17 +00001091 break;
1092
bart51e61da2012-10-23 18:03:28 +00001093 case VKI_XEN_SYSCTL_topologyinfo:
bart0ab84fe2012-09-09 18:30:17 +00001094 POST_XEN_SYSCTL_WRITE(topologyinfo, max_cpu_index);
barta8f524c2012-10-15 18:44:18 +00001095 if (sysctl->u.topologyinfo.cpu_to_core.p)
1096 POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_core.p,
bart0ab84fe2012-09-09 18:30:17 +00001097 sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
barta8f524c2012-10-15 18:44:18 +00001098 if (sysctl->u.topologyinfo.cpu_to_socket.p)
1099 POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_socket.p,
bart0ab84fe2012-09-09 18:30:17 +00001100 sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
barta8f524c2012-10-15 18:44:18 +00001101 if (sysctl->u.topologyinfo.cpu_to_node.p)
1102 POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_node.p,
bart0ab84fe2012-09-09 18:30:17 +00001103 sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
1104 break;
1105
bart51e61da2012-10-23 18:03:28 +00001106 case VKI_XEN_SYSCTL_numainfo:
bart0ab84fe2012-09-09 18:30:17 +00001107 POST_XEN_SYSCTL_WRITE(numainfo, max_node_index);
1108 POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memsize.p,
1109 sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
1110 POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memfree.p,
1111 sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
1112 POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_node_distance.p,
1113 sizeof(uint32_t) * sysctl->u.numainfo.max_node_index);
florian39d8b542013-01-21 13:46:57 +00001114 break;
bart4cf567e2013-12-01 10:58:38 +00001115
1116 /* No outputs */
1117 case VKI_XEN_SYSCTL_debug_keys:
1118 break;
bart0ab84fe2012-09-09 18:30:17 +00001119 }
1120#undef POST_XEN_SYSCTL_WRITE
1121#undef __POST_XEN_SYSCTL_WRITE
1122}
1123
1124POST(domctl){
bart51e61da2012-10-23 18:03:28 +00001125 struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1;
bart0ab84fe2012-09-09 18:30:17 +00001126
bart51e61da2012-10-23 18:03:28 +00001127 switch (domctl->interface_version) {
1128 case 0x00000007:
1129 case 0x00000008:
bart68495eb2013-06-30 07:58:19 +00001130 case 0x00000009:
bart51e61da2012-10-23 18:03:28 +00001131 break;
1132 default:
1133 return;
1134 }
bart0ab84fe2012-09-09 18:30:17 +00001135
1136#define __POST_XEN_DOMCTL_WRITE(_domctl, _union, _field) \
1137 POST_MEM_WRITE((Addr)&domctl->u._union._field, \
1138 sizeof(domctl->u._union._field));
1139#define POST_XEN_DOMCTL_WRITE(_domctl, _field) \
1140 __POST_XEN_DOMCTL_WRITE(_domctl, _domctl, _field)
1141
1142 switch (domctl->cmd) {
bart51e61da2012-10-23 18:03:28 +00001143 case VKI_XEN_DOMCTL_createdomain:
1144 case VKI_XEN_DOMCTL_destroydomain:
1145 case VKI_XEN_DOMCTL_pausedomain:
1146 case VKI_XEN_DOMCTL_max_mem:
1147 case VKI_XEN_DOMCTL_set_address_size:
1148 case VKI_XEN_DOMCTL_settscinfo:
1149 case VKI_XEN_DOMCTL_hypercall_init:
1150 case VKI_XEN_DOMCTL_setvcpuaffinity:
1151 case VKI_XEN_DOMCTL_setvcpucontext:
bart68495eb2013-06-30 07:58:19 +00001152 case VKI_XEN_DOMCTL_setnodeaffinity:
bart51e61da2012-10-23 18:03:28 +00001153 case VKI_XEN_DOMCTL_set_cpuid:
1154 case VKI_XEN_DOMCTL_unpausedomain:
bart8583a2a2013-12-01 10:57:14 +00001155 case VKI_XEN_DOMCTL_sethvmcontext:
bart03f77d22013-12-01 10:59:07 +00001156 case VKI_XEN_DOMCTL_set_max_evtchn:
bart0ab84fe2012-09-09 18:30:17 +00001157 /* No output fields */
1158 break;
1159
bart51e61da2012-10-23 18:03:28 +00001160 case VKI_XEN_DOMCTL_max_vcpus:
bart0ab84fe2012-09-09 18:30:17 +00001161 POST_XEN_DOMCTL_WRITE(max_vcpus, max);
florian39d8b542013-01-21 13:46:57 +00001162 break;
bart0ab84fe2012-09-09 18:30:17 +00001163
bart51e61da2012-10-23 18:03:28 +00001164 case VKI_XEN_DOMCTL_get_address_size:
bart0ab84fe2012-09-09 18:30:17 +00001165 __POST_XEN_DOMCTL_WRITE(get_address_size, address_size, size);
1166 break;
1167
bart51e61da2012-10-23 18:03:28 +00001168 case VKI_XEN_DOMCTL_gettscinfo:
bart0ab84fe2012-09-09 18:30:17 +00001169 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.tsc_mode);
1170 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.gtsc_khz);
1171 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.incarnation);
1172 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.elapsed_nsec);
1173 break;
1174
bart51e61da2012-10-23 18:03:28 +00001175 case VKI_XEN_DOMCTL_getvcpuinfo:
bart0ab84fe2012-09-09 18:30:17 +00001176 POST_XEN_DOMCTL_WRITE(getvcpuinfo, online);
1177 POST_XEN_DOMCTL_WRITE(getvcpuinfo, blocked);
1178 POST_XEN_DOMCTL_WRITE(getvcpuinfo, running);
1179 POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu_time);
1180 POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu);
1181 break;
1182
barte65212e2013-12-01 10:55:54 +00001183 case VKI_XEN_DOMCTL_gethvmcontext:
1184 /* Xen unconditionally writes size... */
1185 __POST_XEN_DOMCTL_WRITE(gethvmcontext, hvmcontext, size);
1186 /* ...but only writes to the buffer if it was non NULL */
1187 if ( domctl->u.hvmcontext.buffer.p )
1188 POST_MEM_WRITE((Addr)domctl->u.hvmcontext.buffer.p,
1189 sizeof(*domctl->u.hvmcontext.buffer.p)
1190 * domctl->u.hvmcontext.size);
1191 break;
1192
bart51e61da2012-10-23 18:03:28 +00001193 case VKI_XEN_DOMCTL_scheduler_op:
1194 if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_getinfo ) {
bart0ab84fe2012-09-09 18:30:17 +00001195 switch(domctl->u.scheduler_op.sched_id) {
bart51e61da2012-10-23 18:03:28 +00001196 case VKI_XEN_SCHEDULER_SEDF:
bart0ab84fe2012-09-09 18:30:17 +00001197 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.period);
1198 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.slice);
1199 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.latency);
1200 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.extratime);
1201 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.weight);
1202 break;
bart51e61da2012-10-23 18:03:28 +00001203 case VKI_XEN_SCHEDULER_CREDIT:
bart0ab84fe2012-09-09 18:30:17 +00001204 POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.weight);
1205 POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.cap);
1206 break;
bart51e61da2012-10-23 18:03:28 +00001207 case VKI_XEN_SCHEDULER_CREDIT2:
bart0ab84fe2012-09-09 18:30:17 +00001208 POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit2.weight);
1209 break;
bart51e61da2012-10-23 18:03:28 +00001210 case VKI_XEN_SCHEDULER_ARINC653:
bart0ab84fe2012-09-09 18:30:17 +00001211 break;
1212 }
1213 }
1214 break;
1215
bart51e61da2012-10-23 18:03:28 +00001216 case VKI_XEN_DOMCTL_getvcpuaffinity:
bart0ab84fe2012-09-09 18:30:17 +00001217 POST_MEM_WRITE((Addr)domctl->u.vcpuaffinity.cpumap.bitmap.p,
bart68495eb2013-06-30 07:58:19 +00001218 domctl->u.vcpuaffinity.cpumap.nr_bits / 8);
1219 break;
1220
1221 case VKI_XEN_DOMCTL_getnodeaffinity:
1222 POST_MEM_WRITE((Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
1223 domctl->u.nodeaffinity.nodemap.nr_bits / 8);
bart0ab84fe2012-09-09 18:30:17 +00001224 break;
1225
bart51e61da2012-10-23 18:03:28 +00001226 case VKI_XEN_DOMCTL_getdomaininfo:
1227 switch (domctl->interface_version) {
1228 case 0x00000007:
1229 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, domain);
1230 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, flags);
1231 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, tot_pages);
1232 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_pages);
1233 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shr_pages);
1234 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shared_info_frame);
1235 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpu_time);
1236 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, nr_online_vcpus);
1237 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_vcpu_id);
1238 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, ssidref);
1239 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, handle);
1240 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpupool);
bartc7c3f2f2013-01-19 13:22:54 +00001241 break;
bart51e61da2012-10-23 18:03:28 +00001242 case 0x00000008:
1243 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, domain);
1244 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, flags);
1245 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, tot_pages);
1246 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_pages);
1247 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shr_pages);
1248 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, paged_pages);
1249 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shared_info_frame);
1250 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpu_time);
1251 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, nr_online_vcpus);
1252 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_vcpu_id);
1253 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, ssidref);
1254 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, handle);
1255 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpupool);
bart0ab84fe2012-09-09 18:30:17 +00001256 break;
bart68495eb2013-06-30 07:58:19 +00001257 case 0x00000009:
1258 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, domain);
1259 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, flags);
1260 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, tot_pages);
1261 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_pages);
1262 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, outstanding_pages);
1263 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shr_pages);
1264 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, paged_pages);
1265 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shared_info_frame);
1266 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpu_time);
1267 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, nr_online_vcpus);
1268 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_vcpu_id);
1269 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, ssidref);
1270 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, handle);
1271 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpupool);
1272 break;
bart51e61da2012-10-23 18:03:28 +00001273 }
1274 break;
1275 case VKI_XEN_DOMCTL_getvcpucontext:
bart0ab84fe2012-09-09 18:30:17 +00001276 __POST_XEN_DOMCTL_WRITE(getvcpucontext, vcpucontext, ctxt.p);
1277 break;
1278
bart14c44a92013-12-01 10:56:28 +00001279 case VKI_XEN_DOMCTL_getpageframeinfo3:
1280 POST_MEM_WRITE((Addr)domctl->u.getpageframeinfo3.array.p,
1281 domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
1282 break;
1283
1284
bart51e61da2012-10-23 18:03:28 +00001285 case VKI_XEN_DOMCTL_getvcpuextstate:
bart0ab84fe2012-09-09 18:30:17 +00001286 __POST_XEN_DOMCTL_WRITE(getvcpuextstate, vcpuextstate, xfeature_mask);
1287 __POST_XEN_DOMCTL_WRITE(getvcpuextstate, vcpuextstate, size);
1288 POST_MEM_WRITE((Addr)domctl->u.vcpuextstate.buffer.p,
1289 domctl->u.vcpuextstate.size);
1290 break;
1291
bart189ade72013-12-01 10:57:43 +00001292 case VKI_XEN_DOMCTL_shadow_op:
1293 switch(domctl->u.shadow_op.op)
1294 {
1295 case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
1296 /* No outputs */
1297 break;
1298
1299 case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
1300 case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
1301 POST_XEN_DOMCTL_WRITE(shadow_op, pages);
1302 POST_XEN_DOMCTL_WRITE(shadow_op, stats.fault_count);
1303 POST_XEN_DOMCTL_WRITE(shadow_op, stats.dirty_count);
1304 if(domctl->u.shadow_op.dirty_bitmap.p)
1305 POST_MEM_WRITE((Addr)domctl->u.shadow_op.dirty_bitmap.p,
1306 domctl->u.shadow_op.pages * sizeof(vki_uint8_t));
1307 break;
1308
1309 default:
1310 break;
1311 }
1312 break;
bart0ab84fe2012-09-09 18:30:17 +00001313 }
1314#undef POST_XEN_DOMCTL_WRITE
1315#undef __POST_XEN_DOMCTL_WRITE
1316}
1317
1318POST(hvm_op)
1319{
1320 unsigned long op = ARG1;
1321 void *arg = (void *)(unsigned long)ARG2;
1322
1323#define __POST_XEN_HVMOP_WRITE(_hvm_op, _type, _field) \
1324 POST_MEM_WRITE((Addr)&((_type*)arg)->_field, \
1325 sizeof(((_type*)arg)->_field))
1326#define POST_XEN_HVMOP_WRITE(_hvm_op, _field) \
bartb1055aa2014-05-01 08:02:39 +00001327 __PRE_XEN_HVMOP_READ(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
bart0ab84fe2012-09-09 18:30:17 +00001328
1329 switch (op) {
bart51e61da2012-10-23 18:03:28 +00001330 case VKI_XEN_HVMOP_set_param:
bart0ab84fe2012-09-09 18:30:17 +00001331 /* No output paramters */
1332 break;
1333
bart51e61da2012-10-23 18:03:28 +00001334 case VKI_XEN_HVMOP_get_param:
1335 __POST_XEN_HVMOP_WRITE(get_param, struct vki_xen_hvm_param, value);
bart0ab84fe2012-09-09 18:30:17 +00001336 break;
1337 }
1338#undef __POST_XEN_HVMOP_WRITE
1339#undef POST_XEN_HVMOP_WRITE
1340}
1341
bart3b35a082013-12-01 10:52:22 +00001342POST(tmem_op)
1343{
1344 struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
1345
1346 switch(tmem->cmd) {
1347
1348 case VKI_XEN_TMEM_control:
1349
1350 switch(tmem->u.ctrl.subop) {
1351 /* No outputs */
1352 case VKI_XEN_TMEMC_save_begin:
1353 break;
1354 }
1355
1356 break;
1357 }
1358}
1359
bart0ab84fe2012-09-09 18:30:17 +00001360typedef
1361 struct {
1362 SyscallTableEntry entry;
1363 int nr_args;
1364 }
1365 XenHypercallTableEntry;
1366
1367#define HYPX_(const, name, nr_args) \
1368 [const] = { { vgSysWrap_xen_##name##_before, NULL }, nr_args }
1369#define HYPXY(const, name, nr_args) \
1370 [const] = { { vgSysWrap_xen_##name##_before, \
1371 vgSysWrap_xen_##name##_after }, \
1372 nr_args }
1373
1374static XenHypercallTableEntry hypercall_table[] = {
bart51e61da2012-10-23 18:03:28 +00001375 // __VKI_XEN_set_trap_table // 0
1376 // __VKI_XEN_mmu_update // 1
1377 // __VKI_XEN_set_gdt // 2
1378 // __VKI_XEN_stack_switch // 3
1379 // __VKI_XEN_set_callbacks // 4
bart0ab84fe2012-09-09 18:30:17 +00001380
bart51e61da2012-10-23 18:03:28 +00001381 // __VKI_XEN_fpu_taskswitch // 5
1382 // __VKI_XEN_sched_op_compat // 6
1383 // __VKI_XEN_platform_op // 7
1384 // __VKI_XEN_set_debugreg // 8
1385 // __VKI_XEN_get_debugreg // 9
bart0ab84fe2012-09-09 18:30:17 +00001386
bart51e61da2012-10-23 18:03:28 +00001387 // __VKI_XEN_update_descriptor // 10
bart0ab84fe2012-09-09 18:30:17 +00001388 // // 11
bart51e61da2012-10-23 18:03:28 +00001389 HYPXY(__VKI_XEN_memory_op, memory_op, 2), // 12
1390 // __VKI_XEN_multicall // 13
1391 // __VKI_XEN_update_va_mapping // 14
bart0ab84fe2012-09-09 18:30:17 +00001392
bart51e61da2012-10-23 18:03:28 +00001393 // __VKI_XEN_set_timer_op // 15
1394 HYPXY(__VKI_XEN_event_channel_op_compat, evtchn_op_compat, 1), // 16
1395 HYPXY(__VKI_XEN_xen_version, xen_version, 2), // 17
1396 // __VKI_XEN_console_io // 18
1397 // __VKI_XEN_physdev_op_compat // 19
bart0ab84fe2012-09-09 18:30:17 +00001398
bart51e61da2012-10-23 18:03:28 +00001399 HYPXY(__VKI_XEN_grant_table_op, grant_table_op, 3), // 20
1400 // __VKI_XEN_vm_assist // 21
1401 // __VKI_XEN_update_va_mapping_otherdomain // 22
1402 // __VKI_XEN_iret, iret // 23
1403 // __VKI_XEN_vcpu_op, vcpu_op // 24
bart0ab84fe2012-09-09 18:30:17 +00001404
bart51e61da2012-10-23 18:03:28 +00001405 // __VKI_XEN_set_segment_base // 25
1406 HYPXY(__VKI_XEN_mmuext_op, mmuext_op, 2), // 26
1407 // __VKI_XEN_xsm_op // 27
1408 // __VKI_XEN_nmi_op // 28
1409 // __VKI_XEN_sched_op // 29
bart0ab84fe2012-09-09 18:30:17 +00001410
bart51e61da2012-10-23 18:03:28 +00001411 // __VKI_XEN_callback_op // 30
1412 // __VKI_XEN_xenoprof_op // 31
1413 HYPXY(__VKI_XEN_event_channel_op, evtchn_op, 2), // 32
1414 // __VKI_XEN_physdev_op // 33
1415 HYPXY(__VKI_XEN_hvm_op, hvm_op, 2), // 34
bart0ab84fe2012-09-09 18:30:17 +00001416
bart51e61da2012-10-23 18:03:28 +00001417 HYPXY(__VKI_XEN_sysctl, sysctl, 1), // 35
1418 HYPXY(__VKI_XEN_domctl, domctl, 1), // 36
1419 // __VKI_XEN_kexec_op // 37
bart3b35a082013-12-01 10:52:22 +00001420 HYPXY(__VKI_XEN_tmem_op, tmem_op, 1), // 38
bart0ab84fe2012-09-09 18:30:17 +00001421};
1422
1423static void bad_before ( ThreadId tid,
1424 SyscallArgLayout* layout,
1425 /*MOD*/SyscallArgs* args,
1426 /*OUT*/SyscallStatus* status,
1427 /*OUT*/UWord* flags )
1428{
1429 VG_(dmsg)("WARNING: unhandled hypercall: %s\n",
1430 VG_SYSNUM_STRING_EXTRA(args->sysno));
1431 if (VG_(clo_verbosity) > 1) {
1432 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
1433 }
1434 VG_(dmsg)("You may be able to write your own handler.\n");
1435 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
1436 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n");
1437 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
1438 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
1439
1440 SET_STATUS_Failure(VKI_ENOSYS);
1441}
1442
1443static XenHypercallTableEntry bad_hyper =
1444{ { bad_before, NULL }, 0 };
1445
1446static XenHypercallTableEntry* ML_(get_xen_hypercall_entry) ( UInt sysno )
1447{
1448 XenHypercallTableEntry *ret = &bad_hyper;
1449
1450 const UInt hypercall_table_size
1451 = sizeof(hypercall_table) / sizeof(hypercall_table[0]);
1452
1453 /* Is it in the contiguous initial section of the table? */
1454 if (sysno < hypercall_table_size) {
1455 XenHypercallTableEntry* ent = &hypercall_table[sysno];
1456 if (ent->entry.before != NULL)
1457 ret = ent;
1458 }
1459
1460 /* Can't find a wrapper */
1461 return ret;
1462}
1463
1464DEFN_PRE_TEMPLATE(xen, hypercall)
1465{
1466 XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
1467
1468 /* Return number of arguments consumed */
1469 ARG8 = ent->nr_args;
1470
1471 vg_assert(ent);
1472 vg_assert(ent->entry.before);
1473 (ent->entry.before)( tid, layout, arrghs, status, flags );
1474
1475}
1476
1477DEFN_POST_TEMPLATE(xen, hypercall)
1478{
1479 XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
1480
1481 /* Return number of arguments consumed */
1482 ARG8 = ent->nr_args;
1483
1484 vg_assert(ent);
1485 if (ent->entry.after)
1486 (ent->entry.after)( tid, arrghs, status );
1487}
bart51e61da2012-10-23 18:03:28 +00001488
1489#endif // defined(ENABLE_XEN)