• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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"
33 
34 #if defined(ENABLE_XEN)
35 
36 #include "pub_core_vkiscnums.h"
37 #include "pub_core_threadstate.h"
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_debuginfo.h"    // VG_(di_notify_*)
40 #include "pub_core_transtab.h"     // VG_(discard_translations)
41 #include "pub_core_xarray.h"
42 #include "pub_core_clientstate.h"
43 #include "pub_core_debuglog.h"
44 #include "pub_core_libcbase.h"
45 #include "pub_core_libcassert.h"
46 #include "pub_core_libcfile.h"
47 #include "pub_core_libcprint.h"
48 #include "pub_core_libcproc.h"
49 #include "pub_core_libcsignal.h"
50 #include "pub_core_mallocfree.h"
51 #include "pub_core_tooliface.h"
52 #include "pub_core_options.h"
53 #include "pub_core_scheduler.h"
54 #include "pub_core_signals.h"
55 #include "pub_core_syscall.h"
56 #include "pub_core_syswrap.h"
57 #include "pub_core_stacktrace.h"    // For VG_(get_and_pp_StackTrace)()
58 
59 #include "priv_types_n_macros.h"
60 #include "priv_syswrap-generic.h"
61 #include "priv_syswrap-xen.h"
62 
63 #include <inttypes.h>
64 
65 #define PRE(name) static DEFN_PRE_TEMPLATE(xen, name)
66 #define POST(name) static DEFN_POST_TEMPLATE(xen, name)
67 
bad_intf_version(ThreadId tid,SyscallArgLayout * layout,SyscallArgs * args,SyscallStatus * status,UWord * flags,const HChar * hypercall,UWord version)68 static void bad_intf_version ( ThreadId              tid,
69                                SyscallArgLayout*     layout,
70                                /*MOD*/SyscallArgs*   args,
71                                /*OUT*/SyscallStatus* status,
72                                /*OUT*/UWord*         flags,
73                                const HChar*          hypercall,
74                                UWord                 version)
75 {
76    VG_(dmsg)("WARNING: %s version %#lx not supported\n",
77              hypercall, version);
78    if (VG_(clo_verbosity) > 1) {
79       VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
80    }
81    VG_(dmsg)("You may be able to write your own handler.\n");
82    VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
83    VG_(dmsg)("Nevertheless we consider this a bug.  Please report\n");
84    VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
85    VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
86 
87    SET_STATUS_Failure(VKI_ENOSYS);
88 }
89 
bad_subop(ThreadId tid,SyscallArgLayout * layout,SyscallArgs * args,SyscallStatus * status,UWord * flags,const HChar * hypercall,UWord subop)90 static void bad_subop ( ThreadId              tid,
91                         SyscallArgLayout*     layout,
92                         /*MOD*/SyscallArgs*   args,
93                         /*OUT*/SyscallStatus* status,
94                         /*OUT*/UWord*         flags,
95                         const HChar*          hypercall,
96                         UWord                 subop)
97 {
98    VG_(dmsg)("WARNING: unhandled %s subop: %lu\n",
99              hypercall, subop);
100    if (VG_(clo_verbosity) > 1) {
101       VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
102    }
103    VG_(dmsg)("You may be able to write your own handler.\n");
104    VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
105    VG_(dmsg)("Nevertheless we consider this a bug.  Please report\n");
106    VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
107    VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
108 
109    SET_STATUS_Failure(VKI_ENOSYS);
110 }
111 
PRE(memory_op)112 PRE(memory_op)
113 {
114    PRINT("__HYPERVISOR_memory_op ( %lu, %#lx )", ARG1, ARG2);
115 
116    switch (ARG1) {
117 
118    case VKI_XENMEM_maximum_ram_page:
119        /* No inputs */
120        break;
121 
122    case VKI_XENMEM_maximum_gpfn:
123        PRE_MEM_READ("XENMEM_maximum_gpfn domid",
124                     (Addr)ARG2, sizeof(vki_xen_domid_t));
125        break;
126 
127    case VKI_XENMEM_machphys_mfn_list:
128    case VKI_XENMEM_machphys_compat_mfn_list: {
129        struct vki_xen_machphys_mfn_list *arg =
130            (struct vki_xen_machphys_mfn_list *)ARG2;
131        PRE_MEM_READ("XENMEM_machphys_mfn_list max_extents",
132                     (Addr)&arg->max_extents, sizeof(arg->max_extents));
133        PRE_MEM_READ("XENMEM_machphys_mfn_list extent_start",
134                     (Addr)&arg->extent_start, sizeof(arg->extent_start));
135        break;
136    }
137 
138    case VKI_XENMEM_set_memory_map: {
139       struct vki_xen_foreign_memory_map *arg =
140 	      (struct vki_xen_foreign_memory_map *)ARG2;
141       PRE_MEM_READ("XENMEM_set_memory_map domid",
142                    (Addr)&arg->domid, sizeof(arg->domid));
143       PRE_MEM_READ("XENMEM_set_memory_map map",
144                    (Addr)&arg->map, sizeof(arg->map));
145       break;
146    }
147 
148    case VKI_XENMEM_memory_map:
149    case VKI_XENMEM_machine_memory_map: {
150       struct vki_xen_memory_map *arg =
151 	      (struct vki_xen_memory_map *)ARG2;
152       PRE_MEM_READ("XENMEM_memory_map nr_entries",
153                    (Addr)&arg->nr_entries, sizeof(arg->nr_entries));
154       break;
155    }
156 
157    case VKI_XENMEM_increase_reservation:
158    case VKI_XENMEM_decrease_reservation:
159    case VKI_XENMEM_populate_physmap:
160    case VKI_XENMEM_claim_pages: {
161       struct xen_memory_reservation *memory_reservation =
162          (struct xen_memory_reservation *)ARG2;
163       const HChar *which;
164 
165       switch (ARG1) {
166       case VKI_XENMEM_increase_reservation:
167          which = "XENMEM_increase_reservation";
168          break;
169       case VKI_XENMEM_decrease_reservation:
170          which = "XENMEM_decrease_reservation";
171          PRE_MEM_READ(which,
172                       (Addr)memory_reservation->extent_start.p,
173                       sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
174 	 break;
175       case VKI_XENMEM_populate_physmap:
176          which = "XENMEM_populate_physmap";
177          PRE_MEM_READ(which,
178                       (Addr)memory_reservation->extent_start.p,
179                       sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
180          break;
181       case VKI_XENMEM_claim_pages:
182          which = "XENMEM_claim_pages";
183          break;
184       default:
185          which = "XENMEM_unknown";
186          break;
187       }
188 
189       PRE_MEM_READ(which,
190                    (Addr)&memory_reservation->extent_start,
191                    sizeof(memory_reservation->extent_start));
192       PRE_MEM_READ(which,
193                    (Addr)&memory_reservation->nr_extents,
194                    sizeof(memory_reservation->nr_extents));
195       PRE_MEM_READ(which,
196                    (Addr)&memory_reservation->extent_order,
197                    sizeof(memory_reservation->extent_order));
198       PRE_MEM_READ(which,
199                    (Addr)&memory_reservation->mem_flags,
200                    sizeof(memory_reservation->mem_flags));
201       PRE_MEM_READ(which,
202                    (Addr)&memory_reservation->domid,
203                    sizeof(memory_reservation->domid));
204       break;
205    }
206 
207    case VKI_XENMEM_add_to_physmap: {
208        struct vki_xen_add_to_physmap *arg =
209            (struct vki_xen_add_to_physmap *)ARG2;
210        PRE_MEM_READ("XENMEM_add_to_physmap domid",
211                     (Addr)&arg->domid, sizeof(arg->domid));
212        PRE_MEM_READ("XENMEM_add_to_physmap size",
213                     (Addr)&arg->size, sizeof(arg->size));
214        PRE_MEM_READ("XENMEM_add_to_physmap space",
215                     (Addr)&arg->space, sizeof(arg->space));
216        PRE_MEM_READ("XENMEM_add_to_physmap idx",
217                     (Addr)&arg->idx, sizeof(arg->idx));
218        PRE_MEM_READ("XENMEM_add_to_physmap gpfn",
219                     (Addr)&arg->gpfn, sizeof(arg->gpfn));
220        break;
221    }
222 
223    case VKI_XENMEM_remove_from_physmap: {
224        struct vki_xen_remove_from_physmap *arg =
225            (struct vki_xen_remove_from_physmap *)ARG2;
226        PRE_MEM_READ("XENMEM_remove_from_physmap domid",
227                     (Addr)&arg->domid, sizeof(arg->domid));
228        PRE_MEM_READ("XENMEM_remove_from_physmap gpfn",
229                     (Addr)&arg->gpfn, sizeof(arg->gpfn));
230        break;
231    }
232 
233    case VKI_XENMEM_get_sharing_freed_pages:
234    case VKI_XENMEM_get_sharing_shared_pages:
235       break;
236 
237    case VKI_XENMEM_access_op: {
238        struct vki_xen_mem_event_op *arg =
239             (struct vki_xen_mem_event_op *)ARG2;
240        PRE_MEM_READ("XENMEM_access_op domid",
241                     (Addr)&arg->domain, sizeof(arg->domain));
242        PRE_MEM_READ("XENMEM_access_op op",
243                     (Addr)&arg->op, sizeof(arg->op));
244        PRE_MEM_READ("XENMEM_access_op gfn",
245                     (Addr)&arg->gfn, sizeof(arg->gfn));
246        break;
247    }
248    default:
249       bad_subop(tid, layout, arrghs, status, flags,
250                 "__HYPERVISOR_memory_op", ARG1);
251       break;
252    }
253 }
254 
PRE(mmuext_op)255 PRE(mmuext_op)
256 {
257    PRINT("__HYPERVISOR_mmuext_op ( %#lx, %ld, %#lx, %lu )",
258          ARG1, SARG2, ARG3, ARG4);
259 
260    struct vki_xen_mmuext_op *ops = (struct vki_xen_mmuext_op *)ARG1;
261    unsigned int i, nr = ARG2;
262 
263    for (i=0; i<nr; i++) {
264       struct vki_xen_mmuext_op *op = ops + i;
265       PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP cmd",
266                    (Addr)&op->cmd, sizeof(op->cmd));
267       switch(op->cmd) {
268       case VKI_XEN_MMUEXT_PIN_L1_TABLE:
269       case VKI_XEN_MMUEXT_PIN_L2_TABLE:
270       case VKI_XEN_MMUEXT_PIN_L3_TABLE:
271       case VKI_XEN_MMUEXT_PIN_L4_TABLE:
272       case VKI_XEN_MMUEXT_UNPIN_TABLE:
273       case VKI_XEN_MMUEXT_NEW_BASEPTR:
274       case VKI_XEN_MMUEXT_CLEAR_PAGE:
275       case VKI_XEN_MMUEXT_COPY_PAGE:
276       case VKI_XEN_MMUEXT_MARK_SUPER:
277       case VKI_XEN_MMUEXT_UNMARK_SUPER:
278          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn",
279                       (Addr)&op->arg1.mfn,
280                       sizeof(op->arg1.mfn));
281          break;
282 
283       case VKI_XEN_MMUEXT_INVLPG_LOCAL:
284       case VKI_XEN_MMUEXT_INVLPG_ALL:
285       case VKI_XEN_MMUEXT_SET_LDT:
286          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn",
287                       (Addr)&op->arg1.linear_addr,
288                       sizeof(op->arg1.linear_addr));
289          break;
290 
291       case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL:
292       case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI:
293       case VKI_XEN_MMUEXT_INVLPG_MULTI:
294       case VKI_XEN_MMUEXT_TLB_FLUSH_ALL:
295       case VKI_XEN_MMUEXT_FLUSH_CACHE:
296       case VKI_XEN_MMUEXT_NEW_USER_BASEPTR:
297       case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL:
298          /* None */
299          break;
300       }
301 
302       switch(op->cmd) {
303       case VKI_XEN_MMUEXT_SET_LDT:
304          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.nr_ents",
305                       (Addr)&op->arg2.nr_ents,
306                       sizeof(op->arg2.nr_ents));
307          break;
308 
309       case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI:
310       case VKI_XEN_MMUEXT_INVLPG_MULTI:
311          /* How many??? */
312          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.vcpumask",
313                       (Addr)&op->arg2.vcpumask,
314                       sizeof(op->arg2.vcpumask));
315          break;
316 
317       case VKI_XEN_MMUEXT_COPY_PAGE:
318          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.src_mfn",
319                       (Addr)&op->arg2.src_mfn,
320                       sizeof(op->arg2.src_mfn));
321          break;
322 
323       case VKI_XEN_MMUEXT_PIN_L1_TABLE:
324       case VKI_XEN_MMUEXT_PIN_L2_TABLE:
325       case VKI_XEN_MMUEXT_PIN_L3_TABLE:
326       case VKI_XEN_MMUEXT_PIN_L4_TABLE:
327       case VKI_XEN_MMUEXT_UNPIN_TABLE:
328       case VKI_XEN_MMUEXT_NEW_BASEPTR:
329       case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL:
330       case VKI_XEN_MMUEXT_INVLPG_LOCAL:
331       case VKI_XEN_MMUEXT_TLB_FLUSH_ALL:
332       case VKI_XEN_MMUEXT_INVLPG_ALL:
333       case VKI_XEN_MMUEXT_FLUSH_CACHE:
334       case VKI_XEN_MMUEXT_NEW_USER_BASEPTR:
335       case VKI_XEN_MMUEXT_CLEAR_PAGE:
336       case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL:
337       case VKI_XEN_MMUEXT_MARK_SUPER:
338       case VKI_XEN_MMUEXT_UNMARK_SUPER:
339          /* None */
340          break;
341       }
342    }
343 }
344 
PRE(xsm_op)345 PRE(xsm_op)
346 {
347    /* XXX assuming flask, only actual XSM right now */
348    struct vki_xen_flask_op *op = (struct vki_xen_flask_op *)ARG1;
349 
350    PRINT("__HYPERVISOR_xsm_op ( %u )", op->cmd);
351 
352    /*
353     * Common part of xen_flask_op:
354     *    vki_uint32_t cmd;
355     *    vki_uint32_t interface_version;
356     */
357    PRE_MEM_READ("__HYPERVISOR_xsm_op", ARG1,
358                 sizeof(vki_uint32_t) + sizeof(vki_uint32_t));
359 
360    if (!op)
361       return;
362 
363    switch (op->interface_version) {
364    case 0x00000001:
365       break;
366    default:
367       bad_intf_version(tid, layout, arrghs, status, flags,
368                        "__HYPERVISOR_xsm_op", op->interface_version);
369       return;
370    }
371 
372 #define PRE_XEN_XSM_OP_READ(_xsm_op, _union, _field)            \
373    PRE_MEM_READ("FLASK_" #_xsm_op " u." #_union "." #_field,    \
374                 (Addr)&op->u._union._field,                     \
375                 sizeof(op->u._union._field))
376 
377    switch (op->cmd) {
378    case VKI_FLASK_SID_TO_CONTEXT:
379       PRE_XEN_XSM_OP_READ(SID_TO_CONTEXT, sid_context, sid);
380       PRE_XEN_XSM_OP_READ(SID_TO_CONTEXT, sid_context, size);
381       PRE_XEN_XSM_OP_READ(SID_TO_CONTEXT, sid_context, context.p);
382       break;
383    default:
384       bad_subop(tid, layout, arrghs, status, flags,
385                 "__HYPERVISOR_xsm_op", op->cmd);
386       break;
387    }
388 #undef __PRE_XEN_XSM_OP_READ
389 #undef PRE_XEN_XSM_OP_READ
390 }
391 
PRE(sched_op)392 PRE(sched_op)
393 {
394    PRINT("__HYPERVISOR_sched_op ( %ld, %#lx )", SARG1, ARG2);
395    void *arg = (void *)(unsigned long)ARG2;
396 
397 #define __PRE_XEN_SCHEDOP_READ(_schedop, _type, _field) \
398    PRE_MEM_READ("XEN_SCHEDOP_" # _schedop " " #_field,  \
399                 (Addr)&((_type*)arg)->_field,           \
400                 sizeof(((_type*)arg)->_field))
401 #define PRE_XEN_SCHEDOP_READ(_schedop, _field)                          \
402    __PRE_XEN_SCHEDOP_READ(_schedop, vki_xen_ ## _schedop ## _t, _field)
403 
404    switch (ARG1) {
405    case VKI_XEN_SCHEDOP_remote_shutdown:
406       PRE_XEN_SCHEDOP_READ(remote_shutdown, domain_id);
407       PRE_XEN_SCHEDOP_READ(remote_shutdown, reason);
408       break;
409 
410    default:
411       bad_subop(tid, layout, arrghs, status, flags,
412                 "__HYPERVISOR_sched_op", ARG1);
413       break;
414    }
415 #undef __PRE_XEN_SCHEDOP_READ
416 #undef PRE_XEN_SCHEDOP_READ
417 }
418 
pre_evtchn_op(ThreadId tid,SyscallArgLayout * layout,SyscallArgs * arrghs,SyscallStatus * status,UWord * flags,__vki_u32 cmd,void * arg,int compat)419 static void pre_evtchn_op(ThreadId tid,
420                           SyscallArgLayout*     layout,
421                           /*MOD*/SyscallArgs*   arrghs,
422                           /*OUT*/SyscallStatus* status,
423                           /*OUT*/UWord*         flags,
424                           __vki_u32 cmd, void *arg, int compat)
425 {
426    PRINT("__HYPERVISOR_event_channel_op%s ( %u, %p )",
427          compat ? "_compat" : "", cmd, arg);
428 
429    switch (cmd) {
430    case VKI_XEN_EVTCHNOP_alloc_unbound: {
431       struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg;
432       PRE_MEM_READ("EVTCHNOP_alloc_unbound dom",
433                    (Addr)&alloc_unbound->dom, sizeof(alloc_unbound->dom));
434       PRE_MEM_READ("EVTCHNOP_alloc_unbound remote_dom",
435                    (Addr)&alloc_unbound->remote_dom,
436                    sizeof(alloc_unbound->remote_dom));
437       break;
438    }
439    default:
440       if ( compat )
441          bad_subop(tid, layout, arrghs, status, flags,
442                    "__HYPERVISOR_event_channel_op_compat", cmd);
443       else
444          bad_subop(tid, layout, arrghs, status, flags,
445                    "__HYPERVISOR_event_channel_op", cmd);
446       break;
447    }
448 }
449 
PRE(evtchn_op)450 PRE(evtchn_op)
451 {
452    pre_evtchn_op(tid, layout, arrghs, status, flags,
453                  ARG1, (void *)ARG2, 0);
454 }
455 
PRE(evtchn_op_compat)456 PRE(evtchn_op_compat)
457 {
458    struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1;
459    PRE_MEM_READ("__HYPERVISOR_event_channel_op_compat",
460                 ARG1, sizeof(*evtchn));
461 
462    pre_evtchn_op(tid, layout, arrghs, status, flags,
463                  evtchn->cmd, &evtchn->u, 1);
464 }
465 
PRE(physdev_op)466 PRE(physdev_op)
467 {
468    int cmd = ARG1;
469 
470    PRINT("__HYPERVISOR_physdev_op ( %ld, %#lx )", SARG1, ARG2);
471 
472 #define PRE_XEN_PHYSDEVOP_READ(_op, _field)		\
473    PRE_MEM_READ("XEN_PHYSDEVOP_" #_op " ." #_field,	\
474                 (Addr)&arg->_field,			\
475                 sizeof(arg->_field))
476 
477    switch (cmd) {
478    case VKI_XEN_PHYSDEVOP_map_pirq: {
479       struct vki_xen_physdev_map_pirq *arg =
480          (struct vki_xen_physdev_map_pirq *)ARG2;
481 
482       PRE_XEN_PHYSDEVOP_READ("map_pirq", domid);
483       PRE_XEN_PHYSDEVOP_READ("map_pirq", type);
484 
485       PRE_XEN_PHYSDEVOP_READ("map_pirq", bus);
486       PRE_XEN_PHYSDEVOP_READ("map_pirq", devfn);
487       PRE_XEN_PHYSDEVOP_READ("map_pirq", entry_nr);
488       PRE_XEN_PHYSDEVOP_READ("map_pirq", table_base);
489 
490       switch(arg->type) {
491       case VKI_XEN_MAP_PIRQ_TYPE_MSI:
492          PRE_XEN_PHYSDEVOP_READ("map_pirq", index);
493          break;
494       case VKI_XEN_MAP_PIRQ_TYPE_GSI:
495          PRE_XEN_PHYSDEVOP_READ("map_pirq", index);
496          PRE_XEN_PHYSDEVOP_READ("map_pirq", pirq);
497          break;
498       case VKI_XEN_MAP_PIRQ_TYPE_MSI_SEG:
499          PRE_XEN_PHYSDEVOP_READ("map_pirq", index);
500          break;
501       case VKI_XEN_MAP_PIRQ_TYPE_MULTI_MSI:
502          break;
503       }
504       break;
505    }
506    case VKI_XEN_PHYSDEVOP_unmap_pirq: {
507       struct vki_xen_physdev_unmap_pirq *arg =
508          (struct vki_xen_physdev_unmap_pirq *)ARG2;
509       PRE_XEN_PHYSDEVOP_READ("unmap_pirq", domid);
510       PRE_XEN_PHYSDEVOP_READ("unmap_pirq", pirq);
511       break;
512    }
513    default:
514       bad_subop(tid, layout, arrghs, status, flags,
515                 "__HYPERVISOR_physdev_op", cmd);
516    }
517 #undef PRE_XEN_PHYSDEVOP_READ
518 }
519 
PRE(xen_version)520 PRE(xen_version)
521 {
522    PRINT("__HYPERVISOR_xen_version ( %ld, %#lx )", SARG1, ARG2);
523 
524    switch (ARG1) {
525    case VKI_XENVER_version:
526    case VKI_XENVER_extraversion:
527    case VKI_XENVER_compile_info:
528    case VKI_XENVER_capabilities:
529    case VKI_XENVER_changeset:
530    case VKI_XENVER_platform_parameters:
531    case VKI_XENVER_get_features:
532    case VKI_XENVER_pagesize:
533    case VKI_XENVER_guest_handle:
534    case VKI_XENVER_commandline:
535       /* No inputs */
536       break;
537 
538    default:
539       bad_subop(tid, layout, arrghs, status, flags,
540                 "__HYPERVISOR_xen_version", ARG1);
541       break;
542    }
543 }
544 
PRE(grant_table_op)545 PRE(grant_table_op)
546 {
547    PRINT("__HYPERVISOR_grant_table_op ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
548    switch (ARG1) {
549    case VKI_XEN_GNTTABOP_setup_table: {
550       struct vki_xen_gnttab_setup_table *gst =
551 	      (struct vki_xen_gnttab_setup_table*)ARG2;
552       PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table dom",
553 		   (Addr)&gst->dom, sizeof(gst->dom));
554       PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table nr_frames",
555                    (Addr)&gst->nr_frames, sizeof(gst->nr_frames));
556       break;
557    }
558    default:
559       bad_subop(tid, layout, arrghs, status, flags,
560                 "__HYPERVISOR_grant_table_op", ARG1);
561       break;
562    }
563 }
564 
PRE(sysctl)565 PRE(sysctl) {
566    struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1;
567 
568    PRINT("__HYPERVISOR_sysctl ( %u )", sysctl->cmd);
569 
570    /*
571     * Common part of xen_sysctl:
572     *    uint32_t cmd;
573     *    uint32_t interface_version;
574     */
575    PRE_MEM_READ("__HYPERVISOR_sysctl", ARG1,
576                 sizeof(vki_uint32_t) + sizeof(vki_uint32_t));
577 
578    if (!sysctl)
579       return;
580 
581    switch (sysctl->interface_version)
582    {
583    case 0x00000008:
584    case 0x00000009:
585    case 0x0000000a:
586    case 0x0000000b:
587 	   break;
588    default:
589       bad_intf_version(tid, layout, arrghs, status, flags,
590                        "__HYPERVISOR_sysctl", sysctl->interface_version);
591       return;
592    }
593 
594 #define __PRE_XEN_SYSCTL_READ(_sysctl, _union, _field)			\
595       PRE_MEM_READ("XEN_SYSCTL_" #_sysctl " u." #_union "." #_field,	\
596                    (Addr)&sysctl->u._union._field,			\
597                    sizeof(sysctl->u._union._field))
598 #define PRE_XEN_SYSCTL_READ(_sysctl, _field) \
599       __PRE_XEN_SYSCTL_READ(_sysctl, _sysctl, _field)
600 
601    switch (sysctl->cmd) {
602    case VKI_XEN_SYSCTL_readconsole:
603        /* These are all unconditionally read */
604        PRE_XEN_SYSCTL_READ(readconsole, clear);
605        PRE_XEN_SYSCTL_READ(readconsole, incremental);
606        PRE_XEN_SYSCTL_READ(readconsole, buffer);
607        PRE_XEN_SYSCTL_READ(readconsole, count);
608 
609        /* 'index' only read if 'incremental' is nonzero */
610        if (sysctl->u.readconsole.incremental)
611            PRE_XEN_SYSCTL_READ(readconsole, index);
612        break;
613 
614    case VKI_XEN_SYSCTL_getdomaininfolist:
615       switch (sysctl->interface_version)
616       {
617       case 0x00000008:
618 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, first_domain);
619 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, max_domains);
620 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, buffer);
621 	 break;
622       case 0x00000009:
623 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, first_domain);
624 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, max_domains);
625 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, buffer);
626 	 break;
627       case 0x0000000a:
628       case 0x0000000b:
629 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, first_domain);
630 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, max_domains);
631 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, buffer);
632 	 break;
633       default:
634           VG_(dmsg)("WARNING: XEN_SYSCTL_getdomaininfolist for sysctl version "
635                     "%"PRIx32" not implemented yet\n",
636                     sysctl->interface_version);
637           SET_STATUS_Failure(VKI_EINVAL);
638           return;
639       }
640       break;
641 
642    case VKI_XEN_SYSCTL_debug_keys:
643        PRE_XEN_SYSCTL_READ(debug_keys, keys);
644        PRE_XEN_SYSCTL_READ(debug_keys, nr_keys);
645        PRE_MEM_READ("XEN_SYSCTL_debug_keys *keys",
646                     (Addr)sysctl->u.debug_keys.keys.p,
647                     sysctl->u.debug_keys.nr_keys * sizeof(char));
648        break;
649 
650    case VKI_XEN_SYSCTL_sched_id:
651        /* No inputs */
652        break;
653 
654    case VKI_XEN_SYSCTL_cpupool_op:
655       PRE_XEN_SYSCTL_READ(cpupool_op, op);
656 
657       switch(sysctl->u.cpupool_op.op) {
658       case VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE:
659       case VKI_XEN_SYSCTL_CPUPOOL_OP_DESTROY:
660       case VKI_XEN_SYSCTL_CPUPOOL_OP_INFO:
661       case VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU:
662       case VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU:
663       case VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN:
664          PRE_XEN_SYSCTL_READ(cpupool_op, cpupool_id);
665       }
666 
667       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE)
668          PRE_XEN_SYSCTL_READ(cpupool_op, sched_id);
669 
670       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN)
671          PRE_XEN_SYSCTL_READ(cpupool_op, domid);
672 
673       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU ||
674           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU)
675          PRE_XEN_SYSCTL_READ(cpupool_op, cpu);
676 
677       break;
678 
679    case VKI_XEN_SYSCTL_physinfo:
680       /* No input params */
681       break;
682 
683    case VKI_XEN_SYSCTL_topologyinfo:
684       PRE_XEN_SYSCTL_READ(topologyinfo, max_cpu_index);
685       PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_core);
686       PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_socket);
687       PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_node);
688       break;
689 
690    case VKI_XEN_SYSCTL_numainfo:
691       PRE_XEN_SYSCTL_READ(numainfo, max_node_index);
692       PRE_XEN_SYSCTL_READ(numainfo, node_to_memsize);
693       PRE_XEN_SYSCTL_READ(numainfo, node_to_memfree);
694       PRE_XEN_SYSCTL_READ(numainfo, node_to_node_distance);
695       break;
696 
697    default:
698       bad_subop(tid, layout, arrghs, status, flags,
699                 "__HYPERVISOR_sysctl", sysctl->cmd);
700       break;
701    }
702 #undef PRE_XEN_SYSCTL_READ
703 #undef __PRE_XEN_SYSCTL_READ
704 }
705 
PRE(domctl)706 PRE(domctl)
707 {
708    struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1;
709 
710    PRINT("__HYPERVISOR_domctl ( %u ) on dom%d", domctl->cmd, domctl->domain);
711 
712    /*
713     * Common part of xen_domctl:
714     *    vki_uint32_t cmd;
715     *    vki_uint32_t interface_version;
716     *    vki_xen_domid_t  domain;
717     */
718    PRE_MEM_READ("__HYPERVISOR_domctl", ARG1,
719                 sizeof(vki_uint32_t) + sizeof(vki_uint32_t)
720 		+ sizeof(vki_xen_domid_t));
721 
722    if (!domctl)
723       return;
724 
725    switch (domctl->interface_version)
726    {
727    case 0x00000007:
728    case 0x00000008:
729    case 0x00000009:
730    case 0x0000000a:
731    case 0x0000000b:
732    case 0x0000000c:
733 	   break;
734    default:
735       bad_intf_version(tid, layout, arrghs, status, flags,
736                        "__HYPERVISOR_domctl", domctl->interface_version);
737       return;
738    }
739 
740 #define __PRE_XEN_DOMCTL_READ(_domctl, _union, _field)			\
741       PRE_MEM_READ("XEN_DOMCTL_" #_domctl " u." #_union "." #_field,	\
742                    (Addr)&domctl->u._union._field,			\
743                    sizeof(domctl->u._union._field))
744 #define PRE_XEN_DOMCTL_READ(_domctl, _field) \
745       __PRE_XEN_DOMCTL_READ(_domctl, _domctl, _field)
746 
747    switch (domctl->cmd) {
748    case VKI_XEN_DOMCTL_destroydomain:
749    case VKI_XEN_DOMCTL_pausedomain:
750    case VKI_XEN_DOMCTL_max_vcpus:
751    case VKI_XEN_DOMCTL_get_address_size:
752    case VKI_XEN_DOMCTL_gettscinfo:
753    case VKI_XEN_DOMCTL_getdomaininfo:
754    case VKI_XEN_DOMCTL_unpausedomain:
755    case VKI_XEN_DOMCTL_resumedomain:
756       /* No input fields. */
757       break;
758 
759    case VKI_XEN_DOMCTL_createdomain:
760       PRE_XEN_DOMCTL_READ(createdomain, ssidref);
761       PRE_XEN_DOMCTL_READ(createdomain, handle);
762       PRE_XEN_DOMCTL_READ(createdomain, flags);
763       break;
764 
765    case VKI_XEN_DOMCTL_gethvmcontext:
766        /* Xen unconditionally reads the 'buffer' pointer */
767        __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, buffer);
768        /* Xen only consumes 'size' if 'buffer' is non NULL. A NULL
769         * buffer is a request for the required size. */
770        if ( domctl->u.hvmcontext.buffer.p )
771            __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, size);
772        break;
773 
774    case VKI_XEN_DOMCTL_sethvmcontext:
775        __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, size);
776        __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, buffer);
777        PRE_MEM_READ("XEN_DOMCTL_sethvmcontext *buffer",
778                     (Addr)domctl->u.hvmcontext.buffer.p,
779                     domctl->u.hvmcontext.size);
780        break;
781 
782    case VKI_XEN_DOMCTL_gethvmcontext_partial:
783        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, type);
784        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, instance);
785        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, buffer);
786 
787        switch (domctl->u.hvmcontext_partial.type) {
788        case VKI_HVM_SAVE_CODE(CPU):
789            if ( domctl->u.hvmcontext_partial.buffer.p )
790                 PRE_MEM_WRITE("XEN_DOMCTL_gethvmcontext_partial *buffer",
791                    (Addr)domctl->u.hvmcontext_partial.buffer.p,
792                    VKI_HVM_SAVE_LENGTH(CPU));
793            break;
794        case VKI_HVM_SAVE_CODE(MTRR):
795            if ( domctl->u.hvmcontext_partial.buffer.p )
796 	        PRE_MEM_WRITE("XEN_DOMCTL_gethvmcontext_partial *buffer",
797 		   (Addr)domctl->u.hvmcontext_partial.buffer.p,
798 		   VKI_HVM_SAVE_LENGTH(MTRR));
799            break;
800        default:
801            bad_subop(tid, layout, arrghs, status, flags,
802                          "__HYPERVISOR_domctl_gethvmcontext_partial type",
803                          domctl->u.hvmcontext_partial.type);
804            break;
805        }
806        break;
807 
808    case VKI_XEN_DOMCTL_max_mem:
809       PRE_XEN_DOMCTL_READ(max_mem, max_memkb);
810       break;
811 
812    case VKI_XEN_DOMCTL_set_address_size:
813       __PRE_XEN_DOMCTL_READ(set_address_size, address_size, size);
814       break;
815 
816    case VKI_XEN_DOMCTL_test_assign_device:
817       switch (domctl->interface_version) {
818       case 0x00000007: /* pre-4.6 */
819       case 0x00000008:
820       case 0x00000009:
821       case 0x0000000a:
822          __PRE_XEN_DOMCTL_READ(test_assign_device, assign_device_00000007, machine_sbdf);
823          break;
824       case 0x0000000b:
825          __PRE_XEN_DOMCTL_READ(test_assign_device, assign_device_0000000b, dev);
826          __PRE_XEN_DOMCTL_READ(test_assign_device, assign_device_0000000b, flag);
827          switch (domctl->u.assign_device_0000000b.dev) {
828          case VKI_XEN_DOMCTL_DEV_PCI:
829             __PRE_XEN_DOMCTL_READ(test_assign_device, assign_device_0000000b, u.pci);
830             break;
831          case VKI_XEN_DOMCTL_DEV_DT:
832             __PRE_XEN_DOMCTL_READ(test_assign_device, assign_device_0000000b, u.dt);
833             PRE_MEM_READ("XEN_DOMTCL_test_assign_device.dt",
834                           (Addr)domctl->u.assign_device_0000000b.u.dt.path.p,
835                           domctl->u.assign_device_0000000b.u.dt.size);
836             break;
837          default:
838             bad_subop(tid, layout, arrghs, status, flags,
839                          "__HYPERVISOR_domctl_test_assign_device dev",
840                          domctl->u.assign_device_0000000b.dev);
841             break;
842          }
843          break;
844       }
845       break;
846    case VKI_XEN_DOMCTL_assign_device:
847       switch (domctl->interface_version) {
848       case 0x00000007: /* pre-4.6 */
849       case 0x00000008:
850       case 0x00000009:
851       case 0x0000000a:
852          __PRE_XEN_DOMCTL_READ(assign_device, assign_device_00000007, machine_sbdf);
853          break;
854       case 0x0000000b:
855          __PRE_XEN_DOMCTL_READ(assign_device, assign_device_0000000b, dev);
856          __PRE_XEN_DOMCTL_READ(assign_device, assign_device_0000000b, flag);
857          switch (domctl->u.assign_device_0000000b.dev) {
858          case VKI_XEN_DOMCTL_DEV_PCI:
859             __PRE_XEN_DOMCTL_READ(assign_device, assign_device_0000000b, u.pci);
860             break;
861          case VKI_XEN_DOMCTL_DEV_DT:
862             __PRE_XEN_DOMCTL_READ(assign_device, assign_device_0000000b, u.dt);
863             PRE_MEM_READ("XEN_DOMTCL_assign_device.dt",
864                           (Addr)domctl->u.assign_device_0000000b.u.dt.path.p,
865                           domctl->u.assign_device_0000000b.u.dt.size);
866             break;
867          default:
868             bad_subop(tid, layout, arrghs, status, flags,
869                          "__HYPERVISOR_domctl_assign_device dev",
870                          domctl->u.assign_device_0000000b.dev);
871             break;
872          }
873          break;
874       }
875       break;
876    case VKI_XEN_DOMCTL_deassign_device:
877       switch (domctl->interface_version) {
878       case 0x00000007: /* pre-4.6 */
879       case 0x00000008:
880       case 0x00000009:
881       case 0x0000000a:
882          __PRE_XEN_DOMCTL_READ(deassign_device, assign_device_00000007, machine_sbdf);
883          break;
884       case 0x0000000b:
885          __PRE_XEN_DOMCTL_READ(deassign_device, assign_device_0000000b, dev);
886          __PRE_XEN_DOMCTL_READ(deassign_device, assign_device_0000000b, flag);
887          switch (domctl->u.assign_device_0000000b.dev) {
888          case VKI_XEN_DOMCTL_DEV_PCI:
889             __PRE_XEN_DOMCTL_READ(deassign_device, assign_device_0000000b, u.pci);
890             break;
891          case VKI_XEN_DOMCTL_DEV_DT:
892             __PRE_XEN_DOMCTL_READ(deassign_device, assign_device_0000000b, u.dt);
893             PRE_MEM_READ("XEN_DOMTCL_assign_device.dt",
894                           (Addr)domctl->u.assign_device_0000000b.u.dt.path.p,
895                           domctl->u.assign_device_0000000b.u.dt.size);
896             break;
897          default:
898             bad_subop(tid, layout, arrghs, status, flags,
899                          "__HYPERVISOR_domctl_deassign_device dev",
900                          domctl->u.assign_device_0000000b.dev);
901             break;
902          }
903          break;
904       }
905       break;
906 
907    case VKI_XEN_DOMCTL_settscinfo:
908       switch (domctl->interface_version) {
909       case 0x00000007: /* pre-4.6 */
910       case 0x00000008:
911       case 0x00000009:
912       case 0x0000000a:
913          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_00000007, info.tsc_mode);
914          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_00000007, info.gtsc_khz);
915          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_00000007, info.incarnation);
916          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_00000007, info.elapsed_nsec);
917          break;
918       case 0x0000000b:
919          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_0000000b, tsc_mode);
920          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_0000000b, gtsc_khz);
921          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_0000000b, incarnation);
922          __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info_0000000b, elapsed_nsec);
923          break;
924       }
925       break;
926 
927    case VKI_XEN_DOMCTL_irq_permission:
928       PRE_XEN_DOMCTL_READ(irq_permission, pirq);
929       PRE_XEN_DOMCTL_READ(irq_permission, allow_access);
930       break;
931 
932    case VKI_XEN_DOMCTL_iomem_permission:
933       PRE_XEN_DOMCTL_READ(iomem_permission, first_mfn);
934       PRE_XEN_DOMCTL_READ(iomem_permission, nr_mfns);
935       PRE_XEN_DOMCTL_READ(iomem_permission, allow_access);
936       break;
937 
938    case VKI_XEN_DOMCTL_ioport_permission:
939       PRE_XEN_DOMCTL_READ(ioport_permission, first_port);
940       PRE_XEN_DOMCTL_READ(ioport_permission, nr_ports);
941       PRE_XEN_DOMCTL_READ(ioport_permission, allow_access);
942       break;
943 
944    case VKI_XEN_DOMCTL_hypercall_init:
945       PRE_XEN_DOMCTL_READ(hypercall_init, gmfn);
946       break;
947 
948    case VKI_XEN_DOMCTL_settimeoffset:
949        PRE_XEN_DOMCTL_READ(settimeoffset, time_offset_seconds);
950        break;
951 
952    case VKI_XEN_DOMCTL_getvcpuinfo:
953       PRE_XEN_DOMCTL_READ(getvcpuinfo, vcpu);
954       break;
955 
956    case VKI_XEN_DOMCTL_scheduler_op:
957       PRE_XEN_DOMCTL_READ(scheduler_op, sched_id);
958       PRE_XEN_DOMCTL_READ(scheduler_op, cmd);
959       if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_putinfo ) {
960          switch(domctl->u.scheduler_op.sched_id) {
961          case VKI_XEN_SCHEDULER_SEDF:
962             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.period);
963             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.slice);
964             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.latency);
965             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.extratime);
966             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.weight);
967             break;
968          case VKI_XEN_SCHEDULER_CREDIT:
969             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.weight);
970             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.cap);
971             break;
972          case VKI_XEN_SCHEDULER_CREDIT2:
973             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit2.weight);
974             break;
975          case VKI_XEN_SCHEDULER_RTDS:
976             PRE_XEN_DOMCTL_READ(scheduler_op, u.rtds.period);
977             PRE_XEN_DOMCTL_READ(scheduler_op, u.rtds.budget);
978             break;
979          case VKI_XEN_SCHEDULER_ARINC653:
980             break;
981          }
982       }
983       break;
984 
985    case VKI_XEN_DOMCTL_getvcpuaffinity:
986       switch (domctl->interface_version) {
987       case 0x00000007:
988       case 0x00000008:
989       case 0x00000009:
990          __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity_00000009, vcpu);
991          __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity_00000009, cpumap.nr_bits);
992          break;
993       case 0x0000000a:
994          __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity_0000000a, vcpu);
995          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_HARD)
996             __PRE_XEN_DOMCTL_READ(
997                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_hard.nr_bits);
998          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_SOFT)
999             __PRE_XEN_DOMCTL_READ(
1000                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_soft.nr_bits);
1001          break;
1002       }
1003       break;
1004 
1005    case VKI_XEN_DOMCTL_setvcpuaffinity:
1006       switch (domctl->interface_version) {
1007       case 0x00000007:
1008       case 0x00000008:
1009       case 0x00000009:
1010          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_00000009, vcpu);
1011          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_00000009, cpumap.nr_bits);
1012          PRE_MEM_READ("XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap.bitmap",
1013                       (Addr)domctl->u.vcpuaffinity_00000009.cpumap.bitmap.p,
1014                       domctl->u.vcpuaffinity_00000009.cpumap.nr_bits / 8);
1015          break;
1016       case 0x0000000a:
1017          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_0000000a, vcpu);
1018          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_0000000a, flags);
1019          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_HARD) {
1020             __PRE_XEN_DOMCTL_READ(
1021                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_hard.nr_bits);
1022             PRE_MEM_READ(
1023                "XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap_hard.bitmap",
1024                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_hard.bitmap.p,
1025                domctl->u.vcpuaffinity_0000000a.cpumap_hard.nr_bits / 8);
1026          }
1027          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_SOFT) {
1028             __PRE_XEN_DOMCTL_READ(
1029                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_soft.nr_bits);
1030             PRE_MEM_READ(
1031                "XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap_soft.bitmap",
1032                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_soft.bitmap.p,
1033                domctl->u.vcpuaffinity_0000000a.cpumap_soft.nr_bits / 8);
1034          }
1035       break;
1036       }
1037       break;
1038 
1039    case VKI_XEN_DOMCTL_getnodeaffinity:
1040       __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
1041       break;
1042    case VKI_XEN_DOMCTL_setnodeaffinity:
1043       __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
1044       PRE_MEM_READ("XEN_DOMCTL_setnodeaffinity u.nodeaffinity.cpumap.bitmap",
1045                    (Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
1046                    domctl->u.nodeaffinity.nodemap.nr_bits / 8);
1047       break;
1048 
1049    case VKI_XEN_DOMCTL_getvcpucontext:
1050       __PRE_XEN_DOMCTL_READ(getvcpucontext, vcpucontext, vcpu);
1051       break;
1052 
1053    case VKI_XEN_DOMCTL_setvcpucontext:
1054       __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, vcpu);
1055       __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, ctxt.p);
1056       break;
1057 
1058    case VKI_XEN_DOMCTL_pin_mem_cacheattr:
1059       PRE_XEN_DOMCTL_READ(pin_mem_cacheattr, start);
1060       PRE_XEN_DOMCTL_READ(pin_mem_cacheattr, end);
1061       PRE_XEN_DOMCTL_READ(pin_mem_cacheattr, type);
1062       break;
1063 
1064    case VKI_XEN_DOMCTL_get_ext_vcpucontext:
1065       switch (domctl->interface_version)
1066       {
1067       case 0x00000007:
1068       case 0x00000008:
1069          __PRE_XEN_DOMCTL_READ(get_ext_vcpucontext, ext_vcpucontext_00000008, vcpu);
1070          break;
1071 
1072       case 0x00000009:
1073          __PRE_XEN_DOMCTL_READ(get_ext_vcpucontext, ext_vcpucontext_00000009, vcpu);
1074          break;
1075 
1076       default:
1077          VG_(dmsg)("WARNING: VKI_XEN_DOMCTL_get_ext_vcpucontext  domctl version %#"
1078                    PRIx32" not implemented\n", domctl->interface_version);
1079          SET_STATUS_Failure(VKI_EINVAL);
1080          break;
1081       }
1082       break;
1083 
1084    case VKI_XEN_DOMCTL_set_ext_vcpucontext:
1085        switch (domctl->interface_version)
1086        {
1087        case 0x00000007:
1088        case 0x00000008:
1089            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008, vcpu);
1090            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008, size);
1091 #if defined(__i386__) || defined(__x86_64__)
1092            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1093                                  syscall32_callback_eip);
1094            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1095                                  sysenter_callback_eip);
1096            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1097                                  syscall32_callback_cs);
1098            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1099                                  sysenter_callback_cs);
1100            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1101                                  syscall32_disables_events);
1102            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1103                                  sysenter_disables_events);
1104 
1105            if ( domctl->u.ext_vcpucontext_00000008.size >=
1106                 offsetof(struct vki_xen_domctl_ext_vcpucontext_00000008, mcg_cap) )
1107                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1108                                      mcg_cap);
1109 #endif
1110            break;
1111 
1112        case 0x00000009:
1113            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009, vcpu);
1114            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009, size);
1115 #if defined(__i386__) || defined(__x86_64__)
1116            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1117                                  syscall32_callback_eip);
1118            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1119                                  sysenter_callback_eip);
1120            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1121                                  syscall32_callback_cs);
1122            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1123                                  sysenter_callback_cs);
1124            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1125                                  syscall32_disables_events);
1126            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1127                                  sysenter_disables_events);
1128 
1129            if ( domctl->u.ext_vcpucontext_00000009.size >=
1130                 offsetof(struct vki_xen_domctl_ext_vcpucontext_00000009, caps) )
1131            {
1132                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1133                                      caps);
1134                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1135                                      mci_ctl2_bank0);
1136                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1137                                      mci_ctl2_bank1);
1138            }
1139 #endif
1140 	   break;
1141 
1142        default:
1143            VG_(dmsg)("WARNING: VKI_XEN_DOMCTL_set_ext_vcpucontext  domctl version %#"
1144                      PRIx32" not implemented\n", domctl->interface_version);
1145            SET_STATUS_Failure(VKI_EINVAL);
1146            break;
1147        }
1148        break;
1149 
1150    case VKI_XEN_DOMCTL_set_cpuid:
1151       PRE_MEM_READ("XEN_DOMCTL_set_cpuid u.cpuid",
1152                    (Addr)&domctl->u.cpuid, sizeof(domctl->u.cpuid));
1153       break;
1154 
1155    case VKI_XEN_DOMCTL_getpageframeinfo3:
1156        PRE_XEN_DOMCTL_READ(getpageframeinfo3, num);
1157        PRE_XEN_DOMCTL_READ(getpageframeinfo3, array.p);
1158        PRE_MEM_READ("XEN_DOMCTL_getpageframeinfo3 *u.getpageframeinfo3.array.p",
1159                     (Addr)domctl->u.getpageframeinfo3.array.p,
1160                     domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
1161        break;
1162 
1163    case VKI_XEN_DOMCTL_setvcpuextstate:
1164       __PRE_XEN_DOMCTL_READ(setvcpuextstate, vcpuextstate, vcpu);
1165       __PRE_XEN_DOMCTL_READ(setvcpuextstate, vcpuextstate, size);
1166       __PRE_XEN_DOMCTL_READ(setvcpuextstate, vcpuextstate, buffer);
1167       PRE_MEM_READ("XEN_DOMCTL_setvcpuextstate *u.vcpuextstate.buffer.p",
1168                    (Addr)domctl->u.vcpuextstate.buffer.p,
1169                    domctl->u.vcpuextstate.size);
1170       break;
1171 
1172    case VKI_XEN_DOMCTL_getvcpuextstate:
1173       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, vcpu);
1174       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, xfeature_mask);
1175       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, size);
1176       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, buffer);
1177       break;
1178 
1179    case VKI_XEN_DOMCTL_shadow_op:
1180        PRE_XEN_DOMCTL_READ(shadow_op, op);
1181 
1182        switch(domctl->u.shadow_op.op)
1183        {
1184        case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
1185        case VKI_XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION:
1186            /* No further inputs */
1187            break;
1188 
1189        case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE:
1190            PRE_XEN_DOMCTL_READ(shadow_op, mode);
1191            switch(domctl->u.shadow_op.mode)
1192            {
1193            case XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY:
1194                goto domctl_shadow_op_enable_logdirty;
1195 
1196 
1197            default:
1198                bad_subop(tid, layout, arrghs, status, flags,
1199                          "__HYPERVISOR_domctl shadowop mode",
1200                          domctl->u.shadow_op.mode);
1201                break;
1202            }
1203 
1204        case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:
1205        domctl_shadow_op_enable_logdirty:
1206            /* No further inputs */
1207            break;
1208 
1209        case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
1210        case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
1211            PRE_XEN_DOMCTL_READ(shadow_op, dirty_bitmap);
1212            PRE_XEN_DOMCTL_READ(shadow_op, pages);
1213            break;
1214 
1215        case VKI_XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION:
1216            PRE_XEN_DOMCTL_READ(shadow_op, mb);
1217            break;
1218 
1219        default:
1220            bad_subop(tid, layout, arrghs, status, flags,
1221                      "__HYPERVISOR_domctl shadow(10)",
1222                      domctl->u.shadow_op.op);
1223            break;
1224        }
1225        break;
1226 
1227    case VKI_XEN_DOMCTL_set_max_evtchn:
1228       PRE_XEN_DOMCTL_READ(set_max_evtchn, max_port);
1229       break;
1230 
1231    case VKI_XEN_DOMCTL_cacheflush:
1232       PRE_XEN_DOMCTL_READ(cacheflush, start_pfn);
1233       PRE_XEN_DOMCTL_READ(cacheflush, nr_pfns);
1234       break;
1235 
1236    case VKI_XEN_DOMCTL_set_access_required:
1237       PRE_XEN_DOMCTL_READ(access_required, access_required);
1238       break;
1239 
1240    case VKI_XEN_DOMCTL_mem_event_op:
1241    //case VKI_XEN_DOMCTL_vm_event_op: /* name change in 4.6 */
1242       switch (domctl->interface_version) {
1243       case 0x00000007: /* pre-4.6 */
1244       case 0x00000008:
1245       case 0x00000009:
1246       case 0x0000000a:
1247          __PRE_XEN_DOMCTL_READ(mem_event_op, mem_event_op_00000007, op);
1248          __PRE_XEN_DOMCTL_READ(mem_event_op, mem_event_op_00000007, mode);
1249          break;
1250       case 0x0000000b:
1251          __PRE_XEN_DOMCTL_READ(vm_event_op, vm_event_op_0000000b, op);
1252          __PRE_XEN_DOMCTL_READ(vm_event_op, vm_event_op_0000000b, mode);
1253          break;
1254       }
1255       break;
1256 
1257    case VKI_XEN_DOMCTL_debug_op:
1258       PRE_XEN_DOMCTL_READ(debug_op, op);
1259       PRE_XEN_DOMCTL_READ(debug_op, vcpu);
1260       break;
1261 
1262    case VKI_XEN_DOMCTL_get_vcpu_msrs:
1263       __PRE_XEN_DOMCTL_READ(get_vcpu_msrs, vcpu_msrs, vcpu);
1264       __PRE_XEN_DOMCTL_READ(get_vcpu_msrs, vcpu_msrs, msr_count);
1265       __PRE_XEN_DOMCTL_READ(get_vcpu_msrs, vcpu_msrs, msrs);
1266       break;
1267 
1268    case VKI_XEN_DOMCTL_set_vcpu_msrs:
1269       __PRE_XEN_DOMCTL_READ(set_vcpu_msrs, vcpu_msrs, vcpu);
1270       __PRE_XEN_DOMCTL_READ(set_vcpu_msrs, vcpu_msrs, msr_count);
1271       __PRE_XEN_DOMCTL_READ(set_vcpu_msrs, vcpu_msrs, msrs);
1272       PRE_MEM_READ("XEN_DOMCTL_set_vcpu_msrs *u.vcpu_msrs.msrs.p",
1273                    (Addr)domctl->u.vcpu_msrs.msrs.p,
1274                    sizeof(vki_xen_domctl_vcpu_msr_t) *
1275                    domctl->u.vcpu_msrs.msr_count);
1276       break;
1277 
1278    case VKI_XEN_DOMCTL_monitor_op:
1279       switch (domctl->interface_version) {
1280       case 0x000000b:
1281           if (domctl->u.monitor_op_0000000b.op == VKI_XEN_DOMCTL_MONITOR_OP_ENABLE ||
1282               domctl->u.monitor_op_0000000b.op == VKI_XEN_DOMCTL_MONITOR_OP_ENABLE) {
1283              switch (domctl->u.monitor_op_0000000b.event) {
1284              case VKI_XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG:
1285                 __PRE_XEN_DOMCTL_READ(monitor_op, monitor_op_0000000b, u.mov_to_cr);
1286                 break;
1287              case VKI_XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR:
1288                 __PRE_XEN_DOMCTL_READ(monitor_op, monitor_op_0000000b, u.mov_to_msr);
1289                 break;
1290              case VKI_XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST:
1291                 __PRE_XEN_DOMCTL_READ(monitor_op, monitor_op_0000000b, u.guest_request);
1292                 break;
1293              case VKI_XEN_DOMCTL_MONITOR_OP_GET_CAPABILITIES:
1294                 break;
1295              }
1296           }
1297 
1298          break;
1299       }
1300       break;
1301 
1302    default:
1303       bad_subop(tid, layout, arrghs, status, flags,
1304                 "__HYPERVISOR_domctl", domctl->cmd);
1305       break;
1306    }
1307 #undef PRE_XEN_DOMCTL_READ
1308 #undef __PRE_XEN_DOMCTL_READ
1309 }
1310 
PRE(hvm_op)1311 PRE(hvm_op)
1312 {
1313    unsigned long op = ARG1;
1314    void *arg = (void *)(unsigned long)ARG2;
1315 
1316    PRINT("__HYPERVISOR_hvm_op ( %ld, %#lx )", SARG1, ARG2);
1317 
1318 #define __PRE_XEN_HVMOP_READ(_hvm_op, _type, _field)    \
1319    PRE_MEM_READ("XEN_HVMOP_" # _hvm_op " " #_field,     \
1320                 (Addr)&((_type*)arg)->_field,           \
1321                 sizeof(((_type*)arg)->_field))
1322 #define PRE_XEN_HVMOP_READ(_hvm_op, _field)                             \
1323    __PRE_XEN_HVMOP_READ(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
1324 
1325    switch (op) {
1326    case VKI_XEN_HVMOP_set_param:
1327       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, domid);
1328       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, index);
1329       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, value);
1330       break;
1331 
1332    case VKI_XEN_HVMOP_get_param:
1333       __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, domid);
1334       __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, index);
1335       break;
1336 
1337    case VKI_XEN_HVMOP_set_pci_intx_level:
1338       PRE_XEN_HVMOP_READ(set_pci_intx_level, domid);
1339       PRE_XEN_HVMOP_READ(set_pci_intx_level, domain);
1340       PRE_XEN_HVMOP_READ(set_pci_intx_level, bus);
1341       PRE_XEN_HVMOP_READ(set_pci_intx_level, device);
1342       PRE_XEN_HVMOP_READ(set_pci_intx_level, level);
1343       break;
1344 
1345    case VKI_XEN_HVMOP_set_isa_irq_level:
1346       PRE_XEN_HVMOP_READ(set_isa_irq_level, domid);
1347       PRE_XEN_HVMOP_READ(set_isa_irq_level, isa_irq);
1348       PRE_XEN_HVMOP_READ(set_isa_irq_level, level);
1349       break;
1350 
1351    case VKI_XEN_HVMOP_set_pci_link_route:
1352       PRE_XEN_HVMOP_READ(set_pci_link_route, domid);
1353       PRE_XEN_HVMOP_READ(set_pci_link_route, link);
1354       PRE_XEN_HVMOP_READ(set_pci_link_route, isa_irq);
1355       break;
1356 
1357    case VKI_XEN_HVMOP_track_dirty_vram: {
1358       vki_xen_hvm_track_dirty_vram_t *Arg =
1359          (vki_xen_hvm_track_dirty_vram_t*)ARG2;
1360       PRE_XEN_HVMOP_READ(track_dirty_vram, domid);
1361       PRE_XEN_HVMOP_READ(track_dirty_vram, nr);
1362       if ( Arg->nr ) {
1363          PRE_XEN_HVMOP_READ(track_dirty_vram, first_pfn);
1364          PRE_XEN_HVMOP_READ(track_dirty_vram, dirty_bitmap);
1365       }
1366       break;
1367    }
1368 
1369    case VKI_XEN_HVMOP_set_mem_type:
1370       PRE_XEN_HVMOP_READ(set_mem_type, domid);
1371       PRE_XEN_HVMOP_READ(set_mem_type, hvmmem_type);
1372       PRE_XEN_HVMOP_READ(set_mem_type, nr);
1373       PRE_XEN_HVMOP_READ(set_mem_type, first_pfn);
1374       break;
1375 
1376    case VKI_XEN_HVMOP_set_mem_access:
1377       PRE_XEN_HVMOP_READ(set_mem_access, domid);
1378       PRE_XEN_HVMOP_READ(set_mem_access, hvmmem_access);
1379       PRE_XEN_HVMOP_READ(set_mem_access, first_pfn);
1380       /* if default access */
1381       if ( ((vki_xen_hvm_set_mem_access_t*)arg)->first_pfn != ~0ULL)
1382          PRE_XEN_HVMOP_READ(set_mem_access, nr);
1383       break;
1384 
1385    case VKI_XEN_HVMOP_get_mem_access:
1386       PRE_XEN_HVMOP_READ(get_mem_access, domid);
1387       PRE_XEN_HVMOP_READ(get_mem_access, pfn);
1388 
1389       PRE_MEM_WRITE("XEN_HVMOP_get_mem_access *hvmmem_access",
1390                     (Addr)&(((vki_xen_hvm_get_mem_access_t*)arg)->hvmmem_access),
1391                     sizeof(vki_uint16_t));
1392       break;
1393 
1394    case VKI_XEN_HVMOP_inject_trap:
1395       PRE_XEN_HVMOP_READ(inject_trap, domid);
1396       PRE_XEN_HVMOP_READ(inject_trap, vcpuid);
1397       PRE_XEN_HVMOP_READ(inject_trap, vector);
1398       PRE_XEN_HVMOP_READ(inject_trap, type);
1399       PRE_XEN_HVMOP_READ(inject_trap, error_code);
1400       PRE_XEN_HVMOP_READ(inject_trap, insn_len);
1401       PRE_XEN_HVMOP_READ(inject_trap, cr2);
1402       break;
1403 
1404    default:
1405       bad_subop(tid, layout, arrghs, status, flags,
1406                 "__HYPERVISOR_hvm_op", op);
1407       break;
1408    }
1409 #undef __PRE_XEN_HVMOP_READ
1410 #undef PRE_XEN_HVMOP_READ
1411 }
1412 
PRE(tmem_op)1413 PRE(tmem_op)
1414 {
1415     struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
1416 
1417     PRINT("__HYPERVISOR_tmem_op ( %u )", tmem->cmd);
1418 
1419     /* Common part for xen_tmem_op:
1420      *    vki_uint32_t cmd;
1421      */
1422     PRE_MEM_READ("__HYPERVISOR_tmem_op cmd", ARG1, sizeof(vki_uint32_t));
1423 
1424 
1425 #define __PRE_XEN_TMEMOP_READ(_tmem, _union, _field)                    \
1426     PRE_MEM_READ("XEN_tmem_op_" #_tmem " u." #_union "." #_field,       \
1427                  (Addr)&tmem->u._union._field,                          \
1428                  sizeof(tmem->u._union._field))
1429 #define PRE_XEN_TMEMOP_READ(_tmem, _field)                              \
1430     __PRE_XEN_TMEMOP_READ(_tmem, _tmem, _field)
1431 
1432     switch(tmem->cmd) {
1433 
1434     case VKI_XEN_TMEM_control:
1435 
1436         /* Common part for control hypercall:
1437          *    vki_int32_t pool_id;
1438          *    vki_uint32_t subop;
1439          */
1440         PRE_MEM_READ("__HYPERVISOR_tmem_op pool_id",
1441                      (Addr)&tmem->pool_id, sizeof(tmem->pool_id));
1442         PRE_XEN_TMEMOP_READ(ctrl, subop);
1443 
1444         switch (tmem->u.ctrl.subop) {
1445 
1446         case VKI_XEN_TMEMC_save_begin:
1447             PRE_XEN_TMEMOP_READ(ctrl, cli_id);
1448             PRE_XEN_TMEMOP_READ(ctrl, arg1);
1449             PRE_XEN_TMEMOP_READ(ctrl, buf);
1450             break;
1451 
1452         default:
1453             bad_subop(tid, layout, arrghs, status, flags,
1454                       "__HYPERVISOR_tmem_op_control", tmem->u.ctrl.subop);
1455         }
1456 
1457         break;
1458 
1459     default:
1460         bad_subop(tid, layout, arrghs, status, flags,
1461                   "__HYPERVISOR_tmem_op", ARG1);
1462     }
1463 
1464 #undef PRE_XEN_TMEMOP_READ
1465 #undef __PRE_XEN_TMEMOP_READ
1466 }
1467 
POST(memory_op)1468 POST(memory_op)
1469 {
1470    switch (ARG1) {
1471    case VKI_XENMEM_maximum_ram_page:
1472    case VKI_XENMEM_set_memory_map:
1473    case VKI_XENMEM_decrease_reservation:
1474    case VKI_XENMEM_claim_pages:
1475    case VKI_XENMEM_maximum_gpfn:
1476    case VKI_XENMEM_remove_from_physmap:
1477    case VKI_XENMEM_access_op:
1478       /* No outputs */
1479       break;
1480    case VKI_XENMEM_increase_reservation:
1481    case VKI_XENMEM_populate_physmap: {
1482       struct xen_memory_reservation *memory_reservation =
1483          (struct xen_memory_reservation *)ARG2;
1484 
1485       POST_MEM_WRITE((Addr)memory_reservation->extent_start.p,
1486                      sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
1487       break;
1488    }
1489 
1490    case VKI_XENMEM_machphys_mfn_list:
1491    case VKI_XENMEM_machphys_compat_mfn_list: {
1492        struct vki_xen_machphys_mfn_list *arg =
1493            (struct vki_xen_machphys_mfn_list *)ARG2;
1494        POST_MEM_WRITE((Addr)&arg->nr_extents, sizeof(arg->nr_extents));
1495        POST_MEM_WRITE((Addr)arg->extent_start.p,
1496                       sizeof(vki_xen_pfn_t) * arg->nr_extents);
1497        break;
1498    }
1499 
1500    case VKI_XENMEM_memory_map:
1501    case VKI_XENMEM_machine_memory_map: {
1502       struct vki_xen_memory_map *arg =
1503          (struct vki_xen_memory_map *)ARG2;
1504       POST_MEM_WRITE(arg->nr_entries, sizeof(arg->nr_entries));
1505       POST_MEM_WRITE((Addr)arg->buffer.p,
1506                      arg->nr_entries * 20 /* size of an e820 entry */);
1507       break;
1508    }
1509 
1510    case VKI_XENMEM_add_to_physmap: {
1511        struct vki_xen_add_to_physmap *arg =
1512            (struct vki_xen_add_to_physmap *)ARG2;
1513        if (arg->space == VKI_XENMAPSPACE_gmfn_range)
1514            POST_MEM_WRITE(ARG2, sizeof(*arg));
1515    }
1516 
1517    case VKI_XENMEM_get_sharing_freed_pages:
1518    case VKI_XENMEM_get_sharing_shared_pages:
1519        /* No outputs */
1520        break;
1521    }
1522 }
1523 
POST(mmuext_op)1524 POST(mmuext_op)
1525 {
1526    unsigned int *pdone = (unsigned int *)ARG3;
1527    /* simplistic */
1528    POST_MEM_WRITE((Addr)pdone, sizeof(*pdone));
1529 }
1530 
POST(xsm_op)1531 POST(xsm_op)
1532 {
1533    /* XXX assuming flask, only actual XSM right now */
1534    struct vki_xen_flask_op *op = (struct vki_xen_flask_op *)ARG1;
1535 
1536    switch (op->interface_version) {
1537    case 0x00000001:
1538       break;
1539    default:
1540       return;
1541    }
1542 
1543 #define POST_XEN_XSM_OP_WRITE(_xsm_op, _union, _field)        \
1544       POST_MEM_WRITE((Addr)&op->u._union._field,              \
1545                      sizeof(op->u._union._field))
1546 
1547    switch (op->cmd) {
1548    case VKI_FLASK_SID_TO_CONTEXT:
1549       POST_XEN_XSM_OP_WRITE(SID_TO_CONTEXT, sid_context, size);
1550       POST_MEM_WRITE((Addr)op->u.sid_context.context.p,
1551                      op->u.sid_context.size);
1552    }
1553 }
1554 
post_evtchn_op(ThreadId tid,__vki_u32 cmd,void * arg,int compat)1555 static void post_evtchn_op(ThreadId tid, __vki_u32 cmd, void *arg, int compat)
1556 {
1557    switch (cmd) {
1558    case VKI_XEN_EVTCHNOP_alloc_unbound: {
1559       struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg;
1560       POST_MEM_WRITE((Addr)&alloc_unbound->port, sizeof(alloc_unbound->port));
1561       break;
1562    }
1563    }
1564 }
1565 
POST(sched_op)1566 POST(sched_op)
1567 {
1568    switch (ARG1) {
1569    case VKI_XEN_SCHEDOP_remote_shutdown:
1570       /* No outputs */
1571       break;
1572    }
1573 }
1574 
POST(evtchn_op)1575 POST(evtchn_op)
1576 {
1577    post_evtchn_op(tid, ARG1, (void *)ARG2, 0);
1578 }
1579 
POST(evtchn_op_compat)1580 POST(evtchn_op_compat)
1581 {
1582    struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1;
1583    post_evtchn_op(tid, evtchn->cmd, &evtchn->u, 1);
1584 }
1585 
POST(physdev_op)1586 POST(physdev_op)
1587 {
1588    int cmd = ARG1;
1589 
1590 #define POST_XEN_PHYSDEVOP_WRITE(_op, _field)                   \
1591    POST_MEM_WRITE((Addr)&arg->_field, sizeof(arg->_field))
1592 
1593    switch (cmd) {
1594    case VKI_XEN_PHYSDEVOP_unmap_pirq:
1595       /* No outputs */
1596       break;
1597 
1598    case VKI_XEN_PHYSDEVOP_map_pirq: {
1599       struct vki_xen_physdev_map_pirq *arg =
1600          (struct vki_xen_physdev_map_pirq *)ARG2;
1601       if (arg->type == VKI_XEN_MAP_PIRQ_TYPE_MULTI_MSI)
1602          POST_XEN_PHYSDEVOP_WRITE("map_pirq", entry_nr);
1603       POST_XEN_PHYSDEVOP_WRITE("map_pirq", pirq);
1604       break;
1605    }
1606 #undef POST_XEN_PHYSDEVOP_WRITE
1607 
1608    default:
1609       break;
1610    }
1611 }
1612 
POST(xen_version)1613 POST(xen_version)
1614 {
1615    switch (ARG1) {
1616    case VKI_XENVER_version:
1617       /* No outputs */
1618       break;
1619    case VKI_XENVER_extraversion:
1620       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_extraversion_t));
1621       break;
1622    case VKI_XENVER_compile_info:
1623       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_compile_info));
1624       break;
1625    case VKI_XENVER_capabilities:
1626       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_capabilities_info_t));
1627       break;
1628    case VKI_XENVER_changeset:
1629       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_changeset_info_t));
1630       break;
1631    case VKI_XENVER_platform_parameters:
1632       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_platform_parameters));
1633       break;
1634    case VKI_XENVER_get_features:
1635       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_feature_info));
1636       break;
1637    case VKI_XENVER_pagesize:
1638       /* No outputs */
1639       break;
1640    case VKI_XENVER_guest_handle:
1641       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_domain_handle_t));
1642       break;
1643    case VKI_XENVER_commandline:
1644       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_commandline_t));
1645       break;
1646    }
1647 }
1648 
POST(grant_table_op)1649 POST(grant_table_op)
1650 {
1651    switch (ARG1) {
1652    case VKI_XEN_GNTTABOP_setup_table: {
1653       struct vki_xen_gnttab_setup_table *gst =
1654 	      (struct vki_xen_gnttab_setup_table*)ARG2;
1655       PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
1656                     (Addr)&gst->status, sizeof(gst->status));
1657       PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
1658                     (Addr)gst->frame_list.p,
1659                     sizeof(*gst->frame_list.p) & gst->nr_frames);
1660       break;
1661    }
1662    }
1663 }
1664 
POST(sysctl)1665 POST(sysctl)
1666 {
1667    struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1;
1668 
1669    switch (sysctl->interface_version)
1670    {
1671    case 0x00000008:
1672    case 0x00000009:
1673    case 0x0000000a:
1674    case 0x0000000b:
1675 	   break;
1676    default:
1677       return;
1678    }
1679 
1680 #define __POST_XEN_SYSCTL_WRITE(_sysctl, _union, _field)        \
1681       POST_MEM_WRITE((Addr)&sysctl->u._union._field,            \
1682                      sizeof(sysctl->u._union._field))
1683 #define POST_XEN_SYSCTL_WRITE(_sysctl, _field) \
1684       __POST_XEN_SYSCTL_WRITE(_sysctl, _sysctl, _field)
1685 
1686    switch (sysctl->cmd) {
1687    case VKI_XEN_SYSCTL_readconsole:
1688        POST_MEM_WRITE((Addr)sysctl->u.readconsole.buffer.p,
1689                       sysctl->u.readconsole.count * sizeof(char));
1690        break;
1691 
1692    case VKI_XEN_SYSCTL_getdomaininfolist:
1693       switch (sysctl->interface_version)
1694       {
1695       case 0x00000008:
1696 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000008, num_domains);
1697 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000008.buffer.p,
1698 			sizeof(*sysctl->u.getdomaininfolist_00000008.buffer.p)
1699 			* sysctl->u.getdomaininfolist_00000008.num_domains);
1700 	 break;
1701       case 0x00000009:
1702 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000009, num_domains);
1703 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000009.buffer.p,
1704 			sizeof(*sysctl->u.getdomaininfolist_00000009.buffer.p)
1705 			* sysctl->u.getdomaininfolist_00000009.num_domains);
1706 	 break;
1707       case 0x0000000a:
1708       case 0x0000000b:
1709 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_0000000a, num_domains);
1710 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_0000000a.buffer.p,
1711 			sizeof(*sysctl->u.getdomaininfolist_0000000a.buffer.p)
1712 			* sysctl->u.getdomaininfolist_0000000a.num_domains);
1713 	 break;
1714       }
1715       break;
1716 
1717    case VKI_XEN_SYSCTL_sched_id:
1718        POST_XEN_SYSCTL_WRITE(sched_id, sched_id);
1719        break;
1720 
1721    case VKI_XEN_SYSCTL_cpupool_op:
1722       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE ||
1723           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO)
1724          POST_XEN_SYSCTL_WRITE(cpupool_op, cpupool_id);
1725       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO) {
1726          POST_XEN_SYSCTL_WRITE(cpupool_op, sched_id);
1727          POST_XEN_SYSCTL_WRITE(cpupool_op, n_dom);
1728       }
1729       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO ||
1730           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_FREEINFO)
1731          POST_XEN_SYSCTL_WRITE(cpupool_op, cpumap);
1732       break;
1733 
1734    case VKI_XEN_SYSCTL_physinfo:
1735       switch (sysctl->interface_version)
1736       {
1737       case 0x00000008:
1738       case 0x00000009: /* Unchanged from version 8 */
1739          POST_XEN_SYSCTL_WRITE(physinfo_00000008, threads_per_core);
1740          POST_XEN_SYSCTL_WRITE(physinfo_00000008, cores_per_socket);
1741          POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_cpus);
1742          POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_cpu_id);
1743          POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_nodes);
1744          POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_node_id);
1745          POST_XEN_SYSCTL_WRITE(physinfo_00000008, cpu_khz);
1746          POST_XEN_SYSCTL_WRITE(physinfo_00000008, total_pages);
1747          POST_XEN_SYSCTL_WRITE(physinfo_00000008, free_pages);
1748          POST_XEN_SYSCTL_WRITE(physinfo_00000008, scrub_pages);
1749          POST_XEN_SYSCTL_WRITE(physinfo_00000008, hw_cap[8]);
1750          POST_XEN_SYSCTL_WRITE(physinfo_00000008, capabilities);
1751          break;
1752       case 0x0000000a:
1753       case 0x0000000b:
1754          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, threads_per_core);
1755          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cores_per_socket);
1756          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_cpus);
1757          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_cpu_id);
1758          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_nodes);
1759          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_node_id);
1760          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cpu_khz);
1761          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, total_pages);
1762          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, free_pages);
1763          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, scrub_pages);
1764          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, outstanding_pages);
1765          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, hw_cap[8]);
1766          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, capabilities);
1767          break;
1768       }
1769       break;
1770 
1771    case VKI_XEN_SYSCTL_topologyinfo:
1772       POST_XEN_SYSCTL_WRITE(topologyinfo, max_cpu_index);
1773       if (sysctl->u.topologyinfo.cpu_to_core.p)
1774          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_core.p,
1775                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
1776       if (sysctl->u.topologyinfo.cpu_to_socket.p)
1777          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_socket.p,
1778                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
1779       if (sysctl->u.topologyinfo.cpu_to_node.p)
1780          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_node.p,
1781                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
1782       break;
1783 
1784    case VKI_XEN_SYSCTL_numainfo:
1785       POST_XEN_SYSCTL_WRITE(numainfo, max_node_index);
1786       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memsize.p,
1787                      sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
1788       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memfree.p,
1789                      sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
1790       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_node_distance.p,
1791                      sizeof(uint32_t) * sysctl->u.numainfo.max_node_index);
1792       break;
1793 
1794    /* No outputs */
1795    case VKI_XEN_SYSCTL_debug_keys:
1796        break;
1797    }
1798 #undef POST_XEN_SYSCTL_WRITE
1799 #undef __POST_XEN_SYSCTL_WRITE
1800 }
1801 
POST(domctl)1802 POST(domctl){
1803    struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1;
1804 
1805    switch (domctl->interface_version) {
1806    case 0x00000007:
1807    case 0x00000008:
1808    case 0x00000009:
1809    case 0x0000000a:
1810    case 0x0000000b:
1811 	   break;
1812    default:
1813 	   return;
1814    }
1815 
1816 #define __POST_XEN_DOMCTL_WRITE(_domctl, _union, _field)        \
1817    POST_MEM_WRITE((Addr)&domctl->u._union._field,               \
1818                   sizeof(domctl->u._union._field));
1819 #define POST_XEN_DOMCTL_WRITE(_domctl, _field)          \
1820    __POST_XEN_DOMCTL_WRITE(_domctl, _domctl, _field)
1821 
1822    switch (domctl->cmd) {
1823    case VKI_XEN_DOMCTL_createdomain:
1824    case VKI_XEN_DOMCTL_destroydomain:
1825    case VKI_XEN_DOMCTL_pausedomain:
1826    case VKI_XEN_DOMCTL_max_mem:
1827    case VKI_XEN_DOMCTL_setvcpuextstate:
1828    case VKI_XEN_DOMCTL_set_address_size:
1829    case VKI_XEN_DOMCTL_test_assign_device:
1830    case VKI_XEN_DOMCTL_assign_device:
1831    case VKI_XEN_DOMCTL_deassign_device:
1832    case VKI_XEN_DOMCTL_settscinfo:
1833    case VKI_XEN_DOMCTL_irq_permission:
1834    case VKI_XEN_DOMCTL_iomem_permission:
1835    case VKI_XEN_DOMCTL_ioport_permission:
1836    case VKI_XEN_DOMCTL_hypercall_init:
1837    case VKI_XEN_DOMCTL_setvcpucontext:
1838    case VKI_XEN_DOMCTL_pin_mem_cacheattr:
1839    case VKI_XEN_DOMCTL_set_ext_vcpucontext:
1840    case VKI_XEN_DOMCTL_setnodeaffinity:
1841    case VKI_XEN_DOMCTL_set_cpuid:
1842    case VKI_XEN_DOMCTL_unpausedomain:
1843    case VKI_XEN_DOMCTL_sethvmcontext:
1844    case VKI_XEN_DOMCTL_debug_op:
1845    case VKI_XEN_DOMCTL_set_max_evtchn:
1846    case VKI_XEN_DOMCTL_cacheflush:
1847    case VKI_XEN_DOMCTL_resumedomain:
1848    case VKI_XEN_DOMCTL_set_vcpu_msrs:
1849    case VKI_XEN_DOMCTL_set_access_required:
1850       /* No output fields */
1851       break;
1852 
1853    case VKI_XEN_DOMCTL_max_vcpus:
1854       POST_XEN_DOMCTL_WRITE(max_vcpus, max);
1855       break;
1856 
1857    case VKI_XEN_DOMCTL_get_address_size:
1858       __POST_XEN_DOMCTL_WRITE(get_address_size, address_size, size);
1859       break;
1860 
1861    case VKI_XEN_DOMCTL_gettscinfo:
1862       switch (domctl->interface_version) {
1863       case 0x00000007: /* pre-4.6 */
1864       case 0x00000008:
1865       case 0x00000009:
1866       case 0x0000000a:
1867          __POST_XEN_DOMCTL_WRITE(gettscinfo, tsc_info_00000007, out_info);
1868          POST_MEM_WRITE((Addr)domctl->u.tsc_info_00000007.out_info.p,
1869                         sizeof(vki_xen_guest_tsc_info_t));
1870          break;
1871       case 0x0000000b:
1872          __POST_XEN_DOMCTL_WRITE(gettscinfo, tsc_info_0000000b, tsc_mode);
1873          __POST_XEN_DOMCTL_WRITE(gettscinfo, tsc_info_0000000b, gtsc_khz);
1874          __POST_XEN_DOMCTL_WRITE(gettscinfo, tsc_info_0000000b, incarnation);
1875          __POST_XEN_DOMCTL_WRITE(gettscinfo, tsc_info_0000000b, elapsed_nsec);
1876          break;
1877       }
1878       break;
1879       break;
1880 
1881    case VKI_XEN_DOMCTL_getvcpuinfo:
1882       POST_XEN_DOMCTL_WRITE(getvcpuinfo, online);
1883       POST_XEN_DOMCTL_WRITE(getvcpuinfo, blocked);
1884       POST_XEN_DOMCTL_WRITE(getvcpuinfo, running);
1885       POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu_time);
1886       POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu);
1887       break;
1888 
1889    case VKI_XEN_DOMCTL_gethvmcontext:
1890        /* Xen unconditionally writes size... */
1891        __POST_XEN_DOMCTL_WRITE(gethvmcontext, hvmcontext, size);
1892        /* ...but only writes to the buffer if it was non NULL */
1893        if ( domctl->u.hvmcontext.buffer.p )
1894            POST_MEM_WRITE((Addr)domctl->u.hvmcontext.buffer.p,
1895                           sizeof(*domctl->u.hvmcontext.buffer.p)
1896                           * domctl->u.hvmcontext.size);
1897        break;
1898 
1899    case VKI_XEN_DOMCTL_gethvmcontext_partial:
1900        switch (domctl->u.hvmcontext_partial.type) {
1901        case VKI_HVM_SAVE_CODE(CPU):
1902            if ( domctl->u.hvmcontext_partial.buffer.p )
1903                 POST_MEM_WRITE((Addr)domctl->u.hvmcontext_partial.buffer.p,
1904                    VKI_HVM_SAVE_LENGTH(CPU));
1905            break;
1906        }
1907        break;
1908 
1909    case VKI_XEN_DOMCTL_scheduler_op:
1910       if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_getinfo ) {
1911          switch(domctl->u.scheduler_op.sched_id) {
1912          case VKI_XEN_SCHEDULER_SEDF:
1913             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.period);
1914             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.slice);
1915             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.latency);
1916             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.extratime);
1917             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.weight);
1918             break;
1919          case VKI_XEN_SCHEDULER_CREDIT:
1920             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.weight);
1921             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.cap);
1922             break;
1923          case VKI_XEN_SCHEDULER_CREDIT2:
1924             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit2.weight);
1925             break;
1926          case VKI_XEN_SCHEDULER_ARINC653:
1927             break;
1928          case VKI_XEN_SCHEDULER_RTDS:
1929             POST_XEN_DOMCTL_WRITE(scheduler_op, u.rtds.period);
1930             POST_XEN_DOMCTL_WRITE(scheduler_op, u.rtds.budget);
1931             break;
1932          }
1933       }
1934       break;
1935 
1936    case VKI_XEN_DOMCTL_getvcpuaffinity:
1937    case VKI_XEN_DOMCTL_setvcpuaffinity: /* Writes back actual result */
1938       switch (domctl->interface_version) {
1939       case 0x00000007:
1940       case 0x00000008:
1941       case 0x00000009:
1942          POST_MEM_WRITE((Addr)domctl->u.vcpuaffinity_00000009.cpumap.bitmap.p,
1943                         domctl->u.vcpuaffinity_00000009.cpumap.nr_bits / 8);
1944          break;
1945       case 0x0000000a:
1946          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_HARD)
1947             POST_MEM_WRITE(
1948                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_hard.bitmap.p,
1949                domctl->u.vcpuaffinity_0000000a.cpumap_hard.nr_bits / 8);
1950          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_SOFT)
1951             POST_MEM_WRITE(
1952                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_soft.bitmap.p,
1953                domctl->u.vcpuaffinity_0000000a.cpumap_soft.nr_bits / 8);
1954       }
1955       break;
1956 
1957    case VKI_XEN_DOMCTL_getnodeaffinity:
1958       POST_MEM_WRITE((Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
1959                      domctl->u.nodeaffinity.nodemap.nr_bits / 8);
1960       break;
1961 
1962    case VKI_XEN_DOMCTL_getdomaininfo:
1963       switch (domctl->interface_version) {
1964       case 0x00000007:
1965 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, domain);
1966 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, flags);
1967 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, tot_pages);
1968 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_pages);
1969 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shr_pages);
1970 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shared_info_frame);
1971 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpu_time);
1972 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, nr_online_vcpus);
1973 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_vcpu_id);
1974 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, ssidref);
1975 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, handle);
1976 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpupool);
1977       break;
1978       case 0x00000008:
1979 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, domain);
1980 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, flags);
1981 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, tot_pages);
1982 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_pages);
1983 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shr_pages);
1984 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, paged_pages);
1985 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shared_info_frame);
1986 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpu_time);
1987 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, nr_online_vcpus);
1988 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_vcpu_id);
1989 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, ssidref);
1990 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, handle);
1991 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpupool);
1992       break;
1993       case 0x00000009:
1994       case 0x0000000a:
1995 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, domain);
1996 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, flags);
1997 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, tot_pages);
1998 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_pages);
1999 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, outstanding_pages);
2000 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shr_pages);
2001 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, paged_pages);
2002 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shared_info_frame);
2003 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpu_time);
2004 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, nr_online_vcpus);
2005 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_vcpu_id);
2006 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, ssidref);
2007 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, handle);
2008 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpupool);
2009       break;
2010       }
2011       break;
2012    case VKI_XEN_DOMCTL_getvcpucontext:
2013       __POST_XEN_DOMCTL_WRITE(getvcpucontext, vcpucontext, ctxt.p);
2014       break;
2015 
2016    case VKI_XEN_DOMCTL_getpageframeinfo3:
2017        POST_MEM_WRITE((Addr)domctl->u.getpageframeinfo3.array.p,
2018                       domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
2019        break;
2020 
2021    case VKI_XEN_DOMCTL_get_ext_vcpucontext:
2022        switch (domctl->interface_version)
2023        {
2024        case 0x00000007:
2025        case 0x00000008:
2026            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008, size);
2027 #if defined(__i386__) || defined(__x86_64__)
2028            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
2029                                    syscall32_callback_eip);
2030            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
2031                                    sysenter_callback_eip);
2032            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
2033                                    syscall32_callback_cs);
2034            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
2035                                    sysenter_callback_cs);
2036            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
2037                                    syscall32_disables_events);
2038            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
2039                                    sysenter_disables_events);
2040 
2041            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
2042                                    mcg_cap);
2043 #endif
2044            break;
2045 
2046        case 0x00000009:
2047            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009, size);
2048 #if defined(__i386__) || defined(__x86_64__)
2049            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2050                                    syscall32_callback_eip);
2051            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2052                                    sysenter_callback_eip);
2053            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2054                                    syscall32_callback_cs);
2055            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2056                                    sysenter_callback_cs);
2057            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2058                                    syscall32_disables_events);
2059            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2060                                    sysenter_disables_events);
2061 
2062            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2063                                    caps);
2064            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2065                                    mci_ctl2_bank0);
2066            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
2067                                    mci_ctl2_bank1);
2068 #endif
2069 	   break;
2070        }
2071        break;
2072 
2073 
2074    case VKI_XEN_DOMCTL_getvcpuextstate:
2075       if (domctl->u.vcpuextstate.buffer.p)
2076          POST_MEM_WRITE((Addr)domctl->u.vcpuextstate.buffer.p,
2077                         domctl->u.vcpuextstate.size);
2078       break;
2079 
2080    case VKI_XEN_DOMCTL_shadow_op:
2081        switch(domctl->u.shadow_op.op)
2082        {
2083        case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
2084        case VKI_XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION:
2085            /* No outputs */
2086            break;
2087 
2088        case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
2089        case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
2090            POST_XEN_DOMCTL_WRITE(shadow_op, pages);
2091            POST_XEN_DOMCTL_WRITE(shadow_op, stats.fault_count);
2092            POST_XEN_DOMCTL_WRITE(shadow_op, stats.dirty_count);
2093            if(domctl->u.shadow_op.dirty_bitmap.p)
2094                POST_MEM_WRITE((Addr)domctl->u.shadow_op.dirty_bitmap.p,
2095                               domctl->u.shadow_op.pages * sizeof(vki_uint8_t));
2096            break;
2097 
2098        case VKI_XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION:
2099            POST_XEN_DOMCTL_WRITE(shadow_op, mb);
2100            break;
2101 
2102        default:
2103            break;
2104        }
2105        break;
2106    case VKI_XEN_DOMCTL_get_vcpu_msrs:
2107       if (domctl->u.vcpu_msrs.msrs.p)
2108          POST_MEM_WRITE((Addr)domctl->u.vcpu_msrs.msrs.p,
2109                         sizeof(vki_xen_domctl_vcpu_msr_t) *
2110                         domctl->u.vcpu_msrs.msr_count);
2111       break;
2112 
2113    case VKI_XEN_DOMCTL_mem_event_op:
2114    //case VKI_XEN_DOMCTL_vm_event_op: /* name change in 4.6 */
2115       switch (domctl->interface_version) {
2116       case 0x00000007: /* pre-4.6 */
2117       case 0x00000008:
2118       case 0x00000009:
2119       case 0x0000000a:
2120          __POST_XEN_DOMCTL_WRITE(mem_event_op, mem_event_op_00000007, port);
2121          break;
2122       case 0x0000000b:
2123          __POST_XEN_DOMCTL_WRITE(vm_event_op, vm_event_op_0000000b, port);
2124          break;
2125       }
2126       break;
2127 
2128    case VKI_XEN_DOMCTL_monitor_op:
2129       switch (domctl->interface_version) {
2130       case 0x000000b:
2131           if (domctl->u.monitor_op_0000000b.op == VKI_XEN_DOMCTL_MONITOR_OP_GET_CAPABILITIES) {
2132              switch(domctl->u.monitor_op_0000000b.event) {
2133              case VKI_XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG:
2134                 __POST_XEN_DOMCTL_WRITE(monitor_op, monitor_op_0000000b, u.mov_to_cr);
2135                 break;
2136              case VKI_XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR:
2137                 __POST_XEN_DOMCTL_WRITE(monitor_op, monitor_op_0000000b, u.mov_to_msr);
2138                 break;
2139              case VKI_XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST:
2140                 __POST_XEN_DOMCTL_WRITE(monitor_op, monitor_op_0000000b, u.guest_request);
2141                 break;
2142              }
2143           }
2144 
2145          break;
2146       }
2147       break;
2148    }
2149 
2150 #undef POST_XEN_DOMCTL_WRITE
2151 #undef __POST_XEN_DOMCTL_WRITE
2152 }
2153 
POST(hvm_op)2154 POST(hvm_op)
2155 {
2156    unsigned long op = ARG1;
2157    void *arg = (void *)(unsigned long)ARG2;
2158 
2159 #define __POST_XEN_HVMOP_WRITE(_hvm_op, _type, _field)  \
2160       POST_MEM_WRITE((Addr)&((_type*)arg)->_field,      \
2161                      sizeof(((_type*)arg)->_field))
2162 #define POST_XEN_HVMOP_WRITE(_hvm_op, _field) \
2163       __POST_XEN_HVMOP_WRITE(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
2164 
2165    switch (op) {
2166    case VKI_XEN_HVMOP_set_param:
2167    case VKI_XEN_HVMOP_set_pci_intx_level:
2168    case VKI_XEN_HVMOP_set_isa_irq_level:
2169    case VKI_XEN_HVMOP_set_pci_link_route:
2170    case VKI_XEN_HVMOP_set_mem_type:
2171    case VKI_XEN_HVMOP_set_mem_access:
2172    case VKI_XEN_HVMOP_inject_trap:
2173       /* No output parameters */
2174       break;
2175 
2176    case VKI_XEN_HVMOP_get_param:
2177       __POST_XEN_HVMOP_WRITE(get_param, struct vki_xen_hvm_param, value);
2178       break;
2179 
2180    case VKI_XEN_HVMOP_get_mem_access:
2181       POST_XEN_HVMOP_WRITE(get_mem_access, hvmmem_access);
2182       break;
2183    }
2184 #undef __POST_XEN_HVMOP_WRITE
2185 #undef POST_XEN_HVMOP_WRITE
2186 }
2187 
POST(tmem_op)2188 POST(tmem_op)
2189 {
2190     struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
2191 
2192     switch(tmem->cmd) {
2193 
2194     case VKI_XEN_TMEM_control:
2195 
2196         switch(tmem->u.ctrl.subop) {
2197             /* No outputs */
2198             case VKI_XEN_TMEMC_save_begin:
2199                 break;
2200         }
2201 
2202         break;
2203     }
2204 }
2205 
2206 typedef
2207    struct {
2208       SyscallTableEntry entry;
2209       int nr_args;
2210    }
2211    XenHypercallTableEntry;
2212 
2213 #define HYPX_(const, name, nr_args) \
2214    [const] = { { vgSysWrap_xen_##name##_before, NULL }, nr_args }
2215 #define HYPXY(const, name, nr_args)                     \
2216    [const] = { { vgSysWrap_xen_##name##_before,         \
2217                  vgSysWrap_xen_##name##_after },        \
2218                nr_args }
2219 
2220 static XenHypercallTableEntry hypercall_table[] = {
2221    //    __VKI_XEN_set_trap_table                                  // 0
2222    //    __VKI_XEN_mmu_update                                      // 1
2223    //    __VKI_XEN_set_gdt                                         // 2
2224    //    __VKI_XEN_stack_switch                                    // 3
2225    //    __VKI_XEN_set_callbacks                                   // 4
2226 
2227    //    __VKI_XEN_fpu_taskswitch                                  // 5
2228    //    __VKI_XEN_sched_op_compat                                 // 6
2229    //    __VKI_XEN_platform_op                                     // 7
2230    //    __VKI_XEN_set_debugreg                                    // 8
2231    //    __VKI_XEN_get_debugreg                                    // 9
2232 
2233    //    __VKI_XEN_update_descriptor                               // 10
2234    //                                                                 // 11
2235    HYPXY(__VKI_XEN_memory_op,               memory_op,         2), // 12
2236    //    __VKI_XEN_multicall                                       // 13
2237    //    __VKI_XEN_update_va_mapping                               // 14
2238 
2239    //    __VKI_XEN_set_timer_op                                    // 15
2240    HYPXY(__VKI_XEN_event_channel_op_compat, evtchn_op_compat,  1), // 16
2241    HYPXY(__VKI_XEN_xen_version,             xen_version,       2), // 17
2242    //    __VKI_XEN_console_io                                      // 18
2243    //    __VKI_XEN_physdev_op_compat                               // 19
2244 
2245    HYPXY(__VKI_XEN_grant_table_op,          grant_table_op,    3), // 20
2246    //    __VKI_XEN_vm_assist                                       // 21
2247    //    __VKI_XEN_update_va_mapping_otherdomain                   // 22
2248    //    __VKI_XEN_iret,                    iret                   // 23
2249    //    __VKI_XEN_vcpu_op,                 vcpu_op                // 24
2250 
2251    //    __VKI_XEN_set_segment_base                                // 25
2252    HYPXY(__VKI_XEN_mmuext_op,               mmuext_op,         2), // 26
2253    HYPXY(__VKI_XEN_xsm_op,                  xsm_op,            1), // 27
2254    //    __VKI_XEN_nmi_op                                          // 28
2255    HYPXY(__VKI_XEN_sched_op,                sched_op,          2), // 29
2256 
2257    //    __VKI_XEN_callback_op                                     // 30
2258    //    __VKI_XEN_xenoprof_op                                     // 31
2259    HYPXY(__VKI_XEN_event_channel_op,        evtchn_op,         2), // 32
2260    HYPXY(__VKI_XEN_physdev_op,              physdev_op,        2), // 33
2261    HYPXY(__VKI_XEN_hvm_op,                  hvm_op,            2), // 34
2262 
2263    HYPXY(__VKI_XEN_sysctl,                  sysctl,            1), // 35
2264    HYPXY(__VKI_XEN_domctl,                  domctl,            1), // 36
2265    //    __VKI_XEN_kexec_op                                        // 37
2266    HYPXY(__VKI_XEN_tmem_op,                 tmem_op,           1), // 38
2267 };
2268 
bad_before(ThreadId tid,SyscallArgLayout * layout,SyscallArgs * args,SyscallStatus * status,UWord * flags)2269 static void bad_before ( ThreadId              tid,
2270                          SyscallArgLayout*     layout,
2271                          /*MOD*/SyscallArgs*   args,
2272                          /*OUT*/SyscallStatus* status,
2273                          /*OUT*/UWord*         flags )
2274 {
2275    VG_(dmsg)("WARNING: unhandled hypercall: %s\n",
2276       VG_SYSNUM_STRING(args->sysno));
2277    if (VG_(clo_verbosity) > 1) {
2278       VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
2279    }
2280    VG_(dmsg)("You may be able to write your own handler.\n");
2281    VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
2282    VG_(dmsg)("Nevertheless we consider this a bug.  Please report\n");
2283    VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
2284    VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
2285 
2286    SET_STATUS_Failure(VKI_ENOSYS);
2287 }
2288 
2289 static XenHypercallTableEntry bad_hyper =
2290 { { bad_before, NULL }, 0 };
2291 
ML_(get_xen_hypercall_entry)2292 static XenHypercallTableEntry* ML_(get_xen_hypercall_entry) ( UInt sysno )
2293 {
2294    XenHypercallTableEntry *ret = &bad_hyper;
2295 
2296    const UInt hypercall_table_size
2297       = sizeof(hypercall_table) / sizeof(hypercall_table[0]);
2298 
2299    /* Is it in the contiguous initial section of the table? */
2300    if (sysno < hypercall_table_size) {
2301       XenHypercallTableEntry* ent = &hypercall_table[sysno];
2302       if (ent->entry.before != NULL)
2303          ret = ent;
2304    }
2305 
2306    /* Can't find a wrapper */
2307    return ret;
2308 }
2309 
DEFN_PRE_TEMPLATE(xen,hypercall)2310 DEFN_PRE_TEMPLATE(xen, hypercall)
2311 {
2312    XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
2313 
2314    /* Return number of arguments consumed */
2315    ARG8 = ent->nr_args;
2316 
2317    vg_assert(ent);
2318    vg_assert(ent->entry.before);
2319    (ent->entry.before)( tid, layout, arrghs, status, flags );
2320 
2321 }
2322 
DEFN_POST_TEMPLATE(xen,hypercall)2323 DEFN_POST_TEMPLATE(xen, hypercall)
2324 {
2325    XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
2326 
2327    /* Return number of arguments consumed */
2328    ARG8 = ent->nr_args;
2329 
2330    vg_assert(ent);
2331    if (ent->entry.after)
2332       (ent->entry.after)( tid, arrghs, status );
2333 }
2334 
2335 #endif // defined(ENABLE_XEN)
2336