Home | History | Annotate | Download | only in m_syswrap
      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 (at) 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 
     68 static void bad_subop ( ThreadId              tid,
     69                         SyscallArgLayout*     layout,
     70                         /*MOD*/SyscallArgs*   args,
     71                         /*OUT*/SyscallStatus* status,
     72                         /*OUT*/UWord*         flags,
     73                         const HChar*           hypercall,
     74                         UWord                 subop)
     75 {
     76    VG_(dmsg)("WARNING: unhandled %s subop: %ld\n",
     77              hypercall, subop);
     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 
     90 PRE(memory_op)
     91 {
     92    PRINT("__HYPERVISOR_memory_op ( %ld, %lx )", ARG1, ARG2);
     93 
     94    switch (ARG1) {
     95 
     96    case VKI_XENMEM_maximum_ram_page:
     97        /* No inputs */
     98        break;
     99 
    100    case VKI_XENMEM_maximum_gpfn:
    101        PRE_MEM_READ("XENMEM_maximum_gpfn domid",
    102                     (Addr)ARG2, sizeof(vki_xen_domid_t));
    103        break;
    104 
    105    case VKI_XENMEM_machphys_mfn_list: {
    106        struct vki_xen_machphys_mfn_list *arg =
    107            (struct vki_xen_machphys_mfn_list *)ARG2;
    108        PRE_MEM_READ("XENMEM_machphys_mfn_list max_extents",
    109                     (Addr)&arg->max_extents, sizeof(arg->max_extents));
    110        PRE_MEM_READ("XENMEM_machphys_mfn_list extent_start",
    111                     (Addr)&arg->extent_start, sizeof(arg->extent_start));
    112        break;
    113    }
    114 
    115    case VKI_XENMEM_set_memory_map: {
    116       struct vki_xen_foreign_memory_map *arg =
    117 	      (struct vki_xen_foreign_memory_map *)ARG2;
    118       PRE_MEM_READ("XENMEM_set_memory_map domid",
    119                    (Addr)&arg->domid, sizeof(arg->domid));
    120       PRE_MEM_READ("XENMEM_set_memory_map map",
    121                    (Addr)&arg->map, sizeof(arg->map));
    122       break;
    123    }
    124    case VKI_XENMEM_increase_reservation:
    125    case VKI_XENMEM_decrease_reservation:
    126    case VKI_XENMEM_populate_physmap:
    127    case VKI_XENMEM_claim_pages: {
    128       struct xen_memory_reservation *memory_reservation =
    129          (struct xen_memory_reservation *)ARG2;
    130       const HChar *which;
    131 
    132       switch (ARG1) {
    133       case VKI_XENMEM_increase_reservation:
    134          which = "XENMEM_increase_reservation";
    135          break;
    136       case VKI_XENMEM_decrease_reservation:
    137          which = "XENMEM_decrease_reservation";
    138          PRE_MEM_READ(which,
    139                       (Addr)memory_reservation->extent_start.p,
    140                       sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
    141 	 break;
    142       case VKI_XENMEM_populate_physmap:
    143          which = "XENMEM_populate_physmap";
    144          PRE_MEM_READ(which,
    145                       (Addr)memory_reservation->extent_start.p,
    146                       sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
    147          break;
    148       case VKI_XENMEM_claim_pages:
    149          which = "XENMEM_claim_pages";
    150          break;
    151       default:
    152          which = "XENMEM_unknown";
    153          break;
    154       }
    155 
    156       PRE_MEM_READ(which,
    157                    (Addr)&memory_reservation->extent_start,
    158                    sizeof(memory_reservation->extent_start));
    159       PRE_MEM_READ(which,
    160                    (Addr)&memory_reservation->nr_extents,
    161                    sizeof(memory_reservation->nr_extents));
    162       PRE_MEM_READ(which,
    163                    (Addr)&memory_reservation->extent_order,
    164                    sizeof(memory_reservation->extent_order));
    165       PRE_MEM_READ(which,
    166                    (Addr)&memory_reservation->mem_flags,
    167                    sizeof(memory_reservation->mem_flags));
    168       PRE_MEM_READ(which,
    169                    (Addr)&memory_reservation->domid,
    170                    sizeof(memory_reservation->domid));
    171       break;
    172    }
    173 
    174    case VKI_XENMEM_add_to_physmap: {
    175        struct vki_xen_add_to_physmap *arg =
    176            (struct vki_xen_add_to_physmap *)ARG2;
    177        PRE_MEM_READ("XENMEM_add_to_physmap domid",
    178                     (Addr)&arg->domid, sizeof(arg->domid));
    179        PRE_MEM_READ("XENMEM_add_to_physmap size",
    180                     (Addr)&arg->size, sizeof(arg->size));
    181        PRE_MEM_READ("XENMEM_add_to_physmap space",
    182                     (Addr)&arg->space, sizeof(arg->space));
    183        PRE_MEM_READ("XENMEM_add_to_physmap idx",
    184                     (Addr)&arg->idx, sizeof(arg->idx));
    185        PRE_MEM_READ("XENMEM_add_to_physmap gpfn",
    186                     (Addr)&arg->gpfn, sizeof(arg->gpfn));
    187        break;
    188    }
    189 
    190    case VKI_XENMEM_remove_from_physmap: {
    191        struct vki_xen_remove_from_physmap *arg =
    192            (struct vki_xen_remove_from_physmap *)ARG2;
    193        PRE_MEM_READ("XENMEM_remove_from_physmap domid",
    194                     (Addr)&arg->domid, sizeof(arg->domid));
    195        PRE_MEM_READ("XENMEM_remove_from_physmap gpfn",
    196                     (Addr)&arg->gpfn, sizeof(arg->gpfn));
    197        break;
    198    }
    199 
    200    case VKI_XENMEM_get_sharing_freed_pages:
    201    case VKI_XENMEM_get_sharing_shared_pages:
    202       break;
    203 
    204    case VKI_XENMEM_access_op: {
    205        struct vki_xen_mem_event_op *arg =
    206             (struct vki_xen_mem_event_op *)ARG2;
    207        PRE_MEM_READ("XENMEM_access_op domid",
    208                     (Addr)&arg->domain, sizeof(arg->domain));
    209        PRE_MEM_READ("XENMEM_access_op op",
    210                     (Addr)&arg->op, sizeof(arg->op));
    211        PRE_MEM_READ("XENMEM_access_op gfn",
    212                     (Addr)&arg->gfn, sizeof(arg->gfn));
    213        break;
    214    }
    215    default:
    216       bad_subop(tid, layout, arrghs, status, flags,
    217                 "__HYPERVISOR_memory_op", ARG1);
    218       break;
    219    }
    220 }
    221 
    222 PRE(mmuext_op)
    223 {
    224    struct vki_xen_mmuext_op *ops = (struct vki_xen_mmuext_op *)ARG1;
    225    unsigned int i, nr = ARG2;
    226 
    227    for (i=0; i<nr; i++) {
    228       struct vki_xen_mmuext_op *op = ops + i;
    229       PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP cmd",
    230                    (Addr)&op->cmd, sizeof(op->cmd));
    231       switch(op->cmd) {
    232       case VKI_XEN_MMUEXT_PIN_L1_TABLE:
    233       case VKI_XEN_MMUEXT_PIN_L2_TABLE:
    234       case VKI_XEN_MMUEXT_PIN_L3_TABLE:
    235       case VKI_XEN_MMUEXT_PIN_L4_TABLE:
    236       case VKI_XEN_MMUEXT_UNPIN_TABLE:
    237       case VKI_XEN_MMUEXT_NEW_BASEPTR:
    238       case VKI_XEN_MMUEXT_CLEAR_PAGE:
    239       case VKI_XEN_MMUEXT_COPY_PAGE:
    240       case VKI_XEN_MMUEXT_MARK_SUPER:
    241       case VKI_XEN_MMUEXT_UNMARK_SUPER:
    242          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn",
    243                       (Addr)&op->arg1.mfn,
    244                       sizeof(op->arg1.mfn));
    245          break;
    246 
    247       case VKI_XEN_MMUEXT_INVLPG_LOCAL:
    248       case VKI_XEN_MMUEXT_INVLPG_ALL:
    249       case VKI_XEN_MMUEXT_SET_LDT:
    250          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn",
    251                       (Addr)&op->arg1.linear_addr,
    252                       sizeof(op->arg1.linear_addr));
    253          break;
    254 
    255       case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL:
    256       case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI:
    257       case VKI_XEN_MMUEXT_INVLPG_MULTI:
    258       case VKI_XEN_MMUEXT_TLB_FLUSH_ALL:
    259       case VKI_XEN_MMUEXT_FLUSH_CACHE:
    260       case VKI_XEN_MMUEXT_NEW_USER_BASEPTR:
    261       case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL:
    262          /* None */
    263          break;
    264       }
    265 
    266       switch(op->cmd) {
    267       case VKI_XEN_MMUEXT_SET_LDT:
    268          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.nr_ents",
    269                       (Addr)&op->arg2.nr_ents,
    270                       sizeof(op->arg2.nr_ents));
    271          break;
    272 
    273       case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI:
    274       case VKI_XEN_MMUEXT_INVLPG_MULTI:
    275          /* How many??? */
    276          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.vcpumask",
    277                       (Addr)&op->arg2.vcpumask,
    278                       sizeof(op->arg2.vcpumask));
    279          break;
    280 
    281       case VKI_XEN_MMUEXT_COPY_PAGE:
    282          PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.src_mfn",
    283                       (Addr)&op->arg2.src_mfn,
    284                       sizeof(op->arg2.src_mfn));
    285          break;
    286 
    287       case VKI_XEN_MMUEXT_PIN_L1_TABLE:
    288       case VKI_XEN_MMUEXT_PIN_L2_TABLE:
    289       case VKI_XEN_MMUEXT_PIN_L3_TABLE:
    290       case VKI_XEN_MMUEXT_PIN_L4_TABLE:
    291       case VKI_XEN_MMUEXT_UNPIN_TABLE:
    292       case VKI_XEN_MMUEXT_NEW_BASEPTR:
    293       case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL:
    294       case VKI_XEN_MMUEXT_INVLPG_LOCAL:
    295       case VKI_XEN_MMUEXT_TLB_FLUSH_ALL:
    296       case VKI_XEN_MMUEXT_INVLPG_ALL:
    297       case VKI_XEN_MMUEXT_FLUSH_CACHE:
    298       case VKI_XEN_MMUEXT_NEW_USER_BASEPTR:
    299       case VKI_XEN_MMUEXT_CLEAR_PAGE:
    300       case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL:
    301       case VKI_XEN_MMUEXT_MARK_SUPER:
    302       case VKI_XEN_MMUEXT_UNMARK_SUPER:
    303          /* None */
    304          break;
    305       }
    306    }
    307 }
    308 
    309 static void pre_evtchn_op(ThreadId tid,
    310                           SyscallArgLayout*     layout,
    311                           /*MOD*/SyscallArgs*   arrghs,
    312                           /*OUT*/SyscallStatus* status,
    313                           /*OUT*/UWord*         flags,
    314                           __vki_u32 cmd, void *arg, int compat)
    315 {
    316    PRINT("__HYPERVISOR_event_channel_op%s ( %d, %p )",
    317          compat ? "_compat" : "", cmd, arg);
    318 
    319    switch (cmd) {
    320    case VKI_XEN_EVTCHNOP_alloc_unbound: {
    321       struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg;
    322       PRE_MEM_READ("EVTCHNOP_alloc_unbound dom",
    323                    (Addr)&alloc_unbound->dom, sizeof(alloc_unbound->dom));
    324       PRE_MEM_READ("EVTCHNOP_alloc_unbound remote_dom",
    325                    (Addr)&alloc_unbound->remote_dom,
    326                    sizeof(alloc_unbound->remote_dom));
    327       break;
    328    }
    329    default:
    330       if ( compat )
    331          bad_subop(tid, layout, arrghs, status, flags,
    332                    "__HYPERVISOR_event_channel_op_compat", cmd);
    333       else
    334          bad_subop(tid, layout, arrghs, status, flags,
    335                    "__HYPERVISOR_event_channel_op", cmd);
    336       break;
    337    }
    338 }
    339 
    340 PRE(evtchn_op)
    341 {
    342    pre_evtchn_op(tid, layout, arrghs, status, flags,
    343                  ARG1, (void *)ARG2, 0);
    344 }
    345 
    346 PRE(evtchn_op_compat)
    347 {
    348    struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1;
    349    PRE_MEM_READ("__HYPERVISOR_event_channel_op_compat",
    350                 ARG1, sizeof(*evtchn));
    351 
    352    pre_evtchn_op(tid, layout, arrghs, status, flags,
    353                  evtchn->cmd, &evtchn->u, 1);
    354 }
    355 
    356 PRE(xen_version)
    357 {
    358    PRINT("__HYPERVISOR_xen_version ( %ld, %lx )", ARG1, ARG2);
    359 
    360    switch (ARG1) {
    361    case VKI_XENVER_version:
    362    case VKI_XENVER_extraversion:
    363    case VKI_XENVER_compile_info:
    364    case VKI_XENVER_capabilities:
    365    case VKI_XENVER_changeset:
    366    case VKI_XENVER_platform_parameters:
    367    case VKI_XENVER_get_features:
    368    case VKI_XENVER_pagesize:
    369    case VKI_XENVER_guest_handle:
    370    case VKI_XENVER_commandline:
    371       /* No inputs */
    372       break;
    373 
    374    default:
    375       bad_subop(tid, layout, arrghs, status, flags,
    376                 "__HYPERVISOR_xen_version", ARG1);
    377       break;
    378    }
    379 }
    380 
    381 PRE(grant_table_op)
    382 {
    383    PRINT("__HYPERVISOR_grant_table_op ( %ld, 0x%lx, %ld )", ARG1, ARG2, ARG3);
    384    switch (ARG1) {
    385    case VKI_XEN_GNTTABOP_setup_table: {
    386       struct vki_xen_gnttab_setup_table *gst =
    387 	      (struct vki_xen_gnttab_setup_table*)ARG2;
    388       PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table dom",
    389 		   (Addr)&gst->dom, sizeof(gst->dom));
    390       PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table nr_frames",
    391                    (Addr)&gst->nr_frames, sizeof(gst->nr_frames));
    392       break;
    393    }
    394    default:
    395       bad_subop(tid, layout, arrghs, status, flags,
    396                 "__HYPERVISOR_grant_table_op", ARG1);
    397       break;
    398    }
    399 }
    400 
    401 PRE(sysctl) {
    402    struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1;
    403 
    404    PRINT("__HYPERVISOR_sysctl ( %d )", sysctl->cmd);
    405 
    406    /*
    407     * Common part of xen_sysctl:
    408     *    uint32_t cmd;
    409     *    uint32_t interface_version;
    410     */
    411    PRE_MEM_READ("__HYPERVISOR_sysctl", ARG1,
    412                 sizeof(vki_uint32_t) + sizeof(vki_uint32_t));
    413 
    414    if (!sysctl)
    415       return;
    416 
    417    switch (sysctl->interface_version)
    418    {
    419    case 0x00000008:
    420    case 0x00000009:
    421    case 0x0000000a:
    422 	   break;
    423    default:
    424       VG_(dmsg)("WARNING: sysctl version %"PRIx32" not supported\n",
    425                 sysctl->interface_version);
    426       if (VG_(clo_verbosity) > 1) {
    427          VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
    428       }
    429       VG_(dmsg)("You may be able to write your own handler.\n");
    430       VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
    431       VG_(dmsg)("Nevertheless we consider this a bug.  Please report\n");
    432       VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
    433       VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
    434 
    435       SET_STATUS_Failure(VKI_EINVAL);
    436       return;
    437    }
    438 
    439 #define __PRE_XEN_SYSCTL_READ(_sysctl, _union, _field)			\
    440       PRE_MEM_READ("XEN_SYSCTL_" #_sysctl " u." #_union "." #_field,	\
    441                    (Addr)&sysctl->u._union._field,			\
    442                    sizeof(sysctl->u._union._field))
    443 #define PRE_XEN_SYSCTL_READ(_sysctl, _field) \
    444       __PRE_XEN_SYSCTL_READ(_sysctl, _sysctl, _field)
    445 
    446    switch (sysctl->cmd) {
    447    case VKI_XEN_SYSCTL_readconsole:
    448        /* These are all unconditionally read */
    449        PRE_XEN_SYSCTL_READ(readconsole, clear);
    450        PRE_XEN_SYSCTL_READ(readconsole, incremental);
    451        PRE_XEN_SYSCTL_READ(readconsole, buffer);
    452        PRE_XEN_SYSCTL_READ(readconsole, count);
    453 
    454        /* 'index' only read if 'incremental' is nonzero */
    455        if (sysctl->u.readconsole.incremental)
    456            PRE_XEN_SYSCTL_READ(readconsole, index);
    457        break;
    458 
    459    case VKI_XEN_SYSCTL_getdomaininfolist:
    460       switch (sysctl->interface_version)
    461       {
    462       case 0x00000008:
    463 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, first_domain);
    464 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, max_domains);
    465 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, buffer);
    466 	 break;
    467       case 0x00000009:
    468 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, first_domain);
    469 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, max_domains);
    470 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, buffer);
    471 	 break;
    472       case 0x0000000a:
    473 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, first_domain);
    474 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, max_domains);
    475 	 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, buffer);
    476 	 break;
    477       default:
    478           VG_(dmsg)("WARNING: XEN_SYSCTL_getdomaininfolist for sysctl version "
    479                     "%"PRIx32" not implemented yet\n",
    480                     sysctl->interface_version);
    481           SET_STATUS_Failure(VKI_EINVAL);
    482           return;
    483       }
    484       break;
    485 
    486    case VKI_XEN_SYSCTL_debug_keys:
    487        PRE_XEN_SYSCTL_READ(debug_keys, keys);
    488        PRE_XEN_SYSCTL_READ(debug_keys, nr_keys);
    489        PRE_MEM_READ("XEN_SYSCTL_debug_keys *keys",
    490                     (Addr)sysctl->u.debug_keys.keys.p,
    491                     sysctl->u.debug_keys.nr_keys * sizeof(char));
    492        break;
    493 
    494    case VKI_XEN_SYSCTL_sched_id:
    495        /* No inputs */
    496        break;
    497 
    498    case VKI_XEN_SYSCTL_cpupool_op:
    499       PRE_XEN_SYSCTL_READ(cpupool_op, op);
    500 
    501       switch(sysctl->u.cpupool_op.op) {
    502       case VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE:
    503       case VKI_XEN_SYSCTL_CPUPOOL_OP_DESTROY:
    504       case VKI_XEN_SYSCTL_CPUPOOL_OP_INFO:
    505       case VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU:
    506       case VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU:
    507       case VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN:
    508          PRE_XEN_SYSCTL_READ(cpupool_op, cpupool_id);
    509       }
    510 
    511       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE)
    512          PRE_XEN_SYSCTL_READ(cpupool_op, sched_id);
    513 
    514       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN)
    515          PRE_XEN_SYSCTL_READ(cpupool_op, domid);
    516 
    517       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU ||
    518           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU)
    519          PRE_XEN_SYSCTL_READ(cpupool_op, cpu);
    520 
    521       break;
    522 
    523    case VKI_XEN_SYSCTL_physinfo:
    524       /* No input params */
    525       break;
    526 
    527    case VKI_XEN_SYSCTL_topologyinfo:
    528       PRE_XEN_SYSCTL_READ(topologyinfo, max_cpu_index);
    529       PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_core);
    530       PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_socket);
    531       PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_node);
    532       break;
    533 
    534    case VKI_XEN_SYSCTL_numainfo:
    535       PRE_XEN_SYSCTL_READ(numainfo, max_node_index);
    536       PRE_XEN_SYSCTL_READ(numainfo, node_to_memsize);
    537       PRE_XEN_SYSCTL_READ(numainfo, node_to_memfree);
    538       PRE_XEN_SYSCTL_READ(numainfo, node_to_node_distance);
    539       break;
    540 
    541    default:
    542       bad_subop(tid, layout, arrghs, status, flags,
    543                 "__HYPERVISOR_sysctl", sysctl->cmd);
    544       break;
    545    }
    546 #undef PRE_XEN_SYSCTL_READ
    547 #undef __PRE_XEN_SYSCTL_READ
    548 }
    549 
    550 PRE(domctl)
    551 {
    552    struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1;
    553 
    554    PRINT("__HYPERVISOR_domctl ( %d ) on dom%d", domctl->cmd, domctl->domain);
    555 
    556    /*
    557     * Common part of xen_domctl:
    558     *    vki_uint32_t cmd;
    559     *    vki_uint32_t interface_version;
    560     *    vki_xen_domid_t  domain;
    561     */
    562    PRE_MEM_READ("__HYPERVISOR_domctl", ARG1,
    563                 sizeof(vki_uint32_t) + sizeof(vki_uint32_t)
    564 		+ sizeof(vki_xen_domid_t));
    565 
    566    if (!domctl)
    567       return;
    568 
    569    switch (domctl->interface_version)
    570    {
    571    case 0x00000007:
    572    case 0x00000008:
    573    case 0x00000009:
    574 	   break;
    575    default:
    576       VG_(dmsg)("WARNING: domctl version %"PRIx32" not supported\n",
    577                 domctl->interface_version);
    578       if (VG_(clo_verbosity) > 1) {
    579          VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
    580       }
    581       VG_(dmsg)("You may be able to write your own handler.\n");
    582       VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
    583       VG_(dmsg)("Nevertheless we consider this a bug.  Please report\n");
    584       VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
    585       VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
    586 
    587       SET_STATUS_Failure(VKI_EINVAL);
    588       return;
    589    }
    590 
    591 #define __PRE_XEN_DOMCTL_READ(_domctl, _union, _field)			\
    592       PRE_MEM_READ("XEN_DOMCTL_" #_domctl " u." #_union "." #_field,	\
    593                    (Addr)&domctl->u._union._field,			\
    594                    sizeof(domctl->u._union._field))
    595 #define PRE_XEN_DOMCTL_READ(_domctl, _field) \
    596       __PRE_XEN_DOMCTL_READ(_domctl, _domctl, _field)
    597 
    598    switch (domctl->cmd) {
    599    case VKI_XEN_DOMCTL_destroydomain:
    600    case VKI_XEN_DOMCTL_pausedomain:
    601    case VKI_XEN_DOMCTL_max_vcpus:
    602    case VKI_XEN_DOMCTL_get_address_size:
    603    case VKI_XEN_DOMCTL_gettscinfo:
    604    case VKI_XEN_DOMCTL_getdomaininfo:
    605    case VKI_XEN_DOMCTL_unpausedomain:
    606    case VKI_XEN_DOMCTL_resumedomain:
    607       /* No input fields. */
    608       break;
    609 
    610    case VKI_XEN_DOMCTL_createdomain:
    611       PRE_XEN_DOMCTL_READ(createdomain, ssidref);
    612       PRE_XEN_DOMCTL_READ(createdomain, handle);
    613       PRE_XEN_DOMCTL_READ(createdomain, flags);
    614       break;
    615 
    616    case VKI_XEN_DOMCTL_gethvmcontext:
    617        /* Xen unconditionally reads the 'buffer' pointer */
    618        __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, buffer);
    619        /* Xen only consumes 'size' if 'buffer' is non NULL. A NULL
    620         * buffer is a request for the required size. */
    621        if ( domctl->u.hvmcontext.buffer.p )
    622            __PRE_XEN_DOMCTL_READ(gethvmcontext, hvmcontext, size);
    623        break;
    624 
    625    case VKI_XEN_DOMCTL_sethvmcontext:
    626        __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, size);
    627        __PRE_XEN_DOMCTL_READ(sethvmcontext, hvmcontext, buffer);
    628        PRE_MEM_READ("XEN_DOMCTL_sethvmcontext *buffer",
    629                     (Addr)domctl->u.hvmcontext.buffer.p,
    630                     domctl->u.hvmcontext.size);
    631        break;
    632 
    633    case VKI_XEN_DOMCTL_gethvmcontext_partial:
    634        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, type);
    635        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, instance);
    636        __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, buffer);
    637 
    638        switch (domctl->u.hvmcontext_partial.type) {
    639        case VKI_HVM_SAVE_CODE(CPU):
    640            if ( domctl->u.hvmcontext_partial.buffer.p )
    641                 PRE_MEM_WRITE("XEN_DOMCTL_gethvmcontext_partial *buffer",
    642                    (Addr)domctl->u.hvmcontext_partial.buffer.p,
    643                    VKI_HVM_SAVE_LENGTH(CPU));
    644            break;
    645        default:
    646            bad_subop(tid, layout, arrghs, status, flags,
    647                          "__HYPERVISOR_domctl_gethvmcontext_partial type",
    648                          domctl->u.hvmcontext_partial.type);
    649            break;
    650        }
    651        break;
    652 
    653    case VKI_XEN_DOMCTL_max_mem:
    654       PRE_XEN_DOMCTL_READ(max_mem, max_memkb);
    655       break;
    656 
    657    case VKI_XEN_DOMCTL_set_address_size:
    658       __PRE_XEN_DOMCTL_READ(set_address_size, address_size, size);
    659       break;
    660 
    661    case VKI_XEN_DOMCTL_settscinfo:
    662       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.tsc_mode);
    663       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.gtsc_khz);
    664       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.incarnation);
    665       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.elapsed_nsec);
    666       break;
    667 
    668    case VKI_XEN_DOMCTL_ioport_permission:
    669       PRE_XEN_DOMCTL_READ(ioport_permission, first_port);
    670       PRE_XEN_DOMCTL_READ(ioport_permission, nr_ports);
    671       PRE_XEN_DOMCTL_READ(ioport_permission, allow_access);
    672       break;
    673 
    674    case VKI_XEN_DOMCTL_hypercall_init:
    675       PRE_XEN_DOMCTL_READ(hypercall_init, gmfn);
    676       break;
    677 
    678    case VKI_XEN_DOMCTL_settimeoffset:
    679        PRE_XEN_DOMCTL_READ(settimeoffset, time_offset_seconds);
    680        break;
    681 
    682    case VKI_XEN_DOMCTL_getvcpuinfo:
    683       PRE_XEN_DOMCTL_READ(getvcpuinfo, vcpu);
    684       break;
    685 
    686    case VKI_XEN_DOMCTL_scheduler_op:
    687       PRE_XEN_DOMCTL_READ(scheduler_op, sched_id);
    688       PRE_XEN_DOMCTL_READ(scheduler_op, cmd);
    689       if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_putinfo ) {
    690          switch(domctl->u.scheduler_op.sched_id) {
    691          case VKI_XEN_SCHEDULER_SEDF:
    692             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.period);
    693             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.slice);
    694             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.latency);
    695             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.extratime);
    696             PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.weight);
    697             break;
    698          case VKI_XEN_SCHEDULER_CREDIT:
    699             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.weight);
    700             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.cap);
    701             break;
    702          case VKI_XEN_SCHEDULER_CREDIT2:
    703             PRE_XEN_DOMCTL_READ(scheduler_op, u.credit2.weight);
    704             break;
    705          case VKI_XEN_SCHEDULER_ARINC653:
    706             break;
    707          }
    708       }
    709       break;
    710 
    711    case VKI_XEN_DOMCTL_getvcpuaffinity:
    712       __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity, vcpu);
    713       break;
    714 
    715    case VKI_XEN_DOMCTL_setvcpuaffinity:
    716       __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity, vcpu);
    717       PRE_MEM_READ("XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap.bitmap",
    718                    (Addr)domctl->u.vcpuaffinity.cpumap.bitmap.p,
    719                    domctl->u.vcpuaffinity.cpumap.nr_bits / 8);
    720       break;
    721 
    722    case VKI_XEN_DOMCTL_getnodeaffinity:
    723       __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
    724       break;
    725    case VKI_XEN_DOMCTL_setnodeaffinity:
    726       __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits);
    727       PRE_MEM_READ("XEN_DOMCTL_setnodeaffinity u.nodeaffinity.cpumap.bitmap",
    728                    (Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
    729                    domctl->u.nodeaffinity.nodemap.nr_bits / 8);
    730       break;
    731 
    732    case VKI_XEN_DOMCTL_getvcpucontext:
    733       __PRE_XEN_DOMCTL_READ(getvcpucontext, vcpucontext, vcpu);
    734       break;
    735 
    736    case VKI_XEN_DOMCTL_setvcpucontext:
    737       __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, vcpu);
    738       __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, ctxt.p);
    739       break;
    740 
    741    case VKI_XEN_DOMCTL_set_cpuid:
    742       PRE_MEM_READ("XEN_DOMCTL_set_cpuid u.cpuid",
    743                    (Addr)&domctl->u.cpuid, sizeof(domctl->u.cpuid));
    744       break;
    745 
    746    case VKI_XEN_DOMCTL_getpageframeinfo3:
    747        PRE_XEN_DOMCTL_READ(getpageframeinfo3, num);
    748        PRE_XEN_DOMCTL_READ(getpageframeinfo3, array.p);
    749        PRE_MEM_READ("XEN_DOMCTL_getpageframeinfo3 *u.getpageframeinfo3.array.p",
    750                     (Addr)domctl->u.getpageframeinfo3.array.p,
    751                     domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
    752        break;
    753 
    754    case VKI_XEN_DOMCTL_getvcpuextstate:
    755       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, vcpu);
    756       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, xfeature_mask);
    757       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, size);
    758       __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, buffer);
    759       break;
    760 
    761    case VKI_XEN_DOMCTL_shadow_op:
    762        PRE_XEN_DOMCTL_READ(shadow_op, op);
    763 
    764        switch(domctl->u.shadow_op.op)
    765        {
    766        case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
    767            /* No further inputs */
    768            break;
    769 
    770        case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE:
    771            PRE_XEN_DOMCTL_READ(shadow_op, mode);
    772            switch(domctl->u.shadow_op.mode)
    773            {
    774            case XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY:
    775                goto domctl_shadow_op_enable_logdirty;
    776 
    777 
    778            default:
    779                bad_subop(tid, layout, arrghs, status, flags,
    780                          "__HYPERVISOR_domctl shadowop mode",
    781                          domctl->u.shadow_op.mode);
    782                break;
    783            }
    784 
    785        case VKI_XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:
    786        domctl_shadow_op_enable_logdirty:
    787            /* No further inputs */
    788            break;
    789 
    790        case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
    791        case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
    792            PRE_XEN_DOMCTL_READ(shadow_op, dirty_bitmap);
    793            PRE_XEN_DOMCTL_READ(shadow_op, pages);
    794            break;
    795 
    796        default:
    797            bad_subop(tid, layout, arrghs, status, flags,
    798                      "__HYPERVISOR_domctl shadow(10)",
    799                      domctl->u.shadow_op.op);
    800            break;
    801        }
    802        break;
    803 
    804    case VKI_XEN_DOMCTL_set_max_evtchn:
    805       PRE_XEN_DOMCTL_READ(set_max_evtchn, max_port);
    806       break;
    807 
    808    case VKI_XEN_DOMCTL_cacheflush:
    809       PRE_XEN_DOMCTL_READ(cacheflush, start_pfn);
    810       PRE_XEN_DOMCTL_READ(cacheflush, nr_pfns);
    811       break;
    812 
    813    case VKI_XEN_DOMCTL_set_access_required:
    814       PRE_XEN_DOMCTL_READ(access_required, access_required);
    815       break;
    816 
    817    case VKI_XEN_DOMCTL_mem_event_op:
    818       PRE_XEN_DOMCTL_READ(mem_event_op, op);
    819       PRE_XEN_DOMCTL_READ(mem_event_op, mode);
    820       break;
    821 
    822    case VKI_XEN_DOMCTL_debug_op:
    823       PRE_XEN_DOMCTL_READ(debug_op, op);
    824       PRE_XEN_DOMCTL_READ(debug_op, vcpu);
    825       break;
    826 
    827    default:
    828       bad_subop(tid, layout, arrghs, status, flags,
    829                 "__HYPERVISOR_domctl", domctl->cmd);
    830       break;
    831    }
    832 #undef PRE_XEN_DOMCTL_READ
    833 #undef __PRE_XEN_DOMCTL_READ
    834 }
    835 
    836 PRE(hvm_op)
    837 {
    838    unsigned long op = ARG1;
    839    void *arg = (void *)(unsigned long)ARG2;
    840 
    841    PRINT("__HYPERVISOR_hvm_op ( %ld, %p )", op, arg);
    842 
    843 #define __PRE_XEN_HVMOP_READ(_hvm_op, _type, _field)    \
    844    PRE_MEM_READ("XEN_HVMOP_" # _hvm_op " " #_field,     \
    845                 (Addr)&((_type*)arg)->_field,           \
    846                 sizeof(((_type*)arg)->_field))
    847 #define PRE_XEN_HVMOP_READ(_hvm_op, _field)                             \
    848    __PRE_XEN_HVMOP_READ(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
    849 
    850    switch (op) {
    851    case VKI_XEN_HVMOP_set_param:
    852       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, domid);
    853       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, index);
    854       __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, value);
    855       break;
    856 
    857    case VKI_XEN_HVMOP_get_param:
    858       __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, domid);
    859       __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, index);
    860       break;
    861 
    862    case VKI_XEN_HVMOP_set_isa_irq_level:
    863        PRE_XEN_HVMOP_READ(set_isa_irq_level, domid);
    864        PRE_XEN_HVMOP_READ(set_isa_irq_level, isa_irq);
    865        PRE_XEN_HVMOP_READ(set_isa_irq_level, level);
    866        break;
    867 
    868    case VKI_XEN_HVMOP_set_pci_link_route:
    869        PRE_XEN_HVMOP_READ(set_pci_link_route, domid);
    870        PRE_XEN_HVMOP_READ(set_pci_link_route, link);
    871        PRE_XEN_HVMOP_READ(set_pci_link_route, isa_irq);
    872        break;
    873 
    874    case VKI_XEN_HVMOP_set_mem_type:
    875        PRE_XEN_HVMOP_READ(set_mem_type, domid);
    876        PRE_XEN_HVMOP_READ(set_mem_type, hvmmem_type);
    877        PRE_XEN_HVMOP_READ(set_mem_type, nr);
    878        PRE_XEN_HVMOP_READ(set_mem_type, first_pfn);
    879        break;
    880 
    881    case VKI_XEN_HVMOP_set_mem_access:
    882        PRE_XEN_HVMOP_READ(set_mem_access, domid);
    883        PRE_XEN_HVMOP_READ(set_mem_access, hvmmem_access);
    884        PRE_XEN_HVMOP_READ(set_mem_access, first_pfn);
    885        /* if default access */
    886        if ( ((vki_xen_hvm_set_mem_access_t*)arg)->first_pfn != ~0ULL)
    887            PRE_XEN_HVMOP_READ(set_mem_access, nr);
    888        break;
    889 
    890    case VKI_XEN_HVMOP_get_mem_access:
    891        PRE_XEN_HVMOP_READ(get_mem_access, domid);
    892        PRE_XEN_HVMOP_READ(get_mem_access, pfn);
    893 
    894        PRE_MEM_WRITE("XEN_HVMOP_get_mem_access *hvmmem_access",
    895                    (Addr)&(((vki_xen_hvm_get_mem_access_t*)arg)->hvmmem_access),
    896                    sizeof(vki_uint16_t));
    897        break;
    898 
    899    case VKI_XEN_HVMOP_inject_trap:
    900        PRE_XEN_HVMOP_READ(inject_trap, domid);
    901        PRE_XEN_HVMOP_READ(inject_trap, vcpuid);
    902        PRE_XEN_HVMOP_READ(inject_trap, vector);
    903        PRE_XEN_HVMOP_READ(inject_trap, type);
    904        PRE_XEN_HVMOP_READ(inject_trap, error_code);
    905        PRE_XEN_HVMOP_READ(inject_trap, insn_len);
    906        PRE_XEN_HVMOP_READ(inject_trap, cr2);
    907        break;
    908 
    909    default:
    910       bad_subop(tid, layout, arrghs, status, flags,
    911                 "__HYPERVISOR_hvm_op", op);
    912       break;
    913    }
    914 #undef __PRE_XEN_HVMOP_READ
    915 #undef PRE_XEN_HVMOP_READ
    916 }
    917 
    918 PRE(tmem_op)
    919 {
    920     struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
    921 
    922     PRINT("__HYPERVISOR_tmem_op ( %d )", tmem->cmd);
    923 
    924     /* Common part for xen_tmem_op:
    925      *    vki_uint32_t cmd;
    926      */
    927     PRE_MEM_READ("__HYPERVISOR_tmem_op cmd", ARG1, sizeof(vki_uint32_t));
    928 
    929 
    930 #define __PRE_XEN_TMEMOP_READ(_tmem, _union, _field)                    \
    931     PRE_MEM_READ("XEN_tmem_op_" #_tmem " u." #_union "." #_field,       \
    932                  (Addr)&tmem->u._union._field,                          \
    933                  sizeof(tmem->u._union._field))
    934 #define PRE_XEN_TMEMOP_READ(_tmem, _field)                              \
    935     __PRE_XEN_TMEMOP_READ(_tmem, _tmem, _field)
    936 
    937     switch(tmem->cmd) {
    938 
    939     case VKI_XEN_TMEM_control:
    940 
    941         /* Common part for control hypercall:
    942          *    vki_int32_t pool_id;
    943          *    vki_uint32_t subop;
    944          */
    945         PRE_MEM_READ("__HYPERVISOR_tmem_op pool_id",
    946                      (Addr)&tmem->pool_id, sizeof(&tmem->pool_id));
    947         PRE_XEN_TMEMOP_READ(ctrl, subop);
    948 
    949         switch (tmem->u.ctrl.subop) {
    950 
    951         case VKI_XEN_TMEMC_save_begin:
    952             PRE_XEN_TMEMOP_READ(ctrl, cli_id);
    953             PRE_XEN_TMEMOP_READ(ctrl, arg1);
    954             PRE_XEN_TMEMOP_READ(ctrl, buf);
    955             break;
    956 
    957         default:
    958             bad_subop(tid, layout, arrghs, status, flags,
    959                       "__HYPERVISOR_tmem_op_control", tmem->u.ctrl.subop);
    960         }
    961 
    962         break;
    963 
    964     default:
    965         bad_subop(tid, layout, arrghs, status, flags,
    966                   "__HYPERVISOR_tmem_op", ARG1);
    967     }
    968 
    969 #undef PRE_XEN_TMEMOP_READ
    970 #undef __PRE_XEN_TMEMOP_READ
    971 }
    972 
    973 POST(memory_op)
    974 {
    975    switch (ARG1) {
    976    case VKI_XENMEM_maximum_ram_page:
    977    case VKI_XENMEM_set_memory_map:
    978    case VKI_XENMEM_decrease_reservation:
    979    case VKI_XENMEM_claim_pages:
    980    case VKI_XENMEM_maximum_gpfn:
    981    case VKI_XENMEM_remove_from_physmap:
    982    case VKI_XENMEM_access_op:
    983       /* No outputs */
    984       break;
    985    case VKI_XENMEM_increase_reservation:
    986    case VKI_XENMEM_populate_physmap: {
    987       struct xen_memory_reservation *memory_reservation =
    988          (struct xen_memory_reservation *)ARG2;
    989 
    990       POST_MEM_WRITE((Addr)memory_reservation->extent_start.p,
    991                      sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents);
    992       break;
    993    }
    994 
    995    case VKI_XENMEM_machphys_mfn_list: {
    996        struct vki_xen_machphys_mfn_list *arg =
    997            (struct vki_xen_machphys_mfn_list *)ARG2;
    998        POST_MEM_WRITE((Addr)&arg->nr_extents, sizeof(arg->nr_extents));
    999        POST_MEM_WRITE((Addr)arg->extent_start.p,
   1000                       sizeof(vki_xen_pfn_t) * arg->nr_extents);
   1001        break;
   1002    }
   1003 
   1004    case VKI_XENMEM_add_to_physmap: {
   1005        struct vki_xen_add_to_physmap *arg =
   1006            (struct vki_xen_add_to_physmap *)ARG2;
   1007        if (arg->space == VKI_XENMAPSPACE_gmfn_range)
   1008            POST_MEM_WRITE(ARG2, sizeof(*arg));
   1009    }
   1010 
   1011    case VKI_XENMEM_get_sharing_freed_pages:
   1012    case VKI_XENMEM_get_sharing_shared_pages:
   1013        /* No outputs */
   1014        break;
   1015    }
   1016 }
   1017 
   1018 POST(mmuext_op)
   1019 {
   1020    unsigned int *pdone = (unsigned int *)ARG3;
   1021    /* simplistic */
   1022    POST_MEM_WRITE((Addr)pdone, sizeof(*pdone));
   1023 }
   1024 
   1025 static void post_evtchn_op(ThreadId tid, __vki_u32 cmd, void *arg, int compat)
   1026 {
   1027    switch (cmd) {
   1028    case VKI_XEN_EVTCHNOP_alloc_unbound: {
   1029       struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg;
   1030       POST_MEM_WRITE((Addr)&alloc_unbound->port, sizeof(alloc_unbound->port));
   1031       break;
   1032    }
   1033    }
   1034 }
   1035 
   1036 POST(evtchn_op)
   1037 {
   1038    post_evtchn_op(tid, ARG1, (void *)ARG2, 0);
   1039 }
   1040 
   1041 POST(evtchn_op_compat)
   1042 {
   1043    struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1;
   1044    post_evtchn_op(tid, evtchn->cmd, &evtchn->u, 1);
   1045 }
   1046 
   1047 POST(xen_version)
   1048 {
   1049    switch (ARG1) {
   1050    case VKI_XENVER_version:
   1051       /* No outputs */
   1052       break;
   1053    case VKI_XENVER_extraversion:
   1054       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_extraversion_t));
   1055       break;
   1056    case VKI_XENVER_compile_info:
   1057       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_compile_info));
   1058       break;
   1059    case VKI_XENVER_capabilities:
   1060       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_capabilities_info_t));
   1061       break;
   1062    case VKI_XENVER_changeset:
   1063       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_changeset_info_t));
   1064       break;
   1065    case VKI_XENVER_platform_parameters:
   1066       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_platform_parameters));
   1067       break;
   1068    case VKI_XENVER_get_features:
   1069       POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_feature_info));
   1070       break;
   1071    case VKI_XENVER_pagesize:
   1072       /* No outputs */
   1073       break;
   1074    case VKI_XENVER_guest_handle:
   1075       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_domain_handle_t));
   1076       break;
   1077    case VKI_XENVER_commandline:
   1078       POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_commandline_t));
   1079       break;
   1080    }
   1081 }
   1082 
   1083 POST(grant_table_op)
   1084 {
   1085    switch (ARG1) {
   1086    case VKI_XEN_GNTTABOP_setup_table: {
   1087       struct vki_xen_gnttab_setup_table *gst =
   1088 	      (struct vki_xen_gnttab_setup_table*)ARG2;
   1089       PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
   1090                     (Addr)&gst->status, sizeof(gst->status));
   1091       PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table",
   1092                     (Addr)gst->frame_list.p,
   1093                     sizeof(*gst->frame_list.p) & gst->nr_frames);
   1094       break;
   1095    }
   1096    }
   1097 }
   1098 
   1099 POST(sysctl)
   1100 {
   1101    struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1;
   1102 
   1103    switch (sysctl->interface_version)
   1104    {
   1105    case 0x00000008:
   1106    case 0x00000009:
   1107    case 0x0000000a:
   1108 	   break;
   1109    default:
   1110       return;
   1111    }
   1112 
   1113 #define __POST_XEN_SYSCTL_WRITE(_sysctl, _union, _field)        \
   1114       POST_MEM_WRITE((Addr)&sysctl->u._union._field,            \
   1115                      sizeof(sysctl->u._union._field))
   1116 #define POST_XEN_SYSCTL_WRITE(_sysctl, _field) \
   1117       __POST_XEN_SYSCTL_WRITE(_sysctl, _sysctl, _field)
   1118 
   1119    switch (sysctl->cmd) {
   1120    case VKI_XEN_SYSCTL_readconsole:
   1121        POST_MEM_WRITE((Addr)sysctl->u.readconsole.buffer.p,
   1122                       sysctl->u.readconsole.count * sizeof(char));
   1123        break;
   1124 
   1125    case VKI_XEN_SYSCTL_getdomaininfolist:
   1126       switch (sysctl->interface_version)
   1127       {
   1128       case 0x00000008:
   1129 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000008, num_domains);
   1130 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000008.buffer.p,
   1131 			sizeof(*sysctl->u.getdomaininfolist_00000008.buffer.p)
   1132 			* sysctl->u.getdomaininfolist_00000008.num_domains);
   1133 	 break;
   1134       case 0x00000009:
   1135 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000009, num_domains);
   1136 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000009.buffer.p,
   1137 			sizeof(*sysctl->u.getdomaininfolist_00000009.buffer.p)
   1138 			* sysctl->u.getdomaininfolist_00000009.num_domains);
   1139 	 break;
   1140       case 0x0000000a:
   1141 	 POST_XEN_SYSCTL_WRITE(getdomaininfolist_0000000a, num_domains);
   1142 	 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_0000000a.buffer.p,
   1143 			sizeof(*sysctl->u.getdomaininfolist_0000000a.buffer.p)
   1144 			* sysctl->u.getdomaininfolist_0000000a.num_domains);
   1145 	 break;
   1146       }
   1147       break;
   1148 
   1149    case VKI_XEN_SYSCTL_sched_id:
   1150        POST_XEN_SYSCTL_WRITE(sched_id, sched_id);
   1151        break;
   1152 
   1153    case VKI_XEN_SYSCTL_cpupool_op:
   1154       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE ||
   1155           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO)
   1156          POST_XEN_SYSCTL_WRITE(cpupool_op, cpupool_id);
   1157       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO) {
   1158          POST_XEN_SYSCTL_WRITE(cpupool_op, sched_id);
   1159          POST_XEN_SYSCTL_WRITE(cpupool_op, n_dom);
   1160       }
   1161       if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO ||
   1162           sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_FREEINFO)
   1163          POST_XEN_SYSCTL_WRITE(cpupool_op, cpumap);
   1164       break;
   1165 
   1166    case VKI_XEN_SYSCTL_physinfo:
   1167       switch (sysctl->interface_version)
   1168       {
   1169       case 0x00000008:
   1170       case 0x00000009: /* Unchanged from version 8 */
   1171          POST_XEN_SYSCTL_WRITE(physinfo_00000008, threads_per_core);
   1172          POST_XEN_SYSCTL_WRITE(physinfo_00000008, cores_per_socket);
   1173          POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_cpus);
   1174          POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_cpu_id);
   1175          POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_nodes);
   1176          POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_node_id);
   1177          POST_XEN_SYSCTL_WRITE(physinfo_00000008, cpu_khz);
   1178          POST_XEN_SYSCTL_WRITE(physinfo_00000008, total_pages);
   1179          POST_XEN_SYSCTL_WRITE(physinfo_00000008, free_pages);
   1180          POST_XEN_SYSCTL_WRITE(physinfo_00000008, scrub_pages);
   1181          POST_XEN_SYSCTL_WRITE(physinfo_00000008, hw_cap[8]);
   1182          POST_XEN_SYSCTL_WRITE(physinfo_00000008, capabilities);
   1183          break;
   1184       case 0x0000000a:
   1185          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, threads_per_core);
   1186          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cores_per_socket);
   1187          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_cpus);
   1188          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_cpu_id);
   1189          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_nodes);
   1190          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_node_id);
   1191          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cpu_khz);
   1192          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, total_pages);
   1193          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, free_pages);
   1194          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, scrub_pages);
   1195          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, outstanding_pages);
   1196          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, hw_cap[8]);
   1197          POST_XEN_SYSCTL_WRITE(physinfo_0000000a, capabilities);
   1198          break;
   1199       }
   1200       break;
   1201 
   1202    case VKI_XEN_SYSCTL_topologyinfo:
   1203       POST_XEN_SYSCTL_WRITE(topologyinfo, max_cpu_index);
   1204       if (sysctl->u.topologyinfo.cpu_to_core.p)
   1205          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_core.p,
   1206                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
   1207       if (sysctl->u.topologyinfo.cpu_to_socket.p)
   1208          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_socket.p,
   1209                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
   1210       if (sysctl->u.topologyinfo.cpu_to_node.p)
   1211          POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_node.p,
   1212                      sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index);
   1213       break;
   1214 
   1215    case VKI_XEN_SYSCTL_numainfo:
   1216       POST_XEN_SYSCTL_WRITE(numainfo, max_node_index);
   1217       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memsize.p,
   1218                      sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
   1219       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memfree.p,
   1220                      sizeof(uint64_t) * sysctl->u.numainfo.max_node_index);
   1221       POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_node_distance.p,
   1222                      sizeof(uint32_t) * sysctl->u.numainfo.max_node_index);
   1223       break;
   1224 
   1225    /* No outputs */
   1226    case VKI_XEN_SYSCTL_debug_keys:
   1227        break;
   1228    }
   1229 #undef POST_XEN_SYSCTL_WRITE
   1230 #undef __POST_XEN_SYSCTL_WRITE
   1231 }
   1232 
   1233 POST(domctl){
   1234    struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1;
   1235 
   1236    switch (domctl->interface_version) {
   1237    case 0x00000007:
   1238    case 0x00000008:
   1239    case 0x00000009:
   1240 	   break;
   1241    default:
   1242 	   return;
   1243    }
   1244 
   1245 #define __POST_XEN_DOMCTL_WRITE(_domctl, _union, _field)        \
   1246    POST_MEM_WRITE((Addr)&domctl->u._union._field,               \
   1247                   sizeof(domctl->u._union._field));
   1248 #define POST_XEN_DOMCTL_WRITE(_domctl, _field)          \
   1249    __POST_XEN_DOMCTL_WRITE(_domctl, _domctl, _field)
   1250 
   1251    switch (domctl->cmd) {
   1252    case VKI_XEN_DOMCTL_createdomain:
   1253    case VKI_XEN_DOMCTL_destroydomain:
   1254    case VKI_XEN_DOMCTL_pausedomain:
   1255    case VKI_XEN_DOMCTL_max_mem:
   1256    case VKI_XEN_DOMCTL_set_address_size:
   1257    case VKI_XEN_DOMCTL_settscinfo:
   1258    case VKI_XEN_DOMCTL_ioport_permission:
   1259    case VKI_XEN_DOMCTL_hypercall_init:
   1260    case VKI_XEN_DOMCTL_setvcpuaffinity:
   1261    case VKI_XEN_DOMCTL_setvcpucontext:
   1262    case VKI_XEN_DOMCTL_setnodeaffinity:
   1263    case VKI_XEN_DOMCTL_set_cpuid:
   1264    case VKI_XEN_DOMCTL_unpausedomain:
   1265    case VKI_XEN_DOMCTL_sethvmcontext:
   1266    case VKI_XEN_DOMCTL_debug_op:
   1267    case VKI_XEN_DOMCTL_set_max_evtchn:
   1268    case VKI_XEN_DOMCTL_cacheflush:
   1269    case VKI_XEN_DOMCTL_resumedomain:
   1270    case VKI_XEN_DOMCTL_set_access_required:
   1271       /* No output fields */
   1272       break;
   1273 
   1274    case VKI_XEN_DOMCTL_max_vcpus:
   1275       POST_XEN_DOMCTL_WRITE(max_vcpus, max);
   1276       break;
   1277 
   1278    case VKI_XEN_DOMCTL_get_address_size:
   1279       __POST_XEN_DOMCTL_WRITE(get_address_size, address_size, size);
   1280       break;
   1281 
   1282    case VKI_XEN_DOMCTL_gettscinfo:
   1283       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.tsc_mode);
   1284       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.gtsc_khz);
   1285       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.incarnation);
   1286       __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.elapsed_nsec);
   1287       break;
   1288 
   1289    case VKI_XEN_DOMCTL_getvcpuinfo:
   1290       POST_XEN_DOMCTL_WRITE(getvcpuinfo, online);
   1291       POST_XEN_DOMCTL_WRITE(getvcpuinfo, blocked);
   1292       POST_XEN_DOMCTL_WRITE(getvcpuinfo, running);
   1293       POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu_time);
   1294       POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu);
   1295       break;
   1296 
   1297    case VKI_XEN_DOMCTL_gethvmcontext:
   1298        /* Xen unconditionally writes size... */
   1299        __POST_XEN_DOMCTL_WRITE(gethvmcontext, hvmcontext, size);
   1300        /* ...but only writes to the buffer if it was non NULL */
   1301        if ( domctl->u.hvmcontext.buffer.p )
   1302            POST_MEM_WRITE((Addr)domctl->u.hvmcontext.buffer.p,
   1303                           sizeof(*domctl->u.hvmcontext.buffer.p)
   1304                           * domctl->u.hvmcontext.size);
   1305        break;
   1306 
   1307    case VKI_XEN_DOMCTL_gethvmcontext_partial:
   1308        switch (domctl->u.hvmcontext_partial.type) {
   1309        case VKI_HVM_SAVE_CODE(CPU):
   1310            if ( domctl->u.hvmcontext_partial.buffer.p )
   1311                 POST_MEM_WRITE((Addr)domctl->u.hvmcontext_partial.buffer.p,
   1312                    VKI_HVM_SAVE_LENGTH(CPU));
   1313            break;
   1314        }
   1315        break;
   1316 
   1317    case VKI_XEN_DOMCTL_scheduler_op:
   1318       if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_getinfo ) {
   1319          switch(domctl->u.scheduler_op.sched_id) {
   1320          case VKI_XEN_SCHEDULER_SEDF:
   1321             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.period);
   1322             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.slice);
   1323             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.latency);
   1324             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.extratime);
   1325             POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.weight);
   1326             break;
   1327          case VKI_XEN_SCHEDULER_CREDIT:
   1328             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.weight);
   1329             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.cap);
   1330             break;
   1331          case VKI_XEN_SCHEDULER_CREDIT2:
   1332             POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit2.weight);
   1333             break;
   1334          case VKI_XEN_SCHEDULER_ARINC653:
   1335             break;
   1336          }
   1337       }
   1338       break;
   1339 
   1340    case VKI_XEN_DOMCTL_getvcpuaffinity:
   1341       POST_MEM_WRITE((Addr)domctl->u.vcpuaffinity.cpumap.bitmap.p,
   1342                      domctl->u.vcpuaffinity.cpumap.nr_bits / 8);
   1343       break;
   1344 
   1345    case VKI_XEN_DOMCTL_getnodeaffinity:
   1346       POST_MEM_WRITE((Addr)domctl->u.nodeaffinity.nodemap.bitmap.p,
   1347                      domctl->u.nodeaffinity.nodemap.nr_bits / 8);
   1348       break;
   1349 
   1350    case VKI_XEN_DOMCTL_getdomaininfo:
   1351       switch (domctl->interface_version) {
   1352       case 0x00000007:
   1353 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, domain);
   1354 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, flags);
   1355 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, tot_pages);
   1356 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_pages);
   1357 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shr_pages);
   1358 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shared_info_frame);
   1359 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpu_time);
   1360 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, nr_online_vcpus);
   1361 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_vcpu_id);
   1362 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, ssidref);
   1363 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, handle);
   1364 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpupool);
   1365       break;
   1366       case 0x00000008:
   1367 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, domain);
   1368 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, flags);
   1369 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, tot_pages);
   1370 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_pages);
   1371 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shr_pages);
   1372 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, paged_pages);
   1373 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shared_info_frame);
   1374 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpu_time);
   1375 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, nr_online_vcpus);
   1376 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_vcpu_id);
   1377 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, ssidref);
   1378 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, handle);
   1379 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpupool);
   1380       break;
   1381       case 0x00000009:
   1382 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, domain);
   1383 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, flags);
   1384 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, tot_pages);
   1385 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_pages);
   1386 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, outstanding_pages);
   1387 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shr_pages);
   1388 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, paged_pages);
   1389 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shared_info_frame);
   1390 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpu_time);
   1391 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, nr_online_vcpus);
   1392 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_vcpu_id);
   1393 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, ssidref);
   1394 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, handle);
   1395 	 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpupool);
   1396       break;
   1397       }
   1398       break;
   1399    case VKI_XEN_DOMCTL_getvcpucontext:
   1400       __POST_XEN_DOMCTL_WRITE(getvcpucontext, vcpucontext, ctxt.p);
   1401       break;
   1402 
   1403    case VKI_XEN_DOMCTL_getpageframeinfo3:
   1404        POST_MEM_WRITE((Addr)domctl->u.getpageframeinfo3.array.p,
   1405                       domctl->u.getpageframeinfo3.num * sizeof(vki_xen_pfn_t));
   1406        break;
   1407 
   1408 
   1409    case VKI_XEN_DOMCTL_getvcpuextstate:
   1410       __POST_XEN_DOMCTL_WRITE(getvcpuextstate, vcpuextstate, xfeature_mask);
   1411       __POST_XEN_DOMCTL_WRITE(getvcpuextstate, vcpuextstate, size);
   1412       POST_MEM_WRITE((Addr)domctl->u.vcpuextstate.buffer.p,
   1413                      domctl->u.vcpuextstate.size);
   1414       break;
   1415 
   1416    case VKI_XEN_DOMCTL_shadow_op:
   1417        switch(domctl->u.shadow_op.op)
   1418        {
   1419        case VKI_XEN_DOMCTL_SHADOW_OP_OFF:
   1420            /* No outputs */
   1421            break;
   1422 
   1423        case VKI_XEN_DOMCTL_SHADOW_OP_CLEAN:
   1424        case VKI_XEN_DOMCTL_SHADOW_OP_PEEK:
   1425            POST_XEN_DOMCTL_WRITE(shadow_op, pages);
   1426            POST_XEN_DOMCTL_WRITE(shadow_op, stats.fault_count);
   1427            POST_XEN_DOMCTL_WRITE(shadow_op, stats.dirty_count);
   1428            if(domctl->u.shadow_op.dirty_bitmap.p)
   1429                POST_MEM_WRITE((Addr)domctl->u.shadow_op.dirty_bitmap.p,
   1430                               domctl->u.shadow_op.pages * sizeof(vki_uint8_t));
   1431            break;
   1432 
   1433        default:
   1434            break;
   1435        }
   1436        break;
   1437    case VKI_XEN_DOMCTL_mem_event_op:
   1438        POST_XEN_DOMCTL_WRITE(mem_event_op, port);
   1439 
   1440        break;
   1441    }
   1442 #undef POST_XEN_DOMCTL_WRITE
   1443 #undef __POST_XEN_DOMCTL_WRITE
   1444 }
   1445 
   1446 POST(hvm_op)
   1447 {
   1448    unsigned long op = ARG1;
   1449    void *arg = (void *)(unsigned long)ARG2;
   1450 
   1451 #define __POST_XEN_HVMOP_WRITE(_hvm_op, _type, _field)  \
   1452       POST_MEM_WRITE((Addr)&((_type*)arg)->_field,      \
   1453                      sizeof(((_type*)arg)->_field))
   1454 #define POST_XEN_HVMOP_WRITE(_hvm_op, _field) \
   1455       __POST_XEN_HVMOP_WRITE(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
   1456 
   1457    switch (op) {
   1458    case VKI_XEN_HVMOP_set_param:
   1459    case VKI_XEN_HVMOP_set_isa_irq_level:
   1460    case VKI_XEN_HVMOP_set_pci_link_route:
   1461    case VKI_XEN_HVMOP_set_mem_type:
   1462    case VKI_XEN_HVMOP_set_mem_access:
   1463    case VKI_XEN_HVMOP_inject_trap:
   1464       /* No output paramters */
   1465       break;
   1466 
   1467    case VKI_XEN_HVMOP_get_param:
   1468       __POST_XEN_HVMOP_WRITE(get_param, struct vki_xen_hvm_param, value);
   1469       break;
   1470 
   1471    case VKI_XEN_HVMOP_get_mem_access:
   1472       POST_XEN_HVMOP_WRITE(get_mem_access, hvmmem_access);
   1473       break;
   1474    }
   1475 #undef __POST_XEN_HVMOP_WRITE
   1476 #undef POST_XEN_HVMOP_WRITE
   1477 }
   1478 
   1479 POST(tmem_op)
   1480 {
   1481     struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1;
   1482 
   1483     switch(tmem->cmd) {
   1484 
   1485     case VKI_XEN_TMEM_control:
   1486 
   1487         switch(tmem->u.ctrl.subop) {
   1488             /* No outputs */
   1489             case VKI_XEN_TMEMC_save_begin:
   1490                 break;
   1491         }
   1492 
   1493         break;
   1494     }
   1495 }
   1496 
   1497 typedef
   1498    struct {
   1499       SyscallTableEntry entry;
   1500       int nr_args;
   1501    }
   1502    XenHypercallTableEntry;
   1503 
   1504 #define HYPX_(const, name, nr_args) \
   1505    [const] = { { vgSysWrap_xen_##name##_before, NULL }, nr_args }
   1506 #define HYPXY(const, name, nr_args)                     \
   1507    [const] = { { vgSysWrap_xen_##name##_before,         \
   1508                  vgSysWrap_xen_##name##_after },        \
   1509                nr_args }
   1510 
   1511 static XenHypercallTableEntry hypercall_table[] = {
   1512    //    __VKI_XEN_set_trap_table                                  // 0
   1513    //    __VKI_XEN_mmu_update                                      // 1
   1514    //    __VKI_XEN_set_gdt                                         // 2
   1515    //    __VKI_XEN_stack_switch                                    // 3
   1516    //    __VKI_XEN_set_callbacks                                   // 4
   1517 
   1518    //    __VKI_XEN_fpu_taskswitch                                  // 5
   1519    //    __VKI_XEN_sched_op_compat                                 // 6
   1520    //    __VKI_XEN_platform_op                                     // 7
   1521    //    __VKI_XEN_set_debugreg                                    // 8
   1522    //    __VKI_XEN_get_debugreg                                    // 9
   1523 
   1524    //    __VKI_XEN_update_descriptor                               // 10
   1525    //                                                                 // 11
   1526    HYPXY(__VKI_XEN_memory_op,               memory_op,         2), // 12
   1527    //    __VKI_XEN_multicall                                       // 13
   1528    //    __VKI_XEN_update_va_mapping                               // 14
   1529 
   1530    //    __VKI_XEN_set_timer_op                                    // 15
   1531    HYPXY(__VKI_XEN_event_channel_op_compat, evtchn_op_compat,  1), // 16
   1532    HYPXY(__VKI_XEN_xen_version,             xen_version,       2), // 17
   1533    //    __VKI_XEN_console_io                                      // 18
   1534    //    __VKI_XEN_physdev_op_compat                               // 19
   1535 
   1536    HYPXY(__VKI_XEN_grant_table_op,          grant_table_op,    3), // 20
   1537    //    __VKI_XEN_vm_assist                                       // 21
   1538    //    __VKI_XEN_update_va_mapping_otherdomain                   // 22
   1539    //    __VKI_XEN_iret,                    iret                   // 23
   1540    //    __VKI_XEN_vcpu_op,                 vcpu_op                // 24
   1541 
   1542    //    __VKI_XEN_set_segment_base                                // 25
   1543    HYPXY(__VKI_XEN_mmuext_op,               mmuext_op,         2), // 26
   1544    //    __VKI_XEN_xsm_op                                          // 27
   1545    //    __VKI_XEN_nmi_op                                          // 28
   1546    //    __VKI_XEN_sched_op                                        // 29
   1547 
   1548    //    __VKI_XEN_callback_op                                     // 30
   1549    //    __VKI_XEN_xenoprof_op                                     // 31
   1550    HYPXY(__VKI_XEN_event_channel_op,        evtchn_op,         2), // 32
   1551    //    __VKI_XEN_physdev_op                                      // 33
   1552    HYPXY(__VKI_XEN_hvm_op,                  hvm_op,            2), // 34
   1553 
   1554    HYPXY(__VKI_XEN_sysctl,                  sysctl,            1), // 35
   1555    HYPXY(__VKI_XEN_domctl,                  domctl,            1), // 36
   1556    //    __VKI_XEN_kexec_op                                        // 37
   1557    HYPXY(__VKI_XEN_tmem_op,                 tmem_op,           1), // 38
   1558 };
   1559 
   1560 static void bad_before ( ThreadId              tid,
   1561                          SyscallArgLayout*     layout,
   1562                          /*MOD*/SyscallArgs*   args,
   1563                          /*OUT*/SyscallStatus* status,
   1564                          /*OUT*/UWord*         flags )
   1565 {
   1566    VG_(dmsg)("WARNING: unhandled hypercall: %s\n",
   1567       VG_SYSNUM_STRING(args->sysno));
   1568    if (VG_(clo_verbosity) > 1) {
   1569       VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
   1570    }
   1571    VG_(dmsg)("You may be able to write your own handler.\n");
   1572    VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
   1573    VG_(dmsg)("Nevertheless we consider this a bug.  Please report\n");
   1574    VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n");
   1575    VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n");
   1576 
   1577    SET_STATUS_Failure(VKI_ENOSYS);
   1578 }
   1579 
   1580 static XenHypercallTableEntry bad_hyper =
   1581 { { bad_before, NULL }, 0 };
   1582 
   1583 static XenHypercallTableEntry* ML_(get_xen_hypercall_entry) ( UInt sysno )
   1584 {
   1585    XenHypercallTableEntry *ret = &bad_hyper;
   1586 
   1587    const UInt hypercall_table_size
   1588       = sizeof(hypercall_table) / sizeof(hypercall_table[0]);
   1589 
   1590    /* Is it in the contiguous initial section of the table? */
   1591    if (sysno < hypercall_table_size) {
   1592       XenHypercallTableEntry* ent = &hypercall_table[sysno];
   1593       if (ent->entry.before != NULL)
   1594          ret = ent;
   1595    }
   1596 
   1597    /* Can't find a wrapper */
   1598    return ret;
   1599 }
   1600 
   1601 DEFN_PRE_TEMPLATE(xen, hypercall)
   1602 {
   1603    XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
   1604 
   1605    /* Return number of arguments consumed */
   1606    ARG8 = ent->nr_args;
   1607 
   1608    vg_assert(ent);
   1609    vg_assert(ent->entry.before);
   1610    (ent->entry.before)( tid, layout, arrghs, status, flags );
   1611 
   1612 }
   1613 
   1614 DEFN_POST_TEMPLATE(xen, hypercall)
   1615 {
   1616    XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO);
   1617 
   1618    /* Return number of arguments consumed */
   1619    ARG8 = ent->nr_args;
   1620 
   1621    vg_assert(ent);
   1622    if (ent->entry.after)
   1623       (ent->entry.after)( tid, arrghs, status );
   1624 }
   1625 
   1626 #endif // defined(ENABLE_XEN)
   1627