• 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 	   break;
732    default:
733       bad_intf_version(tid, layout, arrghs, status, flags,
734                        "__HYPERVISOR_domctl", domctl->interface_version);
735       return;
736    }
737 
738 #define __PRE_XEN_DOMCTL_READ(_domctl, _union, _field)			\
739       PRE_MEM_READ("XEN_DOMCTL_" #_domctl " u." #_union "." #_field,	\
740                    (Addr)&domctl->u._union._field,			\
741                    sizeof(domctl->u._union._field))
742 #define PRE_XEN_DOMCTL_READ(_domctl, _field) \
743       __PRE_XEN_DOMCTL_READ(_domctl, _domctl, _field)
744 
745    switch (domctl->cmd) {
746    case VKI_XEN_DOMCTL_destroydomain:
747    case VKI_XEN_DOMCTL_pausedomain:
748    case VKI_XEN_DOMCTL_max_vcpus:
749    case VKI_XEN_DOMCTL_get_address_size:
750    case VKI_XEN_DOMCTL_gettscinfo:
751    case VKI_XEN_DOMCTL_getdomaininfo:
752    case VKI_XEN_DOMCTL_unpausedomain:
753    case VKI_XEN_DOMCTL_resumedomain:
754       /* No input fields. */
755       break;
756 
757    case VKI_XEN_DOMCTL_createdomain:
758       PRE_XEN_DOMCTL_READ(createdomain, ssidref);
759       PRE_XEN_DOMCTL_READ(createdomain, handle);
760       PRE_XEN_DOMCTL_READ(createdomain, flags);
761       break;
762 
763    case VKI_XEN_DOMCTL_gethvmcontext:
764        /* Xen unconditionally reads the 'buffer' pointer */
765        __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, buffer);
766        /* Xen only consumes 'size' if 'buffer' is non NULL. A NULL
767         * buffer is a request for the required size. */
768        if ( domctl->u.hvmcontext.buffer.p )
769            __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, size);
770        break;
771 
772    case VKI_XEN_DOMCTL_sethvmcontext:
773        __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, size);
774        __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, buffer);
775        PRE_MEM_READ("XEN_DOMCTL_sethvmcontext *buffer",
776                     (Addr)domctl->u.hvmcontext.buffer.p,
777                     domctl->u.hvmcontext.size);
778        break;
779 
780    case VKI_XEN_DOMCTL_gethvmcontext_partial:
781        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, type);
782        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, instance);
783        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, buffer);
784 
785        switch (domctl->u.hvmcontext_partial.type) {
786        case VKI_HVM_SAVE_CODE(CPU):
787            if ( domctl->u.hvmcontext_partial.buffer.p )
788                 PRE_MEM_WRITE("XEN_DOMCTL_gethvmcontext_partial *buffer",
789                    (Addr)domctl->u.hvmcontext_partial.buffer.p,
790                    VKI_HVM_SAVE_LENGTH(CPU));
791            break;
792        default:
793            bad_subop(tid, layout, arrghs, status, flags,
794                          "__HYPERVISOR_domctl_gethvmcontext_partial type",
795                          domctl->u.hvmcontext_partial.type);
796            break;
797        }
798        break;
799 
800    case VKI_XEN_DOMCTL_max_mem:
801       PRE_XEN_DOMCTL_READ(max_mem, max_memkb);
802       break;
803 
804    case VKI_XEN_DOMCTL_set_address_size:
805       __PRE_XEN_DOMCTL_READ(set_address_size, address_size, size);
806       break;
807 
808    case VKI_XEN_DOMCTL_test_assign_device:
809       __PRE_XEN_DOMCTL_READ(test_assign_device, assign_device, machine_sbdf);
810       break;
811    case VKI_XEN_DOMCTL_assign_device:
812       __PRE_XEN_DOMCTL_READ(assign_device, assign_device, machine_sbdf);
813       break;
814    case VKI_XEN_DOMCTL_deassign_device:
815       __PRE_XEN_DOMCTL_READ(deassign_device, assign_device, machine_sbdf);
816       break;
817 
818    case VKI_XEN_DOMCTL_settscinfo:
819       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.tsc_mode);
820       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.gtsc_khz);
821       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.incarnation);
822       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.elapsed_nsec);
823       break;
824 
825    case VKI_XEN_DOMCTL_irq_permission:
826       PRE_XEN_DOMCTL_READ(irq_permission, pirq);
827       PRE_XEN_DOMCTL_READ(irq_permission, allow_access);
828       break;
829 
830    case VKI_XEN_DOMCTL_iomem_permission:
831       PRE_XEN_DOMCTL_READ(iomem_permission, first_mfn);
832       PRE_XEN_DOMCTL_READ(iomem_permission, nr_mfns);
833       PRE_XEN_DOMCTL_READ(iomem_permission, allow_access);
834       break;
835 
836    case VKI_XEN_DOMCTL_ioport_permission:
837       PRE_XEN_DOMCTL_READ(ioport_permission, first_port);
838       PRE_XEN_DOMCTL_READ(ioport_permission, nr_ports);
839       PRE_XEN_DOMCTL_READ(ioport_permission, allow_access);
840       break;
841 
842    case VKI_XEN_DOMCTL_hypercall_init:
843       PRE_XEN_DOMCTL_READ(hypercall_init, gmfn);
844       break;
845 
846    case VKI_XEN_DOMCTL_settimeoffset:
847        PRE_XEN_DOMCTL_READ(settimeoffset, time_offset_seconds);
848        break;
849 
850    case VKI_XEN_DOMCTL_getvcpuinfo:
851       PRE_XEN_DOMCTL_READ(getvcpuinfo, vcpu);
852       break;
853 
854    case VKI_XEN_DOMCTL_scheduler_op:
855       PRE_XEN_DOMCTL_READ(scheduler_op, sched_id);
856       PRE_XEN_DOMCTL_READ(scheduler_op, cmd);
857       if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_putinfo ) {
858          switch(domctl->u.scheduler_op.sched_id) {
859          case VKI_XEN_SCHEDULER_SEDF:
860             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.period);
861             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.slice);
862             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.latency);
863             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.extratime);
864             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.weight);
865             break;
866          case VKI_XEN_SCHEDULER_CREDIT:
867             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.weight);
868             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.cap);
869             break;
870          case VKI_XEN_SCHEDULER_CREDIT2:
871             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit2.weight);
872             break;
873          case VKI_XEN_SCHEDULER_RTDS:
874             PRE_XEN_DOMCTL_READ(scheduler_op, u.rtds.period);
875             PRE_XEN_DOMCTL_READ(scheduler_op, u.rtds.budget);
876             break;
877          case VKI_XEN_SCHEDULER_ARINC653:
878             break;
879          }
880       }
881       break;
882 
883    case VKI_XEN_DOMCTL_getvcpuaffinity:
884       switch (domctl->interface_version) {
885       case 0x00000007:
886       case 0x00000008:
887       case 0x00000009:
888          __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity_00000009, vcpu);
889          __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity_00000009, cpumap.nr_bits);
890          break;
891       case 0x0000000a:
892          __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity_0000000a, vcpu);
893          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_HARD)
894             __PRE_XEN_DOMCTL_READ(
895                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_hard.nr_bits);
896          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_SOFT)
897             __PRE_XEN_DOMCTL_READ(
898                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_soft.nr_bits);
899          break;
900       }
901       break;
902 
903    case VKI_XEN_DOMCTL_setvcpuaffinity:
904       switch (domctl->interface_version) {
905       case 0x00000007:
906       case 0x00000008:
907       case 0x00000009:
908          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_00000009, vcpu);
909          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_00000009, cpumap.nr_bits);
910          PRE_MEM_READ("XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap.bitmap",
911                       (Addr)domctl->u.vcpuaffinity_00000009.cpumap.bitmap.p,
912                       domctl->u.vcpuaffinity_00000009.cpumap.nr_bits / 8);
913          break;
914       case 0x0000000a:
915          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_0000000a, vcpu);
916          __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity_0000000a, flags);
917          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_HARD) {
918             __PRE_XEN_DOMCTL_READ(
919                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_hard.nr_bits);
920             PRE_MEM_READ(
921                "XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap_hard.bitmap",
922                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_hard.bitmap.p,
923                domctl->u.vcpuaffinity_0000000a.cpumap_hard.nr_bits / 8);
924          }
925          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_SOFT) {
926             __PRE_XEN_DOMCTL_READ(
927                setvcpuaffinity, vcpuaffinity_0000000a, cpumap_soft.nr_bits);
928             PRE_MEM_READ(
929                "XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap_soft.bitmap",
930                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_soft.bitmap.p,
931                domctl->u.vcpuaffinity_0000000a.cpumap_soft.nr_bits / 8);
932          }
933       break;
934       }
935       break;
936 
937    case VKI_XEN_DOMCTL_getnodeaffinity:
938       __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
939       break;
940    case VKI_XEN_DOMCTL_setnodeaffinity:
941       __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
942       PRE_MEM_READ("XEN_DOMCTL_setnodeaffinity u.nodeaffinity.cpumap.bitmap",
943                    (Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
944                    domctl->u.nodeaffinity.nodemap.nr_bits / 8);
945       break;
946 
947    case VKI_XEN_DOMCTL_getvcpucontext:
948       __PRE_XEN_DOMCTL_READ(getvcpucontext, vcpucontext, vcpu);
949       break;
950 
951    case VKI_XEN_DOMCTL_setvcpucontext:
952       __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, vcpu);
953       __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, ctxt.p);
954       break;
955 
956    case VKI_XEN_DOMCTL_pin_mem_cacheattr:
957       PRE_XEN_DOMCTL_READ(pin_mem_cacheattr, start);
958       PRE_XEN_DOMCTL_READ(pin_mem_cacheattr, end);
959       PRE_XEN_DOMCTL_READ(pin_mem_cacheattr, type);
960       break;
961 
962    case VKI_XEN_DOMCTL_get_ext_vcpucontext:
963       switch (domctl->interface_version)
964       {
965       case 0x00000007:
966       case 0x00000008:
967          __PRE_XEN_DOMCTL_READ(get_ext_vcpucontext, ext_vcpucontext_00000008, vcpu);
968          break;
969 
970       case 0x00000009:
971          __PRE_XEN_DOMCTL_READ(get_ext_vcpucontext, ext_vcpucontext_00000009, vcpu);
972          break;
973 
974       default:
975          VG_(dmsg)("WARNING: VKI_XEN_DOMCTL_get_ext_vcpucontext  domctl version %#"
976                    PRIx32" not implemented\n", domctl->interface_version);
977          SET_STATUS_Failure(VKI_EINVAL);
978          break;
979       }
980       break;
981 
982    case VKI_XEN_DOMCTL_set_ext_vcpucontext:
983        switch (domctl->interface_version)
984        {
985        case 0x00000007:
986        case 0x00000008:
987            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008, vcpu);
988            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008, size);
989 #if defined(__i386__) || defined(__x86_64__)
990            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
991                                  syscall32_callback_eip);
992            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
993                                  sysenter_callback_eip);
994            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
995                                  syscall32_callback_cs);
996            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
997                                  sysenter_callback_cs);
998            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
999                                  syscall32_disables_events);
1000            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1001                                  sysenter_disables_events);
1002 
1003            if ( domctl->u.ext_vcpucontext_00000008.size >=
1004                 offsetof(struct vki_xen_domctl_ext_vcpucontext_00000008, mcg_cap) )
1005                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000008,
1006                                      mcg_cap);
1007 #endif
1008            break;
1009 
1010        case 0x00000009:
1011            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009, vcpu);
1012            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009, size);
1013 #if defined(__i386__) || defined(__x86_64__)
1014            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1015                                  syscall32_callback_eip);
1016            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1017                                  sysenter_callback_eip);
1018            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1019                                  syscall32_callback_cs);
1020            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1021                                  sysenter_callback_cs);
1022            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1023                                  syscall32_disables_events);
1024            __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1025                                  sysenter_disables_events);
1026 
1027            if ( domctl->u.ext_vcpucontext_00000009.size >=
1028                 offsetof(struct vki_xen_domctl_ext_vcpucontext_00000009, caps) )
1029            {
1030                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1031                                      caps);
1032                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1033                                      mci_ctl2_bank0);
1034                __PRE_XEN_DOMCTL_READ(set_ext_vcpucontext, ext_vcpucontext_00000009,
1035                                      mci_ctl2_bank1);
1036            }
1037 #endif
1038 	   break;
1039 
1040        default:
1041            VG_(dmsg)("WARNING: VKI_XEN_DOMCTL_set_ext_vcpucontext  domctl version %#"
1042                      PRIx32" not implemented\n", domctl->interface_version);
1043            SET_STATUS_Failure(VKI_EINVAL);
1044            break;
1045        }
1046        break;
1047 
1048    case VKI_XEN_DOMCTL_set_cpuid:
1049       PRE_MEM_READ("XEN_DOMCTL_set_cpuid u.cpuid",
1050                    (Addr)&domctl->u.cpuid, sizeof(domctl->u.cpuid));
1051       break;
1052 
1053    case VKI_XEN_DOMCTL_getpageframeinfo3:
1054        PRE_XEN_DOMCTL_READ(getpageframeinfo3, num);
1055        PRE_XEN_DOMCTL_READ(getpageframeinfo3, array.p);
1056        PRE_MEM_READ("XEN_DOMCTL_getpageframeinfo3 *u.getpageframeinfo3.array.p",
1057                     (Addr)domctl->u.getpageframeinfo3.array.p,
1058                     domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
1059        break;
1060 
1061    case VKI_XEN_DOMCTL_setvcpuextstate:
1062       __PRE_XEN_DOMCTL_READ(setvcpuextstate, vcpuextstate, vcpu);
1063       __PRE_XEN_DOMCTL_READ(setvcpuextstate, vcpuextstate, size);
1064       __PRE_XEN_DOMCTL_READ(setvcpuextstate, vcpuextstate, buffer);
1065       PRE_MEM_READ("XEN_DOMCTL_setvcpuextstate *u.vcpuextstate.buffer.p",
1066                    (Addr)domctl->u.vcpuextstate.buffer.p,
1067                    domctl->u.vcpuextstate.size);
1068       break;
1069 
1070    case VKI_XEN_DOMCTL_getvcpuextstate:
1071       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, vcpu);
1072       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, xfeature_mask);
1073       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, size);
1074       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, buffer);
1075       break;
1076 
1077    case VKI_XEN_DOMCTL_shadow_op:
1078        PRE_XEN_DOMCTL_READ(shadow_op, op);
1079 
1080        switch(domctl->u.shadow_op.op)
1081        {
1082        case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
1083        case VKI_XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION:
1084            /* No further inputs */
1085            break;
1086 
1087        case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE:
1088            PRE_XEN_DOMCTL_READ(shadow_op, mode);
1089            switch(domctl->u.shadow_op.mode)
1090            {
1091            case XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY:
1092                goto domctl_shadow_op_enable_logdirty;
1093 
1094 
1095            default:
1096                bad_subop(tid, layout, arrghs, status, flags,
1097                          "__HYPERVISOR_domctl shadowop mode",
1098                          domctl->u.shadow_op.mode);
1099                break;
1100            }
1101 
1102        case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:
1103        domctl_shadow_op_enable_logdirty:
1104            /* No further inputs */
1105            break;
1106 
1107        case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
1108        case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
1109            PRE_XEN_DOMCTL_READ(shadow_op, dirty_bitmap);
1110            PRE_XEN_DOMCTL_READ(shadow_op, pages);
1111            break;
1112 
1113        case VKI_XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION:
1114            PRE_XEN_DOMCTL_READ(shadow_op, mb);
1115            break;
1116 
1117        default:
1118            bad_subop(tid, layout, arrghs, status, flags,
1119                      "__HYPERVISOR_domctl shadow(10)",
1120                      domctl->u.shadow_op.op);
1121            break;
1122        }
1123        break;
1124 
1125    case VKI_XEN_DOMCTL_set_max_evtchn:
1126       PRE_XEN_DOMCTL_READ(set_max_evtchn, max_port);
1127       break;
1128 
1129    case VKI_XEN_DOMCTL_cacheflush:
1130       PRE_XEN_DOMCTL_READ(cacheflush, start_pfn);
1131       PRE_XEN_DOMCTL_READ(cacheflush, nr_pfns);
1132       break;
1133 
1134    case VKI_XEN_DOMCTL_set_access_required:
1135       PRE_XEN_DOMCTL_READ(access_required, access_required);
1136       break;
1137 
1138    case VKI_XEN_DOMCTL_mem_event_op:
1139       PRE_XEN_DOMCTL_READ(mem_event_op, op);
1140       PRE_XEN_DOMCTL_READ(mem_event_op, mode);
1141       break;
1142 
1143    case VKI_XEN_DOMCTL_debug_op:
1144       PRE_XEN_DOMCTL_READ(debug_op, op);
1145       PRE_XEN_DOMCTL_READ(debug_op, vcpu);
1146       break;
1147 
1148    case VKI_XEN_DOMCTL_get_vcpu_msrs:
1149       __PRE_XEN_DOMCTL_READ(get_vcpu_msrs, vcpu_msrs, vcpu);
1150       __PRE_XEN_DOMCTL_READ(get_vcpu_msrs, vcpu_msrs, msr_count);
1151       __PRE_XEN_DOMCTL_READ(get_vcpu_msrs, vcpu_msrs, msrs);
1152       break;
1153 
1154    case VKI_XEN_DOMCTL_set_vcpu_msrs:
1155       __PRE_XEN_DOMCTL_READ(set_vcpu_msrs, vcpu_msrs, vcpu);
1156       __PRE_XEN_DOMCTL_READ(set_vcpu_msrs, vcpu_msrs, msr_count);
1157       __PRE_XEN_DOMCTL_READ(set_vcpu_msrs, vcpu_msrs, msrs);
1158       PRE_MEM_READ("XEN_DOMCTL_set_vcpu_msrs *u.vcpu_msrs.msrs.p",
1159                    (Addr)domctl->u.vcpu_msrs.msrs.p,
1160                    sizeof(vki_xen_domctl_vcpu_msr_t) *
1161                    domctl->u.vcpu_msrs.msr_count);
1162       break;
1163 
1164    default:
1165       bad_subop(tid, layout, arrghs, status, flags,
1166                 "__HYPERVISOR_domctl", domctl->cmd);
1167       break;
1168    }
1169 #undef PRE_XEN_DOMCTL_READ
1170 #undef __PRE_XEN_DOMCTL_READ
1171 }
1172 
PRE(hvm_op)1173 PRE(hvm_op)
1174 {
1175    unsigned long op = ARG1;
1176    void *arg = (void *)(unsigned long)ARG2;
1177 
1178    PRINT("__HYPERVISOR_hvm_op ( %ld, %#lx )", SARG1, ARG2);
1179 
1180 #define __PRE_XEN_HVMOP_READ(_hvm_op, _type, _field)    \
1181    PRE_MEM_READ("XEN_HVMOP_" # _hvm_op " " #_field,     \
1182                 (Addr)&((_type*)arg)->_field,           \
1183                 sizeof(((_type*)arg)->_field))
1184 #define PRE_XEN_HVMOP_READ(_hvm_op, _field)                             \
1185    __PRE_XEN_HVMOP_READ(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
1186 
1187    switch (op) {
1188    case VKI_XEN_HVMOP_set_param:
1189       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, domid);
1190       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, index);
1191       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, value);
1192       break;
1193 
1194    case VKI_XEN_HVMOP_get_param:
1195       __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, domid);
1196       __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, index);
1197       break;
1198 
1199    case VKI_XEN_HVMOP_set_pci_intx_level:
1200       PRE_XEN_HVMOP_READ(set_pci_intx_level, domid);
1201       PRE_XEN_HVMOP_READ(set_pci_intx_level, domain);
1202       PRE_XEN_HVMOP_READ(set_pci_intx_level, bus);
1203       PRE_XEN_HVMOP_READ(set_pci_intx_level, device);
1204       PRE_XEN_HVMOP_READ(set_pci_intx_level, level);
1205       break;
1206 
1207    case VKI_XEN_HVMOP_set_isa_irq_level:
1208       PRE_XEN_HVMOP_READ(set_isa_irq_level, domid);
1209       PRE_XEN_HVMOP_READ(set_isa_irq_level, isa_irq);
1210       PRE_XEN_HVMOP_READ(set_isa_irq_level, level);
1211       break;
1212 
1213    case VKI_XEN_HVMOP_set_pci_link_route:
1214       PRE_XEN_HVMOP_READ(set_pci_link_route, domid);
1215       PRE_XEN_HVMOP_READ(set_pci_link_route, link);
1216       PRE_XEN_HVMOP_READ(set_pci_link_route, isa_irq);
1217       break;
1218 
1219    case VKI_XEN_HVMOP_track_dirty_vram: {
1220       vki_xen_hvm_track_dirty_vram_t *Arg =
1221          (vki_xen_hvm_track_dirty_vram_t*)ARG2;
1222       PRE_XEN_HVMOP_READ(track_dirty_vram, domid);
1223       PRE_XEN_HVMOP_READ(track_dirty_vram, nr);
1224       if ( Arg->nr ) {
1225          PRE_XEN_HVMOP_READ(track_dirty_vram, first_pfn);
1226          PRE_XEN_HVMOP_READ(track_dirty_vram, dirty_bitmap);
1227       }
1228       break;
1229    }
1230 
1231    case VKI_XEN_HVMOP_set_mem_type:
1232       PRE_XEN_HVMOP_READ(set_mem_type, domid);
1233       PRE_XEN_HVMOP_READ(set_mem_type, hvmmem_type);
1234       PRE_XEN_HVMOP_READ(set_mem_type, nr);
1235       PRE_XEN_HVMOP_READ(set_mem_type, first_pfn);
1236       break;
1237 
1238    case VKI_XEN_HVMOP_set_mem_access:
1239       PRE_XEN_HVMOP_READ(set_mem_access, domid);
1240       PRE_XEN_HVMOP_READ(set_mem_access, hvmmem_access);
1241       PRE_XEN_HVMOP_READ(set_mem_access, first_pfn);
1242       /* if default access */
1243       if ( ((vki_xen_hvm_set_mem_access_t*)arg)->first_pfn != ~0ULL)
1244          PRE_XEN_HVMOP_READ(set_mem_access, nr);
1245       break;
1246 
1247    case VKI_XEN_HVMOP_get_mem_access:
1248       PRE_XEN_HVMOP_READ(get_mem_access, domid);
1249       PRE_XEN_HVMOP_READ(get_mem_access, pfn);
1250 
1251       PRE_MEM_WRITE("XEN_HVMOP_get_mem_access *hvmmem_access",
1252                     (Addr)&(((vki_xen_hvm_get_mem_access_t*)arg)->hvmmem_access),
1253                     sizeof(vki_uint16_t));
1254       break;
1255 
1256    case VKI_XEN_HVMOP_inject_trap:
1257       PRE_XEN_HVMOP_READ(inject_trap, domid);
1258       PRE_XEN_HVMOP_READ(inject_trap, vcpuid);
1259       PRE_XEN_HVMOP_READ(inject_trap, vector);
1260       PRE_XEN_HVMOP_READ(inject_trap, type);
1261       PRE_XEN_HVMOP_READ(inject_trap, error_code);
1262       PRE_XEN_HVMOP_READ(inject_trap, insn_len);
1263       PRE_XEN_HVMOP_READ(inject_trap, cr2);
1264       break;
1265 
1266    default:
1267       bad_subop(tid, layout, arrghs, status, flags,
1268                 "__HYPERVISOR_hvm_op", op);
1269       break;
1270    }
1271 #undef __PRE_XEN_HVMOP_READ
1272 #undef PRE_XEN_HVMOP_READ
1273 }
1274 
PRE(tmem_op)1275 PRE(tmem_op)
1276 {
1277     struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
1278 
1279     PRINT("__HYPERVISOR_tmem_op ( %u )", tmem->cmd);
1280 
1281     /* Common part for xen_tmem_op:
1282      *    vki_uint32_t cmd;
1283      */
1284     PRE_MEM_READ("__HYPERVISOR_tmem_op cmd", ARG1, sizeof(vki_uint32_t));
1285 
1286 
1287 #define __PRE_XEN_TMEMOP_READ(_tmem, _union, _field)                    \
1288     PRE_MEM_READ("XEN_tmem_op_" #_tmem " u." #_union "." #_field,       \
1289                  (Addr)&tmem->u._union._field,                          \
1290                  sizeof(tmem->u._union._field))
1291 #define PRE_XEN_TMEMOP_READ(_tmem, _field)                              \
1292     __PRE_XEN_TMEMOP_READ(_tmem, _tmem, _field)
1293 
1294     switch(tmem->cmd) {
1295 
1296     case VKI_XEN_TMEM_control:
1297 
1298         /* Common part for control hypercall:
1299          *    vki_int32_t pool_id;
1300          *    vki_uint32_t subop;
1301          */
1302         PRE_MEM_READ("__HYPERVISOR_tmem_op pool_id",
1303                      (Addr)&tmem->pool_id, sizeof(tmem->pool_id));
1304         PRE_XEN_TMEMOP_READ(ctrl, subop);
1305 
1306         switch (tmem->u.ctrl.subop) {
1307 
1308         case VKI_XEN_TMEMC_save_begin:
1309             PRE_XEN_TMEMOP_READ(ctrl, cli_id);
1310             PRE_XEN_TMEMOP_READ(ctrl, arg1);
1311             PRE_XEN_TMEMOP_READ(ctrl, buf);
1312             break;
1313 
1314         default:
1315             bad_subop(tid, layout, arrghs, status, flags,
1316                       "__HYPERVISOR_tmem_op_control", tmem->u.ctrl.subop);
1317         }
1318 
1319         break;
1320 
1321     default:
1322         bad_subop(tid, layout, arrghs, status, flags,
1323                   "__HYPERVISOR_tmem_op", ARG1);
1324     }
1325 
1326 #undef PRE_XEN_TMEMOP_READ
1327 #undef __PRE_XEN_TMEMOP_READ
1328 }
1329 
POST(memory_op)1330 POST(memory_op)
1331 {
1332    switch (ARG1) {
1333    case VKI_XENMEM_maximum_ram_page:
1334    case VKI_XENMEM_set_memory_map:
1335    case VKI_XENMEM_decrease_reservation:
1336    case VKI_XENMEM_claim_pages:
1337    case VKI_XENMEM_maximum_gpfn:
1338    case VKI_XENMEM_remove_from_physmap:
1339    case VKI_XENMEM_access_op:
1340       /* No outputs */
1341       break;
1342    case VKI_XENMEM_increase_reservation:
1343    case VKI_XENMEM_populate_physmap: {
1344       struct xen_memory_reservation *memory_reservation =
1345          (struct xen_memory_reservation *)ARG2;
1346 
1347       POST_MEM_WRITE((Addr)memory_reservation->extent_start.p,
1348                      sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
1349       break;
1350    }
1351 
1352    case VKI_XENMEM_machphys_mfn_list:
1353    case VKI_XENMEM_machphys_compat_mfn_list: {
1354        struct vki_xen_machphys_mfn_list *arg =
1355            (struct vki_xen_machphys_mfn_list *)ARG2;
1356        POST_MEM_WRITE((Addr)&arg->nr_extents, sizeof(arg->nr_extents));
1357        POST_MEM_WRITE((Addr)arg->extent_start.p,
1358                       sizeof(vki_xen_pfn_t) * arg->nr_extents);
1359        break;
1360    }
1361 
1362    case VKI_XENMEM_memory_map:
1363    case VKI_XENMEM_machine_memory_map: {
1364       struct vki_xen_memory_map *arg =
1365          (struct vki_xen_memory_map *)ARG2;
1366       POST_MEM_WRITE(arg->nr_entries, sizeof(arg->nr_entries));
1367       POST_MEM_WRITE((Addr)arg->buffer.p,
1368                      arg->nr_entries * 20 /* size of an e820 entry */);
1369       break;
1370    }
1371 
1372    case VKI_XENMEM_add_to_physmap: {
1373        struct vki_xen_add_to_physmap *arg =
1374            (struct vki_xen_add_to_physmap *)ARG2;
1375        if (arg->space == VKI_XENMAPSPACE_gmfn_range)
1376            POST_MEM_WRITE(ARG2, sizeof(*arg));
1377    }
1378 
1379    case VKI_XENMEM_get_sharing_freed_pages:
1380    case VKI_XENMEM_get_sharing_shared_pages:
1381        /* No outputs */
1382        break;
1383    }
1384 }
1385 
POST(mmuext_op)1386 POST(mmuext_op)
1387 {
1388    unsigned int *pdone = (unsigned int *)ARG3;
1389    /* simplistic */
1390    POST_MEM_WRITE((Addr)pdone, sizeof(*pdone));
1391 }
1392 
POST(xsm_op)1393 POST(xsm_op)
1394 {
1395    /* XXX assuming flask, only actual XSM right now */
1396    struct vki_xen_flask_op *op = (struct vki_xen_flask_op *)ARG1;
1397 
1398    switch (op->interface_version) {
1399    case 0x00000001:
1400       break;
1401    default:
1402       return;
1403    }
1404 
1405 #define POST_XEN_XSM_OP_WRITE(_xsm_op, _union, _field)        \
1406       POST_MEM_WRITE((Addr)&op->u._union._field,              \
1407                      sizeof(op->u._union._field))
1408 
1409    switch (op->cmd) {
1410    case VKI_FLASK_SID_TO_CONTEXT:
1411       POST_XEN_XSM_OP_WRITE(SID_TO_CONTEXT, sid_context, size);
1412       POST_MEM_WRITE((Addr)op->u.sid_context.context.p,
1413                      op->u.sid_context.size);
1414    }
1415 }
1416 
post_evtchn_op(ThreadId tid,__vki_u32 cmd,void * arg,int compat)1417 static void post_evtchn_op(ThreadId tid, __vki_u32 cmd, void *arg, int compat)
1418 {
1419    switch (cmd) {
1420    case VKI_XEN_EVTCHNOP_alloc_unbound: {
1421       struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg;
1422       POST_MEM_WRITE((Addr)&alloc_unbound->port, sizeof(alloc_unbound->port));
1423       break;
1424    }
1425    }
1426 }
1427 
POST(sched_op)1428 POST(sched_op)
1429 {
1430    switch (ARG1) {
1431    case VKI_XEN_SCHEDOP_remote_shutdown:
1432       /* No outputs */
1433       break;
1434    }
1435 }
1436 
POST(evtchn_op)1437 POST(evtchn_op)
1438 {
1439    post_evtchn_op(tid, ARG1, (void *)ARG2, 0);
1440 }
1441 
POST(evtchn_op_compat)1442 POST(evtchn_op_compat)
1443 {
1444    struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1;
1445    post_evtchn_op(tid, evtchn->cmd, &evtchn->u, 1);
1446 }
1447 
POST(physdev_op)1448 POST(physdev_op)
1449 {
1450    int cmd = ARG1;
1451 
1452 #define POST_XEN_PHYSDEVOP_WRITE(_op, _field)                   \
1453    POST_MEM_WRITE((Addr)&arg->_field, sizeof(arg->_field))
1454 
1455    switch (cmd) {
1456    case VKI_XEN_PHYSDEVOP_unmap_pirq:
1457       /* No outputs */
1458       break;
1459 
1460    case VKI_XEN_PHYSDEVOP_map_pirq: {
1461       struct vki_xen_physdev_map_pirq *arg =
1462          (struct vki_xen_physdev_map_pirq *)ARG2;
1463       if (arg->type == VKI_XEN_MAP_PIRQ_TYPE_MULTI_MSI)
1464          POST_XEN_PHYSDEVOP_WRITE("map_pirq", entry_nr);
1465       POST_XEN_PHYSDEVOP_WRITE("map_pirq", pirq);
1466       break;
1467    }
1468 #undef POST_XEN_PHYSDEVOP_WRITE
1469 
1470    default:
1471       break;
1472    }
1473 }
1474 
POST(xen_version)1475 POST(xen_version)
1476 {
1477    switch (ARG1) {
1478    case VKI_XENVER_version:
1479       /* No outputs */
1480       break;
1481    case VKI_XENVER_extraversion:
1482       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_extraversion_t));
1483       break;
1484    case VKI_XENVER_compile_info:
1485       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_compile_info));
1486       break;
1487    case VKI_XENVER_capabilities:
1488       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_capabilities_info_t));
1489       break;
1490    case VKI_XENVER_changeset:
1491       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_changeset_info_t));
1492       break;
1493    case VKI_XENVER_platform_parameters:
1494       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_platform_parameters));
1495       break;
1496    case VKI_XENVER_get_features:
1497       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_feature_info));
1498       break;
1499    case VKI_XENVER_pagesize:
1500       /* No outputs */
1501       break;
1502    case VKI_XENVER_guest_handle:
1503       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_domain_handle_t));
1504       break;
1505    case VKI_XENVER_commandline:
1506       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_commandline_t));
1507       break;
1508    }
1509 }
1510 
POST(grant_table_op)1511 POST(grant_table_op)
1512 {
1513    switch (ARG1) {
1514    case VKI_XEN_GNTTABOP_setup_table: {
1515       struct vki_xen_gnttab_setup_table *gst =
1516 	      (struct vki_xen_gnttab_setup_table*)ARG2;
1517       PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
1518                     (Addr)&gst->status, sizeof(gst->status));
1519       PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
1520                     (Addr)gst->frame_list.p,
1521                     sizeof(*gst->frame_list.p) & gst->nr_frames);
1522       break;
1523    }
1524    }
1525 }
1526 
POST(sysctl)1527 POST(sysctl)
1528 {
1529    struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1;
1530 
1531    switch (sysctl->interface_version)
1532    {
1533    case 0x00000008:
1534    case 0x00000009:
1535    case 0x0000000a:
1536    case 0x0000000b:
1537 	   break;
1538    default:
1539       return;
1540    }
1541 
1542 #define __POST_XEN_SYSCTL_WRITE(_sysctl, _union, _field)        \
1543       POST_MEM_WRITE((Addr)&sysctl->u._union._field,            \
1544                      sizeof(sysctl->u._union._field))
1545 #define POST_XEN_SYSCTL_WRITE(_sysctl, _field) \
1546       __POST_XEN_SYSCTL_WRITE(_sysctl, _sysctl, _field)
1547 
1548    switch (sysctl->cmd) {
1549    case VKI_XEN_SYSCTL_readconsole:
1550        POST_MEM_WRITE((Addr)sysctl->u.readconsole.buffer.p,
1551                       sysctl->u.readconsole.count * sizeof(char));
1552        break;
1553 
1554    case VKI_XEN_SYSCTL_getdomaininfolist:
1555       switch (sysctl->interface_version)
1556       {
1557       case 0x00000008:
1558 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000008, num_domains);
1559 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000008.buffer.p,
1560 			sizeof(*sysctl->u.getdomaininfolist_00000008.buffer.p)
1561 			* sysctl->u.getdomaininfolist_00000008.num_domains);
1562 	 break;
1563       case 0x00000009:
1564 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000009, num_domains);
1565 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000009.buffer.p,
1566 			sizeof(*sysctl->u.getdomaininfolist_00000009.buffer.p)
1567 			* sysctl->u.getdomaininfolist_00000009.num_domains);
1568 	 break;
1569       case 0x0000000a:
1570       case 0x0000000b:
1571 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_0000000a, num_domains);
1572 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_0000000a.buffer.p,
1573 			sizeof(*sysctl->u.getdomaininfolist_0000000a.buffer.p)
1574 			* sysctl->u.getdomaininfolist_0000000a.num_domains);
1575 	 break;
1576       }
1577       break;
1578 
1579    case VKI_XEN_SYSCTL_sched_id:
1580        POST_XEN_SYSCTL_WRITE(sched_id, sched_id);
1581        break;
1582 
1583    case VKI_XEN_SYSCTL_cpupool_op:
1584       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE ||
1585           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO)
1586          POST_XEN_SYSCTL_WRITE(cpupool_op, cpupool_id);
1587       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO) {
1588          POST_XEN_SYSCTL_WRITE(cpupool_op, sched_id);
1589          POST_XEN_SYSCTL_WRITE(cpupool_op, n_dom);
1590       }
1591       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO ||
1592           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_FREEINFO)
1593          POST_XEN_SYSCTL_WRITE(cpupool_op, cpumap);
1594       break;
1595 
1596    case VKI_XEN_SYSCTL_physinfo:
1597       switch (sysctl->interface_version)
1598       {
1599       case 0x00000008:
1600       case 0x00000009: /* Unchanged from version 8 */
1601          POST_XEN_SYSCTL_WRITE(physinfo_00000008, threads_per_core);
1602          POST_XEN_SYSCTL_WRITE(physinfo_00000008, cores_per_socket);
1603          POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_cpus);
1604          POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_cpu_id);
1605          POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_nodes);
1606          POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_node_id);
1607          POST_XEN_SYSCTL_WRITE(physinfo_00000008, cpu_khz);
1608          POST_XEN_SYSCTL_WRITE(physinfo_00000008, total_pages);
1609          POST_XEN_SYSCTL_WRITE(physinfo_00000008, free_pages);
1610          POST_XEN_SYSCTL_WRITE(physinfo_00000008, scrub_pages);
1611          POST_XEN_SYSCTL_WRITE(physinfo_00000008, hw_cap[8]);
1612          POST_XEN_SYSCTL_WRITE(physinfo_00000008, capabilities);
1613          break;
1614       case 0x0000000a:
1615       case 0x0000000b:
1616          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, threads_per_core);
1617          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cores_per_socket);
1618          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_cpus);
1619          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_cpu_id);
1620          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_nodes);
1621          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_node_id);
1622          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cpu_khz);
1623          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, total_pages);
1624          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, free_pages);
1625          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, scrub_pages);
1626          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, outstanding_pages);
1627          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, hw_cap[8]);
1628          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, capabilities);
1629          break;
1630       }
1631       break;
1632 
1633    case VKI_XEN_SYSCTL_topologyinfo:
1634       POST_XEN_SYSCTL_WRITE(topologyinfo, max_cpu_index);
1635       if (sysctl->u.topologyinfo.cpu_to_core.p)
1636          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_core.p,
1637                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
1638       if (sysctl->u.topologyinfo.cpu_to_socket.p)
1639          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_socket.p,
1640                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
1641       if (sysctl->u.topologyinfo.cpu_to_node.p)
1642          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_node.p,
1643                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
1644       break;
1645 
1646    case VKI_XEN_SYSCTL_numainfo:
1647       POST_XEN_SYSCTL_WRITE(numainfo, max_node_index);
1648       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memsize.p,
1649                      sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
1650       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memfree.p,
1651                      sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
1652       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_node_distance.p,
1653                      sizeof(uint32_t) * sysctl->u.numainfo.max_node_index);
1654       break;
1655 
1656    /* No outputs */
1657    case VKI_XEN_SYSCTL_debug_keys:
1658        break;
1659    }
1660 #undef POST_XEN_SYSCTL_WRITE
1661 #undef __POST_XEN_SYSCTL_WRITE
1662 }
1663 
POST(domctl)1664 POST(domctl){
1665    struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1;
1666 
1667    switch (domctl->interface_version) {
1668    case 0x00000007:
1669    case 0x00000008:
1670    case 0x00000009:
1671    case 0x0000000a:
1672 	   break;
1673    default:
1674 	   return;
1675    }
1676 
1677 #define __POST_XEN_DOMCTL_WRITE(_domctl, _union, _field)        \
1678    POST_MEM_WRITE((Addr)&domctl->u._union._field,               \
1679                   sizeof(domctl->u._union._field));
1680 #define POST_XEN_DOMCTL_WRITE(_domctl, _field)          \
1681    __POST_XEN_DOMCTL_WRITE(_domctl, _domctl, _field)
1682 
1683    switch (domctl->cmd) {
1684    case VKI_XEN_DOMCTL_createdomain:
1685    case VKI_XEN_DOMCTL_destroydomain:
1686    case VKI_XEN_DOMCTL_pausedomain:
1687    case VKI_XEN_DOMCTL_max_mem:
1688    case VKI_XEN_DOMCTL_setvcpuextstate:
1689    case VKI_XEN_DOMCTL_set_address_size:
1690    case VKI_XEN_DOMCTL_test_assign_device:
1691    case VKI_XEN_DOMCTL_assign_device:
1692    case VKI_XEN_DOMCTL_deassign_device:
1693    case VKI_XEN_DOMCTL_settscinfo:
1694    case VKI_XEN_DOMCTL_irq_permission:
1695    case VKI_XEN_DOMCTL_iomem_permission:
1696    case VKI_XEN_DOMCTL_ioport_permission:
1697    case VKI_XEN_DOMCTL_hypercall_init:
1698    case VKI_XEN_DOMCTL_setvcpucontext:
1699    case VKI_XEN_DOMCTL_pin_mem_cacheattr:
1700    case VKI_XEN_DOMCTL_set_ext_vcpucontext:
1701    case VKI_XEN_DOMCTL_setnodeaffinity:
1702    case VKI_XEN_DOMCTL_set_cpuid:
1703    case VKI_XEN_DOMCTL_unpausedomain:
1704    case VKI_XEN_DOMCTL_sethvmcontext:
1705    case VKI_XEN_DOMCTL_debug_op:
1706    case VKI_XEN_DOMCTL_set_max_evtchn:
1707    case VKI_XEN_DOMCTL_cacheflush:
1708    case VKI_XEN_DOMCTL_resumedomain:
1709    case VKI_XEN_DOMCTL_set_vcpu_msrs:
1710    case VKI_XEN_DOMCTL_set_access_required:
1711       /* No output fields */
1712       break;
1713 
1714    case VKI_XEN_DOMCTL_max_vcpus:
1715       POST_XEN_DOMCTL_WRITE(max_vcpus, max);
1716       break;
1717 
1718    case VKI_XEN_DOMCTL_get_address_size:
1719       __POST_XEN_DOMCTL_WRITE(get_address_size, address_size, size);
1720       break;
1721 
1722    case VKI_XEN_DOMCTL_gettscinfo:
1723       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.tsc_mode);
1724       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.gtsc_khz);
1725       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.incarnation);
1726       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.elapsed_nsec);
1727       break;
1728 
1729    case VKI_XEN_DOMCTL_getvcpuinfo:
1730       POST_XEN_DOMCTL_WRITE(getvcpuinfo, online);
1731       POST_XEN_DOMCTL_WRITE(getvcpuinfo, blocked);
1732       POST_XEN_DOMCTL_WRITE(getvcpuinfo, running);
1733       POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu_time);
1734       POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu);
1735       break;
1736 
1737    case VKI_XEN_DOMCTL_gethvmcontext:
1738        /* Xen unconditionally writes size... */
1739        __POST_XEN_DOMCTL_WRITE(gethvmcontext, hvmcontext, size);
1740        /* ...but only writes to the buffer if it was non NULL */
1741        if ( domctl->u.hvmcontext.buffer.p )
1742            POST_MEM_WRITE((Addr)domctl->u.hvmcontext.buffer.p,
1743                           sizeof(*domctl->u.hvmcontext.buffer.p)
1744                           * domctl->u.hvmcontext.size);
1745        break;
1746 
1747    case VKI_XEN_DOMCTL_gethvmcontext_partial:
1748        switch (domctl->u.hvmcontext_partial.type) {
1749        case VKI_HVM_SAVE_CODE(CPU):
1750            if ( domctl->u.hvmcontext_partial.buffer.p )
1751                 POST_MEM_WRITE((Addr)domctl->u.hvmcontext_partial.buffer.p,
1752                    VKI_HVM_SAVE_LENGTH(CPU));
1753            break;
1754        }
1755        break;
1756 
1757    case VKI_XEN_DOMCTL_scheduler_op:
1758       if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_getinfo ) {
1759          switch(domctl->u.scheduler_op.sched_id) {
1760          case VKI_XEN_SCHEDULER_SEDF:
1761             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.period);
1762             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.slice);
1763             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.latency);
1764             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.extratime);
1765             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.weight);
1766             break;
1767          case VKI_XEN_SCHEDULER_CREDIT:
1768             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.weight);
1769             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.cap);
1770             break;
1771          case VKI_XEN_SCHEDULER_CREDIT2:
1772             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit2.weight);
1773             break;
1774          case VKI_XEN_SCHEDULER_ARINC653:
1775             break;
1776          case VKI_XEN_SCHEDULER_RTDS:
1777             POST_XEN_DOMCTL_WRITE(scheduler_op, u.rtds.period);
1778             POST_XEN_DOMCTL_WRITE(scheduler_op, u.rtds.budget);
1779             break;
1780          }
1781       }
1782       break;
1783 
1784    case VKI_XEN_DOMCTL_getvcpuaffinity:
1785    case VKI_XEN_DOMCTL_setvcpuaffinity: /* Writes back actual result */
1786       switch (domctl->interface_version) {
1787       case 0x00000007:
1788       case 0x00000008:
1789       case 0x00000009:
1790          POST_MEM_WRITE((Addr)domctl->u.vcpuaffinity_00000009.cpumap.bitmap.p,
1791                         domctl->u.vcpuaffinity_00000009.cpumap.nr_bits / 8);
1792          break;
1793       case 0x0000000a:
1794          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_HARD)
1795             POST_MEM_WRITE(
1796                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_hard.bitmap.p,
1797                domctl->u.vcpuaffinity_0000000a.cpumap_hard.nr_bits / 8);
1798          if (domctl->u.vcpuaffinity_0000000a.flags & VKI_XEN_VCPUAFFINITY_SOFT)
1799             POST_MEM_WRITE(
1800                (Addr)domctl->u.vcpuaffinity_0000000a.cpumap_soft.bitmap.p,
1801                domctl->u.vcpuaffinity_0000000a.cpumap_soft.nr_bits / 8);
1802       }
1803       break;
1804 
1805    case VKI_XEN_DOMCTL_getnodeaffinity:
1806       POST_MEM_WRITE((Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
1807                      domctl->u.nodeaffinity.nodemap.nr_bits / 8);
1808       break;
1809 
1810    case VKI_XEN_DOMCTL_getdomaininfo:
1811       switch (domctl->interface_version) {
1812       case 0x00000007:
1813 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, domain);
1814 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, flags);
1815 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, tot_pages);
1816 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_pages);
1817 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shr_pages);
1818 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shared_info_frame);
1819 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpu_time);
1820 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, nr_online_vcpus);
1821 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_vcpu_id);
1822 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, ssidref);
1823 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, handle);
1824 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpupool);
1825       break;
1826       case 0x00000008:
1827 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, domain);
1828 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, flags);
1829 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, tot_pages);
1830 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_pages);
1831 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shr_pages);
1832 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, paged_pages);
1833 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shared_info_frame);
1834 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpu_time);
1835 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, nr_online_vcpus);
1836 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_vcpu_id);
1837 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, ssidref);
1838 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, handle);
1839 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpupool);
1840       break;
1841       case 0x00000009:
1842       case 0x0000000a:
1843 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, domain);
1844 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, flags);
1845 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, tot_pages);
1846 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_pages);
1847 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, outstanding_pages);
1848 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shr_pages);
1849 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, paged_pages);
1850 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shared_info_frame);
1851 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpu_time);
1852 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, nr_online_vcpus);
1853 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_vcpu_id);
1854 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, ssidref);
1855 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, handle);
1856 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpupool);
1857       break;
1858       }
1859       break;
1860    case VKI_XEN_DOMCTL_getvcpucontext:
1861       __POST_XEN_DOMCTL_WRITE(getvcpucontext, vcpucontext, ctxt.p);
1862       break;
1863 
1864    case VKI_XEN_DOMCTL_getpageframeinfo3:
1865        POST_MEM_WRITE((Addr)domctl->u.getpageframeinfo3.array.p,
1866                       domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
1867        break;
1868 
1869    case VKI_XEN_DOMCTL_get_ext_vcpucontext:
1870        switch (domctl->interface_version)
1871        {
1872        case 0x00000007:
1873        case 0x00000008:
1874            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008, size);
1875 #if defined(__i386__) || defined(__x86_64__)
1876            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
1877                                    syscall32_callback_eip);
1878            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
1879                                    sysenter_callback_eip);
1880            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
1881                                    syscall32_callback_cs);
1882            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
1883                                    sysenter_callback_cs);
1884            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
1885                                    syscall32_disables_events);
1886            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
1887                                    sysenter_disables_events);
1888 
1889            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000008,
1890                                    mcg_cap);
1891 #endif
1892            break;
1893 
1894        case 0x00000009:
1895            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009, size);
1896 #if defined(__i386__) || defined(__x86_64__)
1897            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1898                                    syscall32_callback_eip);
1899            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1900                                    sysenter_callback_eip);
1901            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1902                                    syscall32_callback_cs);
1903            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1904                                    sysenter_callback_cs);
1905            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1906                                    syscall32_disables_events);
1907            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1908                                    sysenter_disables_events);
1909 
1910            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1911                                    caps);
1912            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1913                                    mci_ctl2_bank0);
1914            __POST_XEN_DOMCTL_WRITE(get_ext_vcpucontext, ext_vcpucontext_00000009,
1915                                    mci_ctl2_bank1);
1916 #endif
1917 	   break;
1918        }
1919        break;
1920 
1921 
1922    case VKI_XEN_DOMCTL_getvcpuextstate:
1923       if (domctl->u.vcpuextstate.buffer.p)
1924          POST_MEM_WRITE((Addr)domctl->u.vcpuextstate.buffer.p,
1925                         domctl->u.vcpuextstate.size);
1926       break;
1927 
1928    case VKI_XEN_DOMCTL_shadow_op:
1929        switch(domctl->u.shadow_op.op)
1930        {
1931        case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
1932        case VKI_XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION:
1933            /* No outputs */
1934            break;
1935 
1936        case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
1937        case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
1938            POST_XEN_DOMCTL_WRITE(shadow_op, pages);
1939            POST_XEN_DOMCTL_WRITE(shadow_op, stats.fault_count);
1940            POST_XEN_DOMCTL_WRITE(shadow_op, stats.dirty_count);
1941            if(domctl->u.shadow_op.dirty_bitmap.p)
1942                POST_MEM_WRITE((Addr)domctl->u.shadow_op.dirty_bitmap.p,
1943                               domctl->u.shadow_op.pages * sizeof(vki_uint8_t));
1944            break;
1945 
1946        case VKI_XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION:
1947            POST_XEN_DOMCTL_WRITE(shadow_op, mb);
1948            break;
1949 
1950        default:
1951            break;
1952        }
1953        break;
1954    case VKI_XEN_DOMCTL_get_vcpu_msrs:
1955       if (domctl->u.vcpu_msrs.msrs.p)
1956          POST_MEM_WRITE((Addr)domctl->u.vcpu_msrs.msrs.p,
1957                         sizeof(vki_xen_domctl_vcpu_msr_t) *
1958                         domctl->u.vcpu_msrs.msr_count);
1959       break;
1960 
1961    case VKI_XEN_DOMCTL_mem_event_op:
1962        POST_XEN_DOMCTL_WRITE(mem_event_op, port);
1963 
1964        break;
1965    }
1966 #undef POST_XEN_DOMCTL_WRITE
1967 #undef __POST_XEN_DOMCTL_WRITE
1968 }
1969 
POST(hvm_op)1970 POST(hvm_op)
1971 {
1972    unsigned long op = ARG1;
1973    void *arg = (void *)(unsigned long)ARG2;
1974 
1975 #define __POST_XEN_HVMOP_WRITE(_hvm_op, _type, _field)  \
1976       POST_MEM_WRITE((Addr)&((_type*)arg)->_field,      \
1977                      sizeof(((_type*)arg)->_field))
1978 #define POST_XEN_HVMOP_WRITE(_hvm_op, _field) \
1979       __POST_XEN_HVMOP_WRITE(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
1980 
1981    switch (op) {
1982    case VKI_XEN_HVMOP_set_param:
1983    case VKI_XEN_HVMOP_set_pci_intx_level:
1984    case VKI_XEN_HVMOP_set_isa_irq_level:
1985    case VKI_XEN_HVMOP_set_pci_link_route:
1986    case VKI_XEN_HVMOP_set_mem_type:
1987    case VKI_XEN_HVMOP_set_mem_access:
1988    case VKI_XEN_HVMOP_inject_trap:
1989       /* No output paramters */
1990       break;
1991 
1992    case VKI_XEN_HVMOP_get_param:
1993       __POST_XEN_HVMOP_WRITE(get_param, struct vki_xen_hvm_param, value);
1994       break;
1995 
1996    case VKI_XEN_HVMOP_get_mem_access:
1997       POST_XEN_HVMOP_WRITE(get_mem_access, hvmmem_access);
1998       break;
1999    }
2000 #undef __POST_XEN_HVMOP_WRITE
2001 #undef POST_XEN_HVMOP_WRITE
2002 }
2003 
POST(tmem_op)2004 POST(tmem_op)
2005 {
2006     struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
2007 
2008     switch(tmem->cmd) {
2009 
2010     case VKI_XEN_TMEM_control:
2011 
2012         switch(tmem->u.ctrl.subop) {
2013             /* No outputs */
2014             case VKI_XEN_TMEMC_save_begin:
2015                 break;
2016         }
2017 
2018         break;
2019     }
2020 }
2021 
2022 typedef
2023    struct {
2024       SyscallTableEntry entry;
2025       int nr_args;
2026    }
2027    XenHypercallTableEntry;
2028 
2029 #define HYPX_(const, name, nr_args) \
2030    [const] = { { vgSysWrap_xen_##name##_before, NULL }, nr_args }
2031 #define HYPXY(const, name, nr_args)                     \
2032    [const] = { { vgSysWrap_xen_##name##_before,         \
2033                  vgSysWrap_xen_##name##_after },        \
2034                nr_args }
2035 
2036 static XenHypercallTableEntry hypercall_table[] = {
2037    //    __VKI_XEN_set_trap_table                                  // 0
2038    //    __VKI_XEN_mmu_update                                      // 1
2039    //    __VKI_XEN_set_gdt                                         // 2
2040    //    __VKI_XEN_stack_switch                                    // 3
2041    //    __VKI_XEN_set_callbacks                                   // 4
2042 
2043    //    __VKI_XEN_fpu_taskswitch                                  // 5
2044    //    __VKI_XEN_sched_op_compat                                 // 6
2045    //    __VKI_XEN_platform_op                                     // 7
2046    //    __VKI_XEN_set_debugreg                                    // 8
2047    //    __VKI_XEN_get_debugreg                                    // 9
2048 
2049    //    __VKI_XEN_update_descriptor                               // 10
2050    //                                                                 // 11
2051    HYPXY(__VKI_XEN_memory_op,               memory_op,         2), // 12
2052    //    __VKI_XEN_multicall                                       // 13
2053    //    __VKI_XEN_update_va_mapping                               // 14
2054 
2055    //    __VKI_XEN_set_timer_op                                    // 15
2056    HYPXY(__VKI_XEN_event_channel_op_compat, evtchn_op_compat,  1), // 16
2057    HYPXY(__VKI_XEN_xen_version,             xen_version,       2), // 17
2058    //    __VKI_XEN_console_io                                      // 18
2059    //    __VKI_XEN_physdev_op_compat                               // 19
2060 
2061    HYPXY(__VKI_XEN_grant_table_op,          grant_table_op,    3), // 20
2062    //    __VKI_XEN_vm_assist                                       // 21
2063    //    __VKI_XEN_update_va_mapping_otherdomain                   // 22
2064    //    __VKI_XEN_iret,                    iret                   // 23
2065    //    __VKI_XEN_vcpu_op,                 vcpu_op                // 24
2066 
2067    //    __VKI_XEN_set_segment_base                                // 25
2068    HYPXY(__VKI_XEN_mmuext_op,               mmuext_op,         2), // 26
2069    HYPXY(__VKI_XEN_xsm_op,                  xsm_op,            1), // 27
2070    //    __VKI_XEN_nmi_op                                          // 28
2071    HYPXY(__VKI_XEN_sched_op,                sched_op,          2), // 29
2072 
2073    //    __VKI_XEN_callback_op                                     // 30
2074    //    __VKI_XEN_xenoprof_op                                     // 31
2075    HYPXY(__VKI_XEN_event_channel_op,        evtchn_op,         2), // 32
2076    HYPXY(__VKI_XEN_physdev_op,              physdev_op,        2), // 33
2077    HYPXY(__VKI_XEN_hvm_op,                  hvm_op,            2), // 34
2078 
2079    HYPXY(__VKI_XEN_sysctl,                  sysctl,            1), // 35
2080    HYPXY(__VKI_XEN_domctl,                  domctl,            1), // 36
2081    //    __VKI_XEN_kexec_op                                        // 37
2082    HYPXY(__VKI_XEN_tmem_op,                 tmem_op,           1), // 38
2083 };
2084 
bad_before(ThreadId tid,SyscallArgLayout * layout,SyscallArgs * args,SyscallStatus * status,UWord * flags)2085 static void bad_before ( ThreadId              tid,
2086                          SyscallArgLayout*     layout,
2087                          /*MOD*/SyscallArgs*   args,
2088                          /*OUT*/SyscallStatus* status,
2089                          /*OUT*/UWord*         flags )
2090 {
2091    VG_(dmsg)("WARNING: unhandled hypercall: %s\n",
2092       VG_SYSNUM_STRING(args->sysno));
2093    if (VG_(clo_verbosity) > 1) {
2094       VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
2095    }
2096    VG_(dmsg)("You may be able to write your own handler.\n");
2097    VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
2098    VG_(dmsg)("Nevertheless we consider this a bug.  Please report\n");
2099    VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
2100    VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
2101 
2102    SET_STATUS_Failure(VKI_ENOSYS);
2103 }
2104 
2105 static XenHypercallTableEntry bad_hyper =
2106 { { bad_before, NULL }, 0 };
2107 
ML_(get_xen_hypercall_entry)2108 static XenHypercallTableEntry* ML_(get_xen_hypercall_entry) ( UInt sysno )
2109 {
2110    XenHypercallTableEntry *ret = &bad_hyper;
2111 
2112    const UInt hypercall_table_size
2113       = sizeof(hypercall_table) / sizeof(hypercall_table[0]);
2114 
2115    /* Is it in the contiguous initial section of the table? */
2116    if (sysno < hypercall_table_size) {
2117       XenHypercallTableEntry* ent = &hypercall_table[sysno];
2118       if (ent->entry.before != NULL)
2119          ret = ent;
2120    }
2121 
2122    /* Can't find a wrapper */
2123    return ret;
2124 }
2125 
DEFN_PRE_TEMPLATE(xen,hypercall)2126 DEFN_PRE_TEMPLATE(xen, hypercall)
2127 {
2128    XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
2129 
2130    /* Return number of arguments consumed */
2131    ARG8 = ent->nr_args;
2132 
2133    vg_assert(ent);
2134    vg_assert(ent->entry.before);
2135    (ent->entry.before)( tid, layout, arrghs, status, flags );
2136 
2137 }
2138 
DEFN_POST_TEMPLATE(xen,hypercall)2139 DEFN_POST_TEMPLATE(xen, hypercall)
2140 {
2141    XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
2142 
2143    /* Return number of arguments consumed */
2144    ARG8 = ent->nr_args;
2145 
2146    vg_assert(ent);
2147    if (ent->entry.after)
2148       (ent->entry.after)( tid, arrghs, status );
2149 }
2150 
2151 #endif // defined(ENABLE_XEN)
2152