syswrap-xen.c revision 1d528a761b257b2543f555fed8586f9c7a34f825
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_libcsetjmp.h" // to keep _threadstate.h happy 38#include "pub_core_threadstate.h" 39#include "pub_core_aspacemgr.h" 40#include "pub_core_debuginfo.h" // VG_(di_notify_*) 41#include "pub_core_transtab.h" // VG_(discard_translations) 42#include "pub_core_xarray.h" 43#include "pub_core_clientstate.h" 44#include "pub_core_debuglog.h" 45#include "pub_core_libcbase.h" 46#include "pub_core_libcassert.h" 47#include "pub_core_libcfile.h" 48#include "pub_core_libcprint.h" 49#include "pub_core_libcproc.h" 50#include "pub_core_libcsignal.h" 51#include "pub_core_mallocfree.h" 52#include "pub_core_tooliface.h" 53#include "pub_core_options.h" 54#include "pub_core_scheduler.h" 55#include "pub_core_signals.h" 56#include "pub_core_syscall.h" 57#include "pub_core_syswrap.h" 58#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)() 59 60#include "priv_types_n_macros.h" 61#include "priv_syswrap-generic.h" 62#include "priv_syswrap-xen.h" 63 64#include <inttypes.h> 65 66#define PRE(name) static DEFN_PRE_TEMPLATE(xen, name) 67#define POST(name) static DEFN_POST_TEMPLATE(xen, name) 68 69static void bad_subop ( ThreadId tid, 70 SyscallArgLayout* layout, 71 /*MOD*/SyscallArgs* args, 72 /*OUT*/SyscallStatus* status, 73 /*OUT*/UWord* flags, 74 const HChar* hypercall, 75 UWord subop) 76{ 77 VG_(dmsg)("WARNING: unhandled %s subop: %ld\n", 78 hypercall, subop); 79 if (VG_(clo_verbosity) > 1) { 80 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 81 } 82 VG_(dmsg)("You may be able to write your own handler.\n"); 83 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n"); 84 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n"); 85 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n"); 86 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n"); 87 88 SET_STATUS_Failure(VKI_ENOSYS); 89} 90 91PRE(memory_op) 92{ 93 PRINT("__HYPERVISOR_memory_op ( %ld, %lx )", ARG1, ARG2); 94 95 switch (ARG1) { 96 97 case VKI_XENMEM_maximum_ram_page: 98 /* No inputs */ 99 break; 100 101 case VKI_XENMEM_maximum_gpfn: 102 PRE_MEM_READ("XENMEM_maximum_gpfn domid", 103 (Addr)ARG2, sizeof(vki_xen_domid_t)); 104 break; 105 106 case VKI_XENMEM_machphys_mfn_list: { 107 struct vki_xen_machphys_mfn_list *arg = 108 (struct vki_xen_machphys_mfn_list *)ARG2; 109 PRE_MEM_READ("XENMEM_machphys_mfn_list max_extents", 110 (Addr)&arg->max_extents, sizeof(arg->max_extents)); 111 PRE_MEM_READ("XENMEM_machphys_mfn_list extent_start", 112 (Addr)&arg->extent_start, sizeof(arg->extent_start)); 113 break; 114 } 115 116 case VKI_XENMEM_set_memory_map: { 117 struct vki_xen_foreign_memory_map *arg = 118 (struct vki_xen_foreign_memory_map *)ARG2; 119 PRE_MEM_READ("XENMEM_set_memory_map domid", 120 (Addr)&arg->domid, sizeof(arg->domid)); 121 PRE_MEM_READ("XENMEM_set_memory_map map", 122 (Addr)&arg->map, sizeof(arg->map)); 123 break; 124 } 125 case VKI_XENMEM_increase_reservation: 126 case VKI_XENMEM_decrease_reservation: 127 case VKI_XENMEM_populate_physmap: 128 case VKI_XENMEM_claim_pages: { 129 struct xen_memory_reservation *memory_reservation = 130 (struct xen_memory_reservation *)ARG2; 131 const HChar *which; 132 133 switch (ARG1) { 134 case VKI_XENMEM_increase_reservation: 135 which = "XENMEM_increase_reservation"; 136 break; 137 case VKI_XENMEM_decrease_reservation: 138 which = "XENMEM_decrease_reservation"; 139 PRE_MEM_READ(which, 140 (Addr)memory_reservation->extent_start.p, 141 sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents); 142 break; 143 case VKI_XENMEM_populate_physmap: 144 which = "XENMEM_populate_physmap"; 145 PRE_MEM_READ(which, 146 (Addr)memory_reservation->extent_start.p, 147 sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents); 148 break; 149 case VKI_XENMEM_claim_pages: 150 which = "XENMEM_claim_pages"; 151 break; 152 default: 153 which = "XENMEM_unknown"; 154 break; 155 } 156 157 PRE_MEM_READ(which, 158 (Addr)&memory_reservation->extent_start, 159 sizeof(memory_reservation->extent_start)); 160 PRE_MEM_READ(which, 161 (Addr)&memory_reservation->nr_extents, 162 sizeof(memory_reservation->nr_extents)); 163 PRE_MEM_READ(which, 164 (Addr)&memory_reservation->extent_order, 165 sizeof(memory_reservation->extent_order)); 166 PRE_MEM_READ(which, 167 (Addr)&memory_reservation->mem_flags, 168 sizeof(memory_reservation->mem_flags)); 169 PRE_MEM_READ(which, 170 (Addr)&memory_reservation->domid, 171 sizeof(memory_reservation->domid)); 172 break; 173 } 174 175 case VKI_XENMEM_get_sharing_freed_pages: 176 case VKI_XENMEM_get_sharing_shared_pages: 177 break; 178 179 default: 180 bad_subop(tid, layout, arrghs, status, flags, 181 "__HYPERVISOR_memory_op", ARG1); 182 break; 183 } 184} 185 186PRE(mmuext_op) 187{ 188 struct vki_xen_mmuext_op *ops = (struct vki_xen_mmuext_op *)ARG1; 189 unsigned int i, nr = ARG2; 190 191 for (i=0; i<nr; i++) { 192 struct vki_xen_mmuext_op *op = ops + i; 193 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP cmd", 194 (Addr)&op->cmd, sizeof(op->cmd)); 195 switch(op->cmd) { 196 case VKI_XEN_MMUEXT_PIN_L1_TABLE: 197 case VKI_XEN_MMUEXT_PIN_L2_TABLE: 198 case VKI_XEN_MMUEXT_PIN_L3_TABLE: 199 case VKI_XEN_MMUEXT_PIN_L4_TABLE: 200 case VKI_XEN_MMUEXT_UNPIN_TABLE: 201 case VKI_XEN_MMUEXT_NEW_BASEPTR: 202 case VKI_XEN_MMUEXT_CLEAR_PAGE: 203 case VKI_XEN_MMUEXT_COPY_PAGE: 204 case VKI_XEN_MMUEXT_MARK_SUPER: 205 case VKI_XEN_MMUEXT_UNMARK_SUPER: 206 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn", 207 (Addr)&op->arg1.mfn, 208 sizeof(op->arg1.mfn)); 209 break; 210 211 case VKI_XEN_MMUEXT_INVLPG_LOCAL: 212 case VKI_XEN_MMUEXT_INVLPG_ALL: 213 case VKI_XEN_MMUEXT_SET_LDT: 214 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg1.mfn", 215 (Addr)&op->arg1.linear_addr, 216 sizeof(op->arg1.linear_addr)); 217 break; 218 219 case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL: 220 case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI: 221 case VKI_XEN_MMUEXT_INVLPG_MULTI: 222 case VKI_XEN_MMUEXT_TLB_FLUSH_ALL: 223 case VKI_XEN_MMUEXT_FLUSH_CACHE: 224 case VKI_XEN_MMUEXT_NEW_USER_BASEPTR: 225 case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL: 226 /* None */ 227 break; 228 } 229 230 switch(op->cmd) { 231 case VKI_XEN_MMUEXT_SET_LDT: 232 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.nr_ents", 233 (Addr)&op->arg2.nr_ents, 234 sizeof(op->arg2.nr_ents)); 235 break; 236 237 case VKI_XEN_MMUEXT_TLB_FLUSH_MULTI: 238 case VKI_XEN_MMUEXT_INVLPG_MULTI: 239 /* How many??? */ 240 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.vcpumask", 241 (Addr)&op->arg2.vcpumask, 242 sizeof(op->arg2.vcpumask)); 243 break; 244 245 case VKI_XEN_MMUEXT_COPY_PAGE: 246 PRE_MEM_READ("__HYPERVISOR_MMUEXT_OP arg2.src_mfn", 247 (Addr)&op->arg2.src_mfn, 248 sizeof(op->arg2.src_mfn)); 249 break; 250 251 case VKI_XEN_MMUEXT_PIN_L1_TABLE: 252 case VKI_XEN_MMUEXT_PIN_L2_TABLE: 253 case VKI_XEN_MMUEXT_PIN_L3_TABLE: 254 case VKI_XEN_MMUEXT_PIN_L4_TABLE: 255 case VKI_XEN_MMUEXT_UNPIN_TABLE: 256 case VKI_XEN_MMUEXT_NEW_BASEPTR: 257 case VKI_XEN_MMUEXT_TLB_FLUSH_LOCAL: 258 case VKI_XEN_MMUEXT_INVLPG_LOCAL: 259 case VKI_XEN_MMUEXT_TLB_FLUSH_ALL: 260 case VKI_XEN_MMUEXT_INVLPG_ALL: 261 case VKI_XEN_MMUEXT_FLUSH_CACHE: 262 case VKI_XEN_MMUEXT_NEW_USER_BASEPTR: 263 case VKI_XEN_MMUEXT_CLEAR_PAGE: 264 case VKI_XEN_MMUEXT_FLUSH_CACHE_GLOBAL: 265 case VKI_XEN_MMUEXT_MARK_SUPER: 266 case VKI_XEN_MMUEXT_UNMARK_SUPER: 267 /* None */ 268 break; 269 } 270 } 271} 272 273static void pre_evtchn_op(ThreadId tid, 274 SyscallArgLayout* layout, 275 /*MOD*/SyscallArgs* arrghs, 276 /*OUT*/SyscallStatus* status, 277 /*OUT*/UWord* flags, 278 __vki_u32 cmd, void *arg, int compat) 279{ 280 PRINT("__HYPERVISOR_event_channel_op%s ( %d, %p )", 281 compat ? "_compat" : "", cmd, arg); 282 283 switch (cmd) { 284 case VKI_XEN_EVTCHNOP_alloc_unbound: { 285 struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg; 286 PRE_MEM_READ("EVTCHNOP_alloc_unbound dom", 287 (Addr)&alloc_unbound->dom, sizeof(alloc_unbound->dom)); 288 PRE_MEM_READ("EVTCHNOP_alloc_unbound remote_dom", 289 (Addr)&alloc_unbound->remote_dom, 290 sizeof(alloc_unbound->remote_dom)); 291 break; 292 } 293 default: 294 if ( compat ) 295 bad_subop(tid, layout, arrghs, status, flags, 296 "__HYPERVISOR_event_channel_op_compat", cmd); 297 else 298 bad_subop(tid, layout, arrghs, status, flags, 299 "__HYPERVISOR_event_channel_op", cmd); 300 break; 301 } 302} 303 304PRE(evtchn_op) 305{ 306 pre_evtchn_op(tid, layout, arrghs, status, flags, 307 ARG1, (void *)ARG2, 0); 308} 309 310PRE(evtchn_op_compat) 311{ 312 struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1; 313 PRE_MEM_READ("__HYPERVISOR_event_channel_op_compat", 314 ARG1, sizeof(*evtchn)); 315 316 pre_evtchn_op(tid, layout, arrghs, status, flags, 317 evtchn->cmd, &evtchn->u, 1); 318} 319 320PRE(xen_version) 321{ 322 PRINT("__HYPERVISOR_xen_version ( %ld, %lx )", ARG1, ARG2); 323 324 switch (ARG1) { 325 case VKI_XENVER_version: 326 case VKI_XENVER_extraversion: 327 case VKI_XENVER_compile_info: 328 case VKI_XENVER_capabilities: 329 case VKI_XENVER_changeset: 330 case VKI_XENVER_platform_parameters: 331 case VKI_XENVER_get_features: 332 case VKI_XENVER_pagesize: 333 case VKI_XENVER_guest_handle: 334 case VKI_XENVER_commandline: 335 /* No inputs */ 336 break; 337 338 default: 339 bad_subop(tid, layout, arrghs, status, flags, 340 "__HYPERVISOR_xen_version", ARG1); 341 break; 342 } 343} 344 345PRE(grant_table_op) 346{ 347 PRINT("__HYPERVISOR_grant_table_op ( %ld, 0x%lx, %ld )", ARG1, ARG2, ARG3); 348 switch (ARG1) { 349 case VKI_XEN_GNTTABOP_setup_table: { 350 struct vki_xen_gnttab_setup_table *gst = 351 (struct vki_xen_gnttab_setup_table*)ARG2; 352 PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table dom", 353 (Addr)&gst->dom, sizeof(gst->dom)); 354 PRE_MEM_READ("VKI_XEN_GNTTABOP_setup_table nr_frames", 355 (Addr)&gst->nr_frames, sizeof(gst->nr_frames)); 356 break; 357 } 358 default: 359 bad_subop(tid, layout, arrghs, status, flags, 360 "__HYPERVISOR_grant_table_op", ARG1); 361 break; 362 } 363} 364 365PRE(sysctl) { 366 struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1; 367 368 PRINT("__HYPERVISOR_sysctl ( %d )", sysctl->cmd); 369 370 /* 371 * Common part of xen_sysctl: 372 * uint32_t cmd; 373 * uint32_t interface_version; 374 */ 375 PRE_MEM_READ("__HYPERVISOR_sysctl", ARG1, 376 sizeof(vki_uint32_t) + sizeof(vki_uint32_t)); 377 378 if (!sysctl) 379 return; 380 381 switch (sysctl->interface_version) 382 { 383 case 0x00000008: 384 case 0x00000009: 385 case 0x0000000a: 386 break; 387 default: 388 VG_(dmsg)("WARNING: sysctl version %"PRIx32" not supported\n", 389 sysctl->interface_version); 390 if (VG_(clo_verbosity) > 1) { 391 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 392 } 393 VG_(dmsg)("You may be able to write your own handler.\n"); 394 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n"); 395 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n"); 396 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n"); 397 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n"); 398 399 SET_STATUS_Failure(VKI_EINVAL); 400 return; 401 } 402 403#define __PRE_XEN_SYSCTL_READ(_sysctl, _union, _field) \ 404 PRE_MEM_READ("XEN_SYSCTL_" #_sysctl " u." #_union "." #_field, \ 405 (Addr)&sysctl->u._union._field, \ 406 sizeof(sysctl->u._union._field)) 407#define PRE_XEN_SYSCTL_READ(_sysctl, _field) \ 408 __PRE_XEN_SYSCTL_READ(_sysctl, _sysctl, _field) 409 410 switch (sysctl->cmd) { 411 case VKI_XEN_SYSCTL_getdomaininfolist: 412 switch (sysctl->interface_version) 413 { 414 case 0x00000008: 415 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, first_domain); 416 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, max_domains); 417 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000008, buffer); 418 break; 419 case 0x00000009: 420 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, first_domain); 421 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, max_domains); 422 PRE_XEN_SYSCTL_READ(getdomaininfolist_00000009, buffer); 423 break; 424 case 0x0000000a: 425 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, first_domain); 426 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, max_domains); 427 PRE_XEN_SYSCTL_READ(getdomaininfolist_0000000a, buffer); 428 break; 429 default: 430 VG_(dmsg)("WARNING: XEN_SYSCTL_getdomaininfolist for sysctl version " 431 "%"PRIx32" not implemented yet\n", 432 sysctl->interface_version); 433 SET_STATUS_Failure(VKI_EINVAL); 434 return; 435 } 436 break; 437 438 case VKI_XEN_SYSCTL_sched_id: 439 /* No inputs */ 440 break; 441 442 case VKI_XEN_SYSCTL_cpupool_op: 443 PRE_XEN_SYSCTL_READ(cpupool_op, op); 444 445 switch(sysctl->u.cpupool_op.op) { 446 case VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE: 447 case VKI_XEN_SYSCTL_CPUPOOL_OP_DESTROY: 448 case VKI_XEN_SYSCTL_CPUPOOL_OP_INFO: 449 case VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU: 450 case VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU: 451 case VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN: 452 PRE_XEN_SYSCTL_READ(cpupool_op, cpupool_id); 453 } 454 455 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE) 456 PRE_XEN_SYSCTL_READ(cpupool_op, sched_id); 457 458 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN) 459 PRE_XEN_SYSCTL_READ(cpupool_op, domid); 460 461 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_ADDCPU || 462 sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_RMCPU) 463 PRE_XEN_SYSCTL_READ(cpupool_op, cpu); 464 465 break; 466 467 case VKI_XEN_SYSCTL_physinfo: 468 /* No input params */ 469 break; 470 471 case VKI_XEN_SYSCTL_topologyinfo: 472 PRE_XEN_SYSCTL_READ(topologyinfo, max_cpu_index); 473 PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_core); 474 PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_socket); 475 PRE_XEN_SYSCTL_READ(topologyinfo, cpu_to_node); 476 break; 477 478 case VKI_XEN_SYSCTL_numainfo: 479 PRE_XEN_SYSCTL_READ(numainfo, max_node_index); 480 PRE_XEN_SYSCTL_READ(numainfo, node_to_memsize); 481 PRE_XEN_SYSCTL_READ(numainfo, node_to_memfree); 482 PRE_XEN_SYSCTL_READ(numainfo, node_to_node_distance); 483 break; 484 485 default: 486 bad_subop(tid, layout, arrghs, status, flags, 487 "__HYPERVISOR_sysctl", sysctl->cmd); 488 break; 489 } 490#undef PRE_XEN_SYSCTL_READ 491#undef __PRE_XEN_SYSCTL_READ 492} 493 494PRE(domctl) 495{ 496 struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1; 497 498 PRINT("__HYPERVISOR_domctl ( %d ) on dom%d", domctl->cmd, domctl->domain); 499 500 /* 501 * Common part of xen_domctl: 502 * vki_uint32_t cmd; 503 * vki_uint32_t interface_version; 504 * vki_xen_domid_t domain; 505 */ 506 PRE_MEM_READ("__HYPERVISOR_domctl", ARG1, 507 sizeof(vki_uint32_t) + sizeof(vki_uint32_t) 508 + sizeof(vki_xen_domid_t)); 509 510 if (!domctl) 511 return; 512 513 switch (domctl->interface_version) 514 { 515 case 0x00000007: 516 case 0x00000008: 517 case 0x00000009: 518 break; 519 default: 520 VG_(dmsg)("WARNING: domctl version %"PRIx32" not supported\n", 521 domctl->interface_version); 522 if (VG_(clo_verbosity) > 1) { 523 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 524 } 525 VG_(dmsg)("You may be able to write your own handler.\n"); 526 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n"); 527 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n"); 528 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n"); 529 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n"); 530 531 SET_STATUS_Failure(VKI_EINVAL); 532 return; 533 } 534 535#define __PRE_XEN_DOMCTL_READ(_domctl, _union, _field) \ 536 PRE_MEM_READ("XEN_DOMCTL_" #_domctl " u." #_union "." #_field, \ 537 (Addr)&domctl->u._union._field, \ 538 sizeof(domctl->u._union._field)) 539#define PRE_XEN_DOMCTL_READ(_domctl, _field) \ 540 __PRE_XEN_DOMCTL_READ(_domctl, _domctl, _field) 541 542 switch (domctl->cmd) { 543 case VKI_XEN_DOMCTL_destroydomain: 544 case VKI_XEN_DOMCTL_pausedomain: 545 case VKI_XEN_DOMCTL_max_vcpus: 546 case VKI_XEN_DOMCTL_get_address_size: 547 case VKI_XEN_DOMCTL_gettscinfo: 548 case VKI_XEN_DOMCTL_getdomaininfo: 549 case VKI_XEN_DOMCTL_unpausedomain: 550 /* No input fields. */ 551 break; 552 553 case VKI_XEN_DOMCTL_createdomain: 554 PRE_XEN_DOMCTL_READ(createdomain, ssidref); 555 PRE_XEN_DOMCTL_READ(createdomain, handle); 556 PRE_XEN_DOMCTL_READ(createdomain, flags); 557 break; 558 559 case VKI_XEN_DOMCTL_max_mem: 560 PRE_XEN_DOMCTL_READ(max_mem, max_memkb); 561 break; 562 563 case VKI_XEN_DOMCTL_set_address_size: 564 __PRE_XEN_DOMCTL_READ(set_address_size, address_size, size); 565 break; 566 567 case VKI_XEN_DOMCTL_settscinfo: 568 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.tsc_mode); 569 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.gtsc_khz); 570 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.incarnation); 571 __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.elapsed_nsec); 572 break; 573 574 case VKI_XEN_DOMCTL_hypercall_init: 575 PRE_XEN_DOMCTL_READ(hypercall_init, gmfn); 576 break; 577 578 case VKI_XEN_DOMCTL_getvcpuinfo: 579 PRE_XEN_DOMCTL_READ(getvcpuinfo, vcpu); 580 break; 581 582 case VKI_XEN_DOMCTL_scheduler_op: 583 PRE_XEN_DOMCTL_READ(scheduler_op, sched_id); 584 PRE_XEN_DOMCTL_READ(scheduler_op, cmd); 585 if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_putinfo ) { 586 switch(domctl->u.scheduler_op.sched_id) { 587 case VKI_XEN_SCHEDULER_SEDF: 588 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.period); 589 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.slice); 590 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.latency); 591 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.extratime); 592 PRE_XEN_DOMCTL_READ(scheduler_op, u.sedf.weight); 593 break; 594 case VKI_XEN_SCHEDULER_CREDIT: 595 PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.weight); 596 PRE_XEN_DOMCTL_READ(scheduler_op, u.credit.cap); 597 break; 598 case VKI_XEN_SCHEDULER_CREDIT2: 599 PRE_XEN_DOMCTL_READ(scheduler_op, u.credit2.weight); 600 break; 601 case VKI_XEN_SCHEDULER_ARINC653: 602 break; 603 } 604 } 605 break; 606 607 case VKI_XEN_DOMCTL_getvcpuaffinity: 608 __PRE_XEN_DOMCTL_READ(getvcpuaffinity, vcpuaffinity, vcpu); 609 break; 610 611 case VKI_XEN_DOMCTL_setvcpuaffinity: 612 __PRE_XEN_DOMCTL_READ(setvcpuaffinity, vcpuaffinity, vcpu); 613 PRE_MEM_READ("XEN_DOMCTL_setvcpuaffinity u.vcpuaffinity.cpumap.bitmap", 614 (Addr)domctl->u.vcpuaffinity.cpumap.bitmap.p, 615 domctl->u.vcpuaffinity.cpumap.nr_bits / 8); 616 break; 617 618 case VKI_XEN_DOMCTL_getnodeaffinity: 619 __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits); 620 break; 621 case VKI_XEN_DOMCTL_setnodeaffinity: 622 __PRE_XEN_DOMCTL_READ(nodeaffinity, nodeaffinity, nodemap.nr_bits); 623 PRE_MEM_READ("XEN_DOMCTL_setnodeaffinity u.nodeaffinity.cpumap.bitmap", 624 (Addr)domctl->u.nodeaffinity.nodemap.bitmap.p, 625 domctl->u.nodeaffinity.nodemap.nr_bits / 8); 626 break; 627 628 case VKI_XEN_DOMCTL_getvcpucontext: 629 __PRE_XEN_DOMCTL_READ(getvcpucontext, vcpucontext, vcpu); 630 break; 631 632 case VKI_XEN_DOMCTL_setvcpucontext: 633 __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, vcpu); 634 __PRE_XEN_DOMCTL_READ(setvcpucontext, vcpucontext, ctxt.p); 635 break; 636 637 case VKI_XEN_DOMCTL_set_cpuid: 638 PRE_MEM_READ("XEN_DOMCTL_set_cpuid u.cpuid", 639 (Addr)&domctl->u.cpuid, sizeof(domctl->u.cpuid)); 640 break; 641 642 case VKI_XEN_DOMCTL_getvcpuextstate: 643 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, vcpu); 644 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, xfeature_mask); 645 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, size); 646 __PRE_XEN_DOMCTL_READ(getvcpuextstate, vcpuextstate, buffer); 647 break; 648 649 default: 650 bad_subop(tid, layout, arrghs, status, flags, 651 "__HYPERVISOR_domctl", domctl->cmd); 652 break; 653 } 654#undef PRE_XEN_DOMCTL_READ 655#undef __PRE_XEN_DOMCTL_READ 656} 657 658PRE(hvm_op) 659{ 660 unsigned long op = ARG1; 661 void *arg = (void *)(unsigned long)ARG2; 662 663 PRINT("__HYPERVISOR_hvm_op ( %ld, %p )", op, arg); 664 665#define __PRE_XEN_HVMOP_READ(_hvm_op, _type, _field) \ 666 PRE_MEM_READ("XEN_HVMOP_" # _hvm_op " " #_field, \ 667 (Addr)&((_type*)arg)->_field, \ 668 sizeof(((_type*)arg)->_field)) 669#define PRE_XEN_HVMOP_READ(_hvm_op, _field) \ 670 __PRE_XEN_HVMOP_READ(_hvm_op, "xen_hvm_" # _hvm_op "_t", _field) 671 672 switch (op) { 673 case VKI_XEN_HVMOP_set_param: 674 __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, domid); 675 __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, index); 676 __PRE_XEN_HVMOP_READ(set_param, struct vki_xen_hvm_param, value); 677 break; 678 679 case VKI_XEN_HVMOP_get_param: 680 __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, domid); 681 __PRE_XEN_HVMOP_READ(get_param, struct vki_xen_hvm_param, index); 682 break; 683 684 default: 685 bad_subop(tid, layout, arrghs, status, flags, 686 "__HYPERVISOR_hvm_op", op); 687 break; 688 } 689#undef __PRE_XEN_HVMOP_READ 690#undef PRE_XEN_HVMOP_READ 691} 692 693PRE(tmem_op) 694{ 695 struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1; 696 697 PRINT("__HYPERVISOR_tmem_op ( %d )", tmem->cmd); 698 699 /* Common part for xen_tmem_op: 700 * vki_uint32_t cmd; 701 */ 702 PRE_MEM_READ("__HYPERVISOR_tmem_op cmd", ARG1, sizeof(vki_uint32_t)); 703 704 705#define __PRE_XEN_TMEMOP_READ(_tmem, _union, _field) \ 706 PRE_MEM_READ("XEN_tmem_op_" #_tmem " u." #_union "." #_field, \ 707 (Addr)&tmem->u._union._field, \ 708 sizeof(tmem->u._union._field)) 709#define PRE_XEN_TMEMOP_READ(_tmem, _field) \ 710 __PRE_XEN_TMEMOP_READ(_tmem, _tmem, _field) 711 712 switch(tmem->cmd) { 713 714 case VKI_XEN_TMEM_control: 715 716 /* Common part for control hypercall: 717 * vki_int32_t pool_id; 718 * vki_uint32_t subop; 719 */ 720 PRE_MEM_READ("__HYPERVISOR_tmem_op pool_id", 721 (Addr)&tmem->pool_id, sizeof(&tmem->pool_id)); 722 PRE_XEN_TMEMOP_READ(ctrl, subop); 723 724 switch (tmem->u.ctrl.subop) { 725 726 case VKI_XEN_TMEMC_save_begin: 727 PRE_XEN_TMEMOP_READ(ctrl, cli_id); 728 PRE_XEN_TMEMOP_READ(ctrl, arg1); 729 PRE_XEN_TMEMOP_READ(ctrl, buf); 730 break; 731 732 default: 733 bad_subop(tid, layout, arrghs, status, flags, 734 "__HYPERVISOR_tmem_op_control", tmem->u.ctrl.subop); 735 } 736 737 break; 738 739 default: 740 bad_subop(tid, layout, arrghs, status, flags, 741 "__HYPERVISOR_tmem_op", ARG1); 742 } 743 744#undef PRE_XEN_TMEMOP_READ 745#undef __PRE_XEN_TMEMOP_READ 746} 747 748POST(memory_op) 749{ 750 switch (ARG1) { 751 case VKI_XENMEM_maximum_ram_page: 752 case VKI_XENMEM_set_memory_map: 753 case VKI_XENMEM_decrease_reservation: 754 case VKI_XENMEM_claim_pages: 755 case VKI_XENMEM_maximum_gpfn: 756 /* No outputs */ 757 break; 758 case VKI_XENMEM_increase_reservation: 759 case VKI_XENMEM_populate_physmap: { 760 struct xen_memory_reservation *memory_reservation = 761 (struct xen_memory_reservation *)ARG2; 762 763 POST_MEM_WRITE((Addr)memory_reservation->extent_start.p, 764 sizeof(vki_xen_pfn_t) * memory_reservation->nr_extents); 765 break; 766 } 767 768 case VKI_XENMEM_machphys_mfn_list: { 769 struct vki_xen_machphys_mfn_list *arg = 770 (struct vki_xen_machphys_mfn_list *)ARG2; 771 POST_MEM_WRITE((Addr)&arg->nr_extents, sizeof(arg->nr_extents)); 772 POST_MEM_WRITE((Addr)arg->extent_start.p, 773 sizeof(vki_xen_pfn_t) * arg->nr_extents); 774 break; 775 } 776 777 case VKI_XENMEM_get_sharing_freed_pages: 778 case VKI_XENMEM_get_sharing_shared_pages: 779 /* No outputs */ 780 break; 781 } 782} 783 784POST(mmuext_op) 785{ 786 unsigned int *pdone = (unsigned int *)ARG3; 787 /* simplistic */ 788 POST_MEM_WRITE((Addr)pdone, sizeof(*pdone)); 789} 790 791static void post_evtchn_op(ThreadId tid, __vki_u32 cmd, void *arg, int compat) 792{ 793 switch (cmd) { 794 case VKI_XEN_EVTCHNOP_alloc_unbound: { 795 struct vki_xen_evtchn_alloc_unbound *alloc_unbound = arg; 796 POST_MEM_WRITE((Addr)&alloc_unbound->port, sizeof(alloc_unbound->port)); 797 break; 798 } 799 } 800} 801 802POST(evtchn_op) 803{ 804 post_evtchn_op(tid, ARG1, (void *)ARG2, 0); 805} 806 807POST(evtchn_op_compat) 808{ 809 struct vki_xen_evtchn_op *evtchn = (struct vki_xen_evtchn_op *)ARG1; 810 post_evtchn_op(tid, evtchn->cmd, &evtchn->u, 1); 811} 812 813POST(xen_version) 814{ 815 switch (ARG1) { 816 case VKI_XENVER_version: 817 /* No outputs */ 818 break; 819 case VKI_XENVER_extraversion: 820 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_extraversion_t)); 821 break; 822 case VKI_XENVER_compile_info: 823 POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_compile_info)); 824 break; 825 case VKI_XENVER_capabilities: 826 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_capabilities_info_t)); 827 break; 828 case VKI_XENVER_changeset: 829 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_changeset_info_t)); 830 break; 831 case VKI_XENVER_platform_parameters: 832 POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_platform_parameters)); 833 break; 834 case VKI_XENVER_get_features: 835 POST_MEM_WRITE((Addr)ARG2, sizeof(struct vki_xen_feature_info)); 836 break; 837 case VKI_XENVER_pagesize: 838 /* No outputs */ 839 break; 840 case VKI_XENVER_guest_handle: 841 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_domain_handle_t)); 842 break; 843 case VKI_XENVER_commandline: 844 POST_MEM_WRITE((Addr)ARG2, sizeof(vki_xen_commandline_t)); 845 break; 846 } 847} 848 849POST(grant_table_op) 850{ 851 switch (ARG1) { 852 case VKI_XEN_GNTTABOP_setup_table: { 853 struct vki_xen_gnttab_setup_table *gst = 854 (struct vki_xen_gnttab_setup_table*)ARG2; 855 PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table", 856 (Addr)&gst->status, sizeof(gst->status)); 857 PRE_MEM_WRITE("VKI_XEN_GNTTABOP_setup_table", 858 (Addr)gst->frame_list.p, 859 sizeof(*gst->frame_list.p) & gst->nr_frames); 860 break; 861 } 862 } 863} 864 865POST(sysctl) 866{ 867 struct vki_xen_sysctl *sysctl = (struct vki_xen_sysctl *)ARG1; 868 869 switch (sysctl->interface_version) 870 { 871 case 0x00000008: 872 case 0x00000009: 873 case 0x0000000a: 874 break; 875 default: 876 return; 877 } 878 879#define __POST_XEN_SYSCTL_WRITE(_sysctl, _union, _field) \ 880 POST_MEM_WRITE((Addr)&sysctl->u._union._field, \ 881 sizeof(sysctl->u._union._field)) 882#define POST_XEN_SYSCTL_WRITE(_sysctl, _field) \ 883 __POST_XEN_SYSCTL_WRITE(_sysctl, _sysctl, _field) 884 885 switch (sysctl->cmd) { 886 case VKI_XEN_SYSCTL_getdomaininfolist: 887 switch (sysctl->interface_version) 888 { 889 case 0x00000008: 890 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000008, num_domains); 891 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000008.buffer.p, 892 sizeof(*sysctl->u.getdomaininfolist_00000008.buffer.p) 893 * sysctl->u.getdomaininfolist_00000008.num_domains); 894 break; 895 case 0x00000009: 896 POST_XEN_SYSCTL_WRITE(getdomaininfolist_00000009, num_domains); 897 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_00000009.buffer.p, 898 sizeof(*sysctl->u.getdomaininfolist_00000009.buffer.p) 899 * sysctl->u.getdomaininfolist_00000009.num_domains); 900 break; 901 case 0x0000000a: 902 POST_XEN_SYSCTL_WRITE(getdomaininfolist_0000000a, num_domains); 903 POST_MEM_WRITE((Addr)sysctl->u.getdomaininfolist_0000000a.buffer.p, 904 sizeof(*sysctl->u.getdomaininfolist_0000000a.buffer.p) 905 * sysctl->u.getdomaininfolist_0000000a.num_domains); 906 break; 907 } 908 break; 909 910 case VKI_XEN_SYSCTL_sched_id: 911 POST_XEN_SYSCTL_WRITE(sched_id, sched_id); 912 break; 913 914 case VKI_XEN_SYSCTL_cpupool_op: 915 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_CREATE || 916 sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO) 917 POST_XEN_SYSCTL_WRITE(cpupool_op, cpupool_id); 918 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO) { 919 POST_XEN_SYSCTL_WRITE(cpupool_op, sched_id); 920 POST_XEN_SYSCTL_WRITE(cpupool_op, n_dom); 921 } 922 if (sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_INFO || 923 sysctl->u.cpupool_op.op == VKI_XEN_SYSCTL_CPUPOOL_OP_FREEINFO) 924 POST_XEN_SYSCTL_WRITE(cpupool_op, cpumap); 925 break; 926 927 case VKI_XEN_SYSCTL_physinfo: 928 switch (sysctl->interface_version) 929 { 930 case 0x00000008: 931 case 0x00000009: /* Unchanged from version 8 */ 932 POST_XEN_SYSCTL_WRITE(physinfo_00000008, threads_per_core); 933 POST_XEN_SYSCTL_WRITE(physinfo_00000008, cores_per_socket); 934 POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_cpus); 935 POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_cpu_id); 936 POST_XEN_SYSCTL_WRITE(physinfo_00000008, nr_nodes); 937 POST_XEN_SYSCTL_WRITE(physinfo_00000008, max_node_id); 938 POST_XEN_SYSCTL_WRITE(physinfo_00000008, cpu_khz); 939 POST_XEN_SYSCTL_WRITE(physinfo_00000008, total_pages); 940 POST_XEN_SYSCTL_WRITE(physinfo_00000008, free_pages); 941 POST_XEN_SYSCTL_WRITE(physinfo_00000008, scrub_pages); 942 POST_XEN_SYSCTL_WRITE(physinfo_00000008, hw_cap[8]); 943 POST_XEN_SYSCTL_WRITE(physinfo_00000008, capabilities); 944 break; 945 case 0x0000000a: 946 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, threads_per_core); 947 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cores_per_socket); 948 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_cpus); 949 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_cpu_id); 950 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, nr_nodes); 951 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, max_node_id); 952 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, cpu_khz); 953 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, total_pages); 954 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, free_pages); 955 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, scrub_pages); 956 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, outstanding_pages); 957 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, hw_cap[8]); 958 POST_XEN_SYSCTL_WRITE(physinfo_0000000a, capabilities); 959 break; 960 } 961 break; 962 963 case VKI_XEN_SYSCTL_topologyinfo: 964 POST_XEN_SYSCTL_WRITE(topologyinfo, max_cpu_index); 965 if (sysctl->u.topologyinfo.cpu_to_core.p) 966 POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_core.p, 967 sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index); 968 if (sysctl->u.topologyinfo.cpu_to_socket.p) 969 POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_socket.p, 970 sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index); 971 if (sysctl->u.topologyinfo.cpu_to_node.p) 972 POST_MEM_WRITE((Addr)sysctl->u.topologyinfo.cpu_to_node.p, 973 sizeof(uint32_t) * sysctl->u.topologyinfo.max_cpu_index); 974 break; 975 976 case VKI_XEN_SYSCTL_numainfo: 977 POST_XEN_SYSCTL_WRITE(numainfo, max_node_index); 978 POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memsize.p, 979 sizeof(uint64_t) * sysctl->u.numainfo.max_node_index); 980 POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_memfree.p, 981 sizeof(uint64_t) * sysctl->u.numainfo.max_node_index); 982 POST_MEM_WRITE((Addr)sysctl->u.numainfo.node_to_node_distance.p, 983 sizeof(uint32_t) * sysctl->u.numainfo.max_node_index); 984 break; 985 } 986#undef POST_XEN_SYSCTL_WRITE 987#undef __POST_XEN_SYSCTL_WRITE 988} 989 990POST(domctl){ 991 struct vki_xen_domctl *domctl = (struct vki_xen_domctl *)ARG1; 992 993 switch (domctl->interface_version) { 994 case 0x00000007: 995 case 0x00000008: 996 case 0x00000009: 997 break; 998 default: 999 return; 1000 } 1001 1002#define __POST_XEN_DOMCTL_WRITE(_domctl, _union, _field) \ 1003 POST_MEM_WRITE((Addr)&domctl->u._union._field, \ 1004 sizeof(domctl->u._union._field)); 1005#define POST_XEN_DOMCTL_WRITE(_domctl, _field) \ 1006 __POST_XEN_DOMCTL_WRITE(_domctl, _domctl, _field) 1007 1008 switch (domctl->cmd) { 1009 case VKI_XEN_DOMCTL_createdomain: 1010 case VKI_XEN_DOMCTL_destroydomain: 1011 case VKI_XEN_DOMCTL_pausedomain: 1012 case VKI_XEN_DOMCTL_max_mem: 1013 case VKI_XEN_DOMCTL_set_address_size: 1014 case VKI_XEN_DOMCTL_settscinfo: 1015 case VKI_XEN_DOMCTL_hypercall_init: 1016 case VKI_XEN_DOMCTL_setvcpuaffinity: 1017 case VKI_XEN_DOMCTL_setvcpucontext: 1018 case VKI_XEN_DOMCTL_setnodeaffinity: 1019 case VKI_XEN_DOMCTL_set_cpuid: 1020 case VKI_XEN_DOMCTL_unpausedomain: 1021 /* No output fields */ 1022 break; 1023 1024 case VKI_XEN_DOMCTL_max_vcpus: 1025 POST_XEN_DOMCTL_WRITE(max_vcpus, max); 1026 break; 1027 1028 case VKI_XEN_DOMCTL_get_address_size: 1029 __POST_XEN_DOMCTL_WRITE(get_address_size, address_size, size); 1030 break; 1031 1032 case VKI_XEN_DOMCTL_gettscinfo: 1033 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.tsc_mode); 1034 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.gtsc_khz); 1035 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.incarnation); 1036 __POST_XEN_DOMCTL_WRITE(settscinfo, tsc_info, info.elapsed_nsec); 1037 break; 1038 1039 case VKI_XEN_DOMCTL_getvcpuinfo: 1040 POST_XEN_DOMCTL_WRITE(getvcpuinfo, online); 1041 POST_XEN_DOMCTL_WRITE(getvcpuinfo, blocked); 1042 POST_XEN_DOMCTL_WRITE(getvcpuinfo, running); 1043 POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu_time); 1044 POST_XEN_DOMCTL_WRITE(getvcpuinfo, cpu); 1045 break; 1046 1047 case VKI_XEN_DOMCTL_scheduler_op: 1048 if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_getinfo ) { 1049 switch(domctl->u.scheduler_op.sched_id) { 1050 case VKI_XEN_SCHEDULER_SEDF: 1051 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.period); 1052 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.slice); 1053 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.latency); 1054 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.extratime); 1055 POST_XEN_DOMCTL_WRITE(scheduler_op, u.sedf.weight); 1056 break; 1057 case VKI_XEN_SCHEDULER_CREDIT: 1058 POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.weight); 1059 POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit.cap); 1060 break; 1061 case VKI_XEN_SCHEDULER_CREDIT2: 1062 POST_XEN_DOMCTL_WRITE(scheduler_op, u.credit2.weight); 1063 break; 1064 case VKI_XEN_SCHEDULER_ARINC653: 1065 break; 1066 } 1067 } 1068 break; 1069 1070 case VKI_XEN_DOMCTL_getvcpuaffinity: 1071 POST_MEM_WRITE((Addr)domctl->u.vcpuaffinity.cpumap.bitmap.p, 1072 domctl->u.vcpuaffinity.cpumap.nr_bits / 8); 1073 break; 1074 1075 case VKI_XEN_DOMCTL_getnodeaffinity: 1076 POST_MEM_WRITE((Addr)domctl->u.nodeaffinity.nodemap.bitmap.p, 1077 domctl->u.nodeaffinity.nodemap.nr_bits / 8); 1078 break; 1079 1080 case VKI_XEN_DOMCTL_getdomaininfo: 1081 switch (domctl->interface_version) { 1082 case 0x00000007: 1083 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, domain); 1084 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, flags); 1085 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, tot_pages); 1086 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_pages); 1087 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shr_pages); 1088 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, shared_info_frame); 1089 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpu_time); 1090 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, nr_online_vcpus); 1091 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, max_vcpu_id); 1092 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, ssidref); 1093 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, handle); 1094 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000007, cpupool); 1095 break; 1096 case 0x00000008: 1097 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, domain); 1098 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, flags); 1099 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, tot_pages); 1100 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_pages); 1101 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shr_pages); 1102 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, paged_pages); 1103 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, shared_info_frame); 1104 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpu_time); 1105 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, nr_online_vcpus); 1106 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, max_vcpu_id); 1107 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, ssidref); 1108 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, handle); 1109 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000008, cpupool); 1110 break; 1111 case 0x00000009: 1112 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, domain); 1113 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, flags); 1114 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, tot_pages); 1115 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_pages); 1116 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, outstanding_pages); 1117 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shr_pages); 1118 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, paged_pages); 1119 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, shared_info_frame); 1120 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpu_time); 1121 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, nr_online_vcpus); 1122 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, max_vcpu_id); 1123 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, ssidref); 1124 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, handle); 1125 POST_XEN_DOMCTL_WRITE(getdomaininfo_00000009, cpupool); 1126 break; 1127 } 1128 break; 1129 case VKI_XEN_DOMCTL_getvcpucontext: 1130 __POST_XEN_DOMCTL_WRITE(getvcpucontext, vcpucontext, ctxt.p); 1131 break; 1132 1133 case VKI_XEN_DOMCTL_getvcpuextstate: 1134 __POST_XEN_DOMCTL_WRITE(getvcpuextstate, vcpuextstate, xfeature_mask); 1135 __POST_XEN_DOMCTL_WRITE(getvcpuextstate, vcpuextstate, size); 1136 POST_MEM_WRITE((Addr)domctl->u.vcpuextstate.buffer.p, 1137 domctl->u.vcpuextstate.size); 1138 break; 1139 1140 } 1141#undef POST_XEN_DOMCTL_WRITE 1142#undef __POST_XEN_DOMCTL_WRITE 1143} 1144 1145POST(hvm_op) 1146{ 1147 unsigned long op = ARG1; 1148 void *arg = (void *)(unsigned long)ARG2; 1149 1150#define __POST_XEN_HVMOP_WRITE(_hvm_op, _type, _field) \ 1151 POST_MEM_WRITE((Addr)&((_type*)arg)->_field, \ 1152 sizeof(((_type*)arg)->_field)) 1153#define POST_XEN_HVMOP_WRITE(_hvm_op, _field) \ 1154 __PRE_XEN_HVMOP_READ(_hvm_op, "xen_hvm_" # _hvm_op "_t", _field) 1155 1156 switch (op) { 1157 case VKI_XEN_HVMOP_set_param: 1158 /* No output paramters */ 1159 break; 1160 1161 case VKI_XEN_HVMOP_get_param: 1162 __POST_XEN_HVMOP_WRITE(get_param, struct vki_xen_hvm_param, value); 1163 break; 1164 } 1165#undef __POST_XEN_HVMOP_WRITE 1166#undef POST_XEN_HVMOP_WRITE 1167} 1168 1169POST(tmem_op) 1170{ 1171 struct vki_xen_tmem_op *tmem = (struct vki_xen_tmem_op *)ARG1; 1172 1173 switch(tmem->cmd) { 1174 1175 case VKI_XEN_TMEM_control: 1176 1177 switch(tmem->u.ctrl.subop) { 1178 /* No outputs */ 1179 case VKI_XEN_TMEMC_save_begin: 1180 break; 1181 } 1182 1183 break; 1184 } 1185} 1186 1187typedef 1188 struct { 1189 SyscallTableEntry entry; 1190 int nr_args; 1191 } 1192 XenHypercallTableEntry; 1193 1194#define HYPX_(const, name, nr_args) \ 1195 [const] = { { vgSysWrap_xen_##name##_before, NULL }, nr_args } 1196#define HYPXY(const, name, nr_args) \ 1197 [const] = { { vgSysWrap_xen_##name##_before, \ 1198 vgSysWrap_xen_##name##_after }, \ 1199 nr_args } 1200 1201static XenHypercallTableEntry hypercall_table[] = { 1202 // __VKI_XEN_set_trap_table // 0 1203 // __VKI_XEN_mmu_update // 1 1204 // __VKI_XEN_set_gdt // 2 1205 // __VKI_XEN_stack_switch // 3 1206 // __VKI_XEN_set_callbacks // 4 1207 1208 // __VKI_XEN_fpu_taskswitch // 5 1209 // __VKI_XEN_sched_op_compat // 6 1210 // __VKI_XEN_platform_op // 7 1211 // __VKI_XEN_set_debugreg // 8 1212 // __VKI_XEN_get_debugreg // 9 1213 1214 // __VKI_XEN_update_descriptor // 10 1215 // // 11 1216 HYPXY(__VKI_XEN_memory_op, memory_op, 2), // 12 1217 // __VKI_XEN_multicall // 13 1218 // __VKI_XEN_update_va_mapping // 14 1219 1220 // __VKI_XEN_set_timer_op // 15 1221 HYPXY(__VKI_XEN_event_channel_op_compat, evtchn_op_compat, 1), // 16 1222 HYPXY(__VKI_XEN_xen_version, xen_version, 2), // 17 1223 // __VKI_XEN_console_io // 18 1224 // __VKI_XEN_physdev_op_compat // 19 1225 1226 HYPXY(__VKI_XEN_grant_table_op, grant_table_op, 3), // 20 1227 // __VKI_XEN_vm_assist // 21 1228 // __VKI_XEN_update_va_mapping_otherdomain // 22 1229 // __VKI_XEN_iret, iret // 23 1230 // __VKI_XEN_vcpu_op, vcpu_op // 24 1231 1232 // __VKI_XEN_set_segment_base // 25 1233 HYPXY(__VKI_XEN_mmuext_op, mmuext_op, 2), // 26 1234 // __VKI_XEN_xsm_op // 27 1235 // __VKI_XEN_nmi_op // 28 1236 // __VKI_XEN_sched_op // 29 1237 1238 // __VKI_XEN_callback_op // 30 1239 // __VKI_XEN_xenoprof_op // 31 1240 HYPXY(__VKI_XEN_event_channel_op, evtchn_op, 2), // 32 1241 // __VKI_XEN_physdev_op // 33 1242 HYPXY(__VKI_XEN_hvm_op, hvm_op, 2), // 34 1243 1244 HYPXY(__VKI_XEN_sysctl, sysctl, 1), // 35 1245 HYPXY(__VKI_XEN_domctl, domctl, 1), // 36 1246 // __VKI_XEN_kexec_op // 37 1247 HYPXY(__VKI_XEN_tmem_op, tmem_op, 1), // 38 1248}; 1249 1250static void bad_before ( ThreadId tid, 1251 SyscallArgLayout* layout, 1252 /*MOD*/SyscallArgs* args, 1253 /*OUT*/SyscallStatus* status, 1254 /*OUT*/UWord* flags ) 1255{ 1256 VG_(dmsg)("WARNING: unhandled hypercall: %s\n", 1257 VG_SYSNUM_STRING_EXTRA(args->sysno)); 1258 if (VG_(clo_verbosity) > 1) { 1259 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 1260 } 1261 VG_(dmsg)("You may be able to write your own handler.\n"); 1262 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n"); 1263 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n"); 1264 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html &\n"); 1265 VG_(dmsg)("http://wiki.xen.org/wiki/Reporting_Bugs_against_Xen.\n"); 1266 1267 SET_STATUS_Failure(VKI_ENOSYS); 1268} 1269 1270static XenHypercallTableEntry bad_hyper = 1271{ { bad_before, NULL }, 0 }; 1272 1273static XenHypercallTableEntry* ML_(get_xen_hypercall_entry) ( UInt sysno ) 1274{ 1275 XenHypercallTableEntry *ret = &bad_hyper; 1276 1277 const UInt hypercall_table_size 1278 = sizeof(hypercall_table) / sizeof(hypercall_table[0]); 1279 1280 /* Is it in the contiguous initial section of the table? */ 1281 if (sysno < hypercall_table_size) { 1282 XenHypercallTableEntry* ent = &hypercall_table[sysno]; 1283 if (ent->entry.before != NULL) 1284 ret = ent; 1285 } 1286 1287 /* Can't find a wrapper */ 1288 return ret; 1289} 1290 1291DEFN_PRE_TEMPLATE(xen, hypercall) 1292{ 1293 XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO); 1294 1295 /* Return number of arguments consumed */ 1296 ARG8 = ent->nr_args; 1297 1298 vg_assert(ent); 1299 vg_assert(ent->entry.before); 1300 (ent->entry.before)( tid, layout, arrghs, status, flags ); 1301 1302} 1303 1304DEFN_POST_TEMPLATE(xen, hypercall) 1305{ 1306 XenHypercallTableEntry *ent = ML_(get_xen_hypercall_entry)(SYSNO); 1307 1308 /* Return number of arguments consumed */ 1309 ARG8 = ent->nr_args; 1310 1311 vg_assert(ent); 1312 if (ent->entry.after) 1313 (ent->entry.after)( tid, arrghs, status ); 1314} 1315 1316#endif // defined(ENABLE_XEN) 1317