1843e1988Sjohnlev /* 2843e1988Sjohnlev * CDDL HEADER START 3843e1988Sjohnlev * 4843e1988Sjohnlev * The contents of this file are subject to the terms of the 5843e1988Sjohnlev * Common Development and Distribution License (the "License"). 6843e1988Sjohnlev * You may not use this file except in compliance with the License. 7843e1988Sjohnlev * 8843e1988Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9843e1988Sjohnlev * or http://www.opensolaris.org/os/licensing. 10843e1988Sjohnlev * See the License for the specific language governing permissions 11843e1988Sjohnlev * and limitations under the License. 12843e1988Sjohnlev * 13843e1988Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each 14843e1988Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15843e1988Sjohnlev * If applicable, add the following below this CDDL HEADER, with the 16843e1988Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying 17843e1988Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner] 18843e1988Sjohnlev * 19843e1988Sjohnlev * CDDL HEADER END 20843e1988Sjohnlev */ 21843e1988Sjohnlev 22843e1988Sjohnlev /* 23a576ab5bSrab * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24843e1988Sjohnlev * Use is subject to license terms. 25843e1988Sjohnlev */ 26843e1988Sjohnlev 27843e1988Sjohnlev /* 28843e1988Sjohnlev * Provides basic C wrappers around hypervisor invocation. 29843e1988Sjohnlev * 30843e1988Sjohnlev * i386: eax = vector: ebx, ecx, edx, esi, edi = args 1-5 31843e1988Sjohnlev * eax = return value 32843e1988Sjohnlev * (argument registers may be clobbered on return) 33843e1988Sjohnlev * 34843e1988Sjohnlev * amd64:rax = vector: rdi, rsi, rdx, r10, r8, r9 = args 1-6 35843e1988Sjohnlev * rax = return value 36843e1988Sjohnlev * (arguments registers not clobbered on return; rcx, r11 are) 37843e1988Sjohnlev */ 38843e1988Sjohnlev 39843e1988Sjohnlev #include <sys/types.h> 40551bc2a6Smrj #ifdef XPV_HVM_DRIVER 41551bc2a6Smrj #include <sys/xpv_support.h> 42551bc2a6Smrj #endif 43843e1988Sjohnlev 44843e1988Sjohnlev #include <sys/hypervisor.h> 45843e1988Sjohnlev #include <xen/public/sched.h> 46843e1988Sjohnlev #include <sys/debug.h> 47843e1988Sjohnlev #include <sys/archsystm.h> 48843e1988Sjohnlev 49843e1988Sjohnlev long 50843e1988Sjohnlev HYPERVISOR_set_trap_table(trap_info_t *table) 51843e1988Sjohnlev { 52843e1988Sjohnlev return (__hypercall1(__HYPERVISOR_set_trap_table, (ulong_t)table)); 53843e1988Sjohnlev } 54843e1988Sjohnlev 55843e1988Sjohnlev int 56843e1988Sjohnlev HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count, 57843e1988Sjohnlev domid_t domain_id) 58843e1988Sjohnlev { 59843e1988Sjohnlev return (__hypercall4_int(__HYPERVISOR_mmu_update, 60843e1988Sjohnlev (ulong_t)req, (long)count, (ulong_t)success_count, 61843e1988Sjohnlev (ulong_t)domain_id)); 62843e1988Sjohnlev } 63843e1988Sjohnlev 64843e1988Sjohnlev long 65843e1988Sjohnlev HYPERVISOR_set_gdt(ulong_t *frame_list, int entries) 66843e1988Sjohnlev { 67843e1988Sjohnlev return (__hypercall2( 68843e1988Sjohnlev __HYPERVISOR_set_gdt, (ulong_t)frame_list, (long)entries)); 69843e1988Sjohnlev } 70843e1988Sjohnlev 71843e1988Sjohnlev /* 72843e1988Sjohnlev * XXPV Seems like "sp" would be a better name for both amd64 and i386? 73843e1988Sjohnlev * For now stay consistent with xen project source. 74843e1988Sjohnlev */ 75843e1988Sjohnlev long 76843e1988Sjohnlev HYPERVISOR_stack_switch(ulong_t ss, ulong_t esp) 77843e1988Sjohnlev { 78843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_stack_switch, ss, esp)); 79843e1988Sjohnlev } 80843e1988Sjohnlev 81843e1988Sjohnlev #if defined(__amd64) 82843e1988Sjohnlev 83843e1988Sjohnlev long 84843e1988Sjohnlev HYPERVISOR_set_callbacks(ulong_t event_address, ulong_t failsafe_address, 85843e1988Sjohnlev ulong_t syscall_address) 86843e1988Sjohnlev { 87843e1988Sjohnlev return (__hypercall3(__HYPERVISOR_set_callbacks, 88843e1988Sjohnlev event_address, failsafe_address, syscall_address)); 89843e1988Sjohnlev } 90843e1988Sjohnlev 91843e1988Sjohnlev #elif defined(__i386) 92843e1988Sjohnlev 93843e1988Sjohnlev long 94843e1988Sjohnlev HYPERVISOR_set_callbacks( 95843e1988Sjohnlev ulong_t event_selector, ulong_t event_address, 96843e1988Sjohnlev ulong_t failsafe_selector, ulong_t failsafe_address) 97843e1988Sjohnlev { 98843e1988Sjohnlev return (__hypercall4(__HYPERVISOR_set_callbacks, 99843e1988Sjohnlev event_selector, event_address, 100843e1988Sjohnlev failsafe_selector, failsafe_address)); 101843e1988Sjohnlev } 102843e1988Sjohnlev 103843e1988Sjohnlev #endif /* __amd64 */ 104843e1988Sjohnlev 105843e1988Sjohnlev long 106843e1988Sjohnlev HYPERVISOR_fpu_taskswitch(int set) 107843e1988Sjohnlev { 108843e1988Sjohnlev return (__hypercall1(__HYPERVISOR_fpu_taskswitch, (long)set)); 109843e1988Sjohnlev } 110843e1988Sjohnlev 111843e1988Sjohnlev /* *** __HYPERVISOR_sched_op_compat *** OBSOLETED */ 112843e1988Sjohnlev 113843e1988Sjohnlev long 114843e1988Sjohnlev HYPERVISOR_platform_op(xen_platform_op_t *platform_op) 115843e1988Sjohnlev { 116843e1988Sjohnlev return (__hypercall1(__HYPERVISOR_platform_op, (ulong_t)platform_op)); 117843e1988Sjohnlev } 118843e1988Sjohnlev 119843e1988Sjohnlev /* *** __HYPERVISOR_set_debugreg *** NOT IMPLEMENTED */ 120843e1988Sjohnlev 121843e1988Sjohnlev /* *** __HYPERVISOR_get_debugreg *** NOT IMPLEMENTED */ 122843e1988Sjohnlev 123843e1988Sjohnlev long 124843e1988Sjohnlev HYPERVISOR_update_descriptor(maddr_t ma, uint64_t desc) 125843e1988Sjohnlev { 126843e1988Sjohnlev #if defined(__amd64) 127843e1988Sjohnlev 128843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_update_descriptor, ma, desc)); 129843e1988Sjohnlev 130843e1988Sjohnlev #elif defined(__i386) 131843e1988Sjohnlev 132843e1988Sjohnlev return (__hypercall4(__HYPERVISOR_update_descriptor, 133843e1988Sjohnlev (ulong_t)ma, (ulong_t)(ma >>32), 134843e1988Sjohnlev (ulong_t)desc, (ulong_t)(desc >> 32))); 135843e1988Sjohnlev 136843e1988Sjohnlev #endif 137843e1988Sjohnlev } 138843e1988Sjohnlev 139843e1988Sjohnlev long 140843e1988Sjohnlev HYPERVISOR_memory_op(int cmd, void *arg) 141843e1988Sjohnlev { 142843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_memory_op, (long)cmd, 143843e1988Sjohnlev (ulong_t)arg)); 144843e1988Sjohnlev } 145843e1988Sjohnlev 146843e1988Sjohnlev long 147843e1988Sjohnlev HYPERVISOR_multicall(void *call_list, uint_t nr_calls) 148843e1988Sjohnlev { 149843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_multicall, 150843e1988Sjohnlev (ulong_t)call_list, (ulong_t)nr_calls)); 151843e1988Sjohnlev } 152843e1988Sjohnlev 153843e1988Sjohnlev int 154843e1988Sjohnlev HYPERVISOR_update_va_mapping(ulong_t va, uint64_t new_pte, ulong_t flags) 155843e1988Sjohnlev { 156843e1988Sjohnlev #if !defined(_BOOT) 157843e1988Sjohnlev if (IN_XPV_PANIC()) 158843e1988Sjohnlev return (0); 159843e1988Sjohnlev #endif 160843e1988Sjohnlev #if defined(__amd64) 161843e1988Sjohnlev 162843e1988Sjohnlev return (__hypercall3_int(__HYPERVISOR_update_va_mapping, va, 163843e1988Sjohnlev new_pte, flags)); 164843e1988Sjohnlev 165843e1988Sjohnlev #elif defined(__i386) 166843e1988Sjohnlev 167843e1988Sjohnlev return (__hypercall4_int(__HYPERVISOR_update_va_mapping, va, 168843e1988Sjohnlev (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags)); 169843e1988Sjohnlev 170843e1988Sjohnlev #endif /* __i386 */ 171843e1988Sjohnlev } 172843e1988Sjohnlev 173843e1988Sjohnlev /* 174843e1988Sjohnlev * Note: this timeout must be the Xen system time not hrtime (see 175843e1988Sjohnlev * xpv_timestamp.c). 176843e1988Sjohnlev */ 177843e1988Sjohnlev long 178843e1988Sjohnlev HYPERVISOR_set_timer_op(uint64_t timeout) 179843e1988Sjohnlev { 180843e1988Sjohnlev #if defined(__amd64) 181843e1988Sjohnlev 182843e1988Sjohnlev return (__hypercall1(__HYPERVISOR_set_timer_op, timeout)); 183843e1988Sjohnlev 184843e1988Sjohnlev #elif defined(__i386) 185843e1988Sjohnlev 186843e1988Sjohnlev uint32_t timeout_hi = (uint32_t)(timeout >> 32); 187843e1988Sjohnlev uint32_t timeout_lo = (uint32_t)timeout; 188843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_set_timer_op, 189843e1988Sjohnlev (ulong_t)timeout_lo, (ulong_t)timeout_hi)); 190843e1988Sjohnlev 191843e1988Sjohnlev #endif /* __i386 */ 192843e1988Sjohnlev } 193843e1988Sjohnlev 194843e1988Sjohnlev /* *** __HYPERVISOR_event_channel_op_compat *** OBSOLETED */ 195843e1988Sjohnlev 196843e1988Sjohnlev long 197843e1988Sjohnlev HYPERVISOR_xen_version(int cmd, void *arg) 198843e1988Sjohnlev { 199843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_xen_version, (long)cmd, 200843e1988Sjohnlev (ulong_t)arg)); 201843e1988Sjohnlev } 202843e1988Sjohnlev 203843e1988Sjohnlev long 204843e1988Sjohnlev HYPERVISOR_console_io(int cmd, int count, char *str) 205843e1988Sjohnlev { 206843e1988Sjohnlev return (__hypercall3(__HYPERVISOR_console_io, (long)cmd, (long)count, 207843e1988Sjohnlev (ulong_t)str)); 208843e1988Sjohnlev } 209843e1988Sjohnlev 210843e1988Sjohnlev /* *** __HYPERVISOR_physdev_op_compat *** OBSOLETED */ 211843e1988Sjohnlev 212843e1988Sjohnlev long 213843e1988Sjohnlev HYPERVISOR_grant_table_op(uint_t cmd, void *uop, uint_t count) 214843e1988Sjohnlev { 215843e1988Sjohnlev int ret_val; 216843e1988Sjohnlev ret_val = __hypercall3(__HYPERVISOR_grant_table_op, 217843e1988Sjohnlev (long)cmd, (ulong_t)uop, (ulong_t)count); 218843e1988Sjohnlev 219551bc2a6Smrj #if !defined(_BOOT) && !defined(XPV_HVM_DRIVER) 220843e1988Sjohnlev /* 221843e1988Sjohnlev * XXPV -- 222843e1988Sjohnlev * The map_grant_ref call suffers a poor design flaw. 223843e1988Sjohnlev * It's the only hypervisor interface that creates page table mappings 224843e1988Sjohnlev * that doesn't take an entire PTE. Hence we can't create the 225843e1988Sjohnlev * mapping with a particular setting of the software PTE bits, NX, etc. 226843e1988Sjohnlev * 227843e1988Sjohnlev * Until the interface is fixed, we need to minimize the possiblity 228843e1988Sjohnlev * of dtrace or kmdb blowing up on a foreign mapping that doesn't 229843e1988Sjohnlev * have a correct setting for the soft bits. We'll force them here. 230843e1988Sjohnlev */ 231843e1988Sjohnlev if (ret_val == 0 && cmd == GNTTABOP_map_grant_ref) { 232843e1988Sjohnlev extern void xen_fix_foreign(uint64_t); 233843e1988Sjohnlev gnttab_map_grant_ref_t *mapops = (gnttab_map_grant_ref_t *)uop; 234843e1988Sjohnlev uint_t i; 235843e1988Sjohnlev for (i = 0; i < count; ++i) { 236843e1988Sjohnlev if (mapops[i].status == GNTST_okay) 237843e1988Sjohnlev xen_fix_foreign(mapops[i].host_addr); 238843e1988Sjohnlev } 239843e1988Sjohnlev } 240843e1988Sjohnlev #endif 241843e1988Sjohnlev return (ret_val); 242843e1988Sjohnlev } 243843e1988Sjohnlev 244843e1988Sjohnlev long 245843e1988Sjohnlev HYPERVISOR_vm_assist(uint_t cmd, uint_t type) 246843e1988Sjohnlev { 247843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_vm_assist, 248843e1988Sjohnlev (ulong_t)cmd, (ulong_t)type)); 249843e1988Sjohnlev } 250843e1988Sjohnlev 251843e1988Sjohnlev int 252843e1988Sjohnlev HYPERVISOR_update_va_mapping_otherdomain(ulong_t va, 253843e1988Sjohnlev uint64_t new_pte, ulong_t flags, domid_t domain_id) 254843e1988Sjohnlev { 255843e1988Sjohnlev #if defined(__amd64) 256843e1988Sjohnlev 257843e1988Sjohnlev return (__hypercall4_int(__HYPERVISOR_update_va_mapping_otherdomain, 258843e1988Sjohnlev va, new_pte, flags, (ulong_t)domain_id)); 259843e1988Sjohnlev 260843e1988Sjohnlev #elif defined(__i386) 261843e1988Sjohnlev 262843e1988Sjohnlev return (__hypercall5_int(__HYPERVISOR_update_va_mapping_otherdomain, 263843e1988Sjohnlev va, (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags, 264843e1988Sjohnlev (ulong_t)domain_id)); 265843e1988Sjohnlev 266843e1988Sjohnlev #endif /* __i386 */ 267843e1988Sjohnlev } 268843e1988Sjohnlev 269843e1988Sjohnlev /* 270843e1988Sjohnlev * *** __HYPERVISOR_iret *** 271843e1988Sjohnlev * see HYPERVISOR_IRET() macro in i86xpv/sys/machprivregs.h 272843e1988Sjohnlev */ 273843e1988Sjohnlev 274843e1988Sjohnlev long 275843e1988Sjohnlev HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args) 276843e1988Sjohnlev { 277843e1988Sjohnlev return (__hypercall3(__HYPERVISOR_vcpu_op, (long)cmd, (long)vcpuid, 278843e1988Sjohnlev (ulong_t)extra_args)); 279843e1988Sjohnlev } 280843e1988Sjohnlev 281843e1988Sjohnlev #if defined(__amd64) 282843e1988Sjohnlev 283843e1988Sjohnlev long 284843e1988Sjohnlev HYPERVISOR_set_segment_base(int reg, ulong_t value) 285843e1988Sjohnlev { 286843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_set_segment_base, (long)reg, value)); 287843e1988Sjohnlev } 288843e1988Sjohnlev 289843e1988Sjohnlev #endif /* __amd64 */ 290843e1988Sjohnlev 291843e1988Sjohnlev int 292843e1988Sjohnlev HYPERVISOR_mmuext_op(struct mmuext_op *req, int count, uint_t *success_count, 293843e1988Sjohnlev domid_t domain_id) 294843e1988Sjohnlev { 295843e1988Sjohnlev return (__hypercall4_int(__HYPERVISOR_mmuext_op, 296843e1988Sjohnlev (ulong_t)req, (long)count, (ulong_t)success_count, 297843e1988Sjohnlev (ulong_t)domain_id)); 298843e1988Sjohnlev } 299843e1988Sjohnlev 300843e1988Sjohnlev long 301a576ab5bSrab HYPERVISOR_acm_op(struct xen_acmctl *arg) 302843e1988Sjohnlev { 303a576ab5bSrab return (__hypercall1(__HYPERVISOR_acm_op, (ulong_t)arg)); 304843e1988Sjohnlev } 305843e1988Sjohnlev 306843e1988Sjohnlev long 307843e1988Sjohnlev HYPERVISOR_nmi_op(int cmd, void *arg) 308843e1988Sjohnlev { 309843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_nmi_op, (long)cmd, (ulong_t)arg)); 310843e1988Sjohnlev } 311843e1988Sjohnlev 312843e1988Sjohnlev long 313843e1988Sjohnlev HYPERVISOR_sched_op(int cmd, void *arg) 314843e1988Sjohnlev { 315843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_sched_op, 316843e1988Sjohnlev (ulong_t)cmd, (ulong_t)arg)); 317843e1988Sjohnlev } 318843e1988Sjohnlev 319843e1988Sjohnlev long 320843e1988Sjohnlev HYPERVISOR_callback_op(int cmd, void *arg) 321843e1988Sjohnlev { 322843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_callback_op, 323843e1988Sjohnlev (ulong_t)cmd, (ulong_t)arg)); 324843e1988Sjohnlev } 325843e1988Sjohnlev 326843e1988Sjohnlev /* *** __HYPERVISOR_xenoprof_op *** NOT IMPLEMENTED */ 327843e1988Sjohnlev 328843e1988Sjohnlev long 329843e1988Sjohnlev HYPERVISOR_event_channel_op(int cmd, void *arg) 330843e1988Sjohnlev { 331843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_event_channel_op, (long)cmd, 332843e1988Sjohnlev (ulong_t)arg)); 333843e1988Sjohnlev } 334843e1988Sjohnlev 335843e1988Sjohnlev long 336843e1988Sjohnlev HYPERVISOR_physdev_op(int cmd, void *arg) 337843e1988Sjohnlev { 338843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_physdev_op, (long)cmd, 339843e1988Sjohnlev (ulong_t)arg)); 340843e1988Sjohnlev } 341843e1988Sjohnlev 342843e1988Sjohnlev long 343843e1988Sjohnlev HYPERVISOR_hvm_op(int cmd, void *arg) 344843e1988Sjohnlev { 345843e1988Sjohnlev return (__hypercall2(__HYPERVISOR_hvm_op, (long)cmd, (ulong_t)arg)); 346843e1988Sjohnlev } 347843e1988Sjohnlev 348843e1988Sjohnlev long 349843e1988Sjohnlev HYPERVISOR_sysctl(xen_sysctl_t *sysctl) 350843e1988Sjohnlev { 351843e1988Sjohnlev return (__hypercall1(__HYPERVISOR_sysctl, (ulong_t)sysctl)); 352843e1988Sjohnlev } 353843e1988Sjohnlev 354843e1988Sjohnlev long 355843e1988Sjohnlev HYPERVISOR_domctl(xen_domctl_t *domctl) 356843e1988Sjohnlev { 357843e1988Sjohnlev return (__hypercall1(__HYPERVISOR_domctl, (ulong_t)domctl)); 358843e1988Sjohnlev } 359843e1988Sjohnlev 360843e1988Sjohnlev /* *** __HYPERVISOR_kexec_op *** NOT IMPLEMENTED */ 361843e1988Sjohnlev 362843e1988Sjohnlev /* 363843e1988Sjohnlev * 364843e1988Sjohnlev * HYPERCALL HELPER ROUTINES 365843e1988Sjohnlev * These don't have there own unique hypercalls. 366843e1988Sjohnlev * 367843e1988Sjohnlev */ 368843e1988Sjohnlev 369843e1988Sjohnlev long 370843e1988Sjohnlev HYPERVISOR_yield(void) 371843e1988Sjohnlev { 372843e1988Sjohnlev return (HYPERVISOR_sched_op(SCHEDOP_yield, NULL)); 373843e1988Sjohnlev } 374843e1988Sjohnlev 375843e1988Sjohnlev long 376843e1988Sjohnlev HYPERVISOR_block(void) 377843e1988Sjohnlev { 378843e1988Sjohnlev return (HYPERVISOR_sched_op(SCHEDOP_block, NULL)); 379843e1988Sjohnlev } 380843e1988Sjohnlev 381843e1988Sjohnlev long 382843e1988Sjohnlev HYPERVISOR_shutdown(uint_t reason) 383843e1988Sjohnlev { 384843e1988Sjohnlev struct sched_shutdown sched_shutdown; 385843e1988Sjohnlev 386843e1988Sjohnlev sched_shutdown.reason = reason; 387843e1988Sjohnlev 388843e1988Sjohnlev return (HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown)); 389843e1988Sjohnlev } 390843e1988Sjohnlev 391843e1988Sjohnlev /* 392843e1988Sjohnlev * Poll one or more event-channel ports, and return when pending. 393843e1988Sjohnlev * An optional timeout (in nanoseconds, absolute time since boot) may be 394843e1988Sjohnlev * specified. Note: this timeout must be the Xen system time not hrtime (see 395843e1988Sjohnlev * xpv_timestamp.c). 396843e1988Sjohnlev */ 397843e1988Sjohnlev long 398843e1988Sjohnlev HYPERVISOR_poll(evtchn_port_t *ports, uint_t nr_ports, uint64_t timeout) 399843e1988Sjohnlev { 400843e1988Sjohnlev struct sched_poll sched_poll; 401843e1988Sjohnlev 402843e1988Sjohnlev /*LINTED: constant in conditional context*/ 403843e1988Sjohnlev set_xen_guest_handle(sched_poll.ports, ports); 404843e1988Sjohnlev sched_poll.nr_ports = nr_ports; 405843e1988Sjohnlev sched_poll.timeout = timeout; 406843e1988Sjohnlev 407843e1988Sjohnlev return (HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll)); 408843e1988Sjohnlev } 409843e1988Sjohnlev 410843e1988Sjohnlev long 411843e1988Sjohnlev HYPERVISOR_suspend(ulong_t start_info_mfn) 412843e1988Sjohnlev { 413843e1988Sjohnlev struct sched_shutdown sched_shutdown; 414843e1988Sjohnlev 415843e1988Sjohnlev sched_shutdown.reason = SHUTDOWN_suspend; 416843e1988Sjohnlev 417843e1988Sjohnlev return (__hypercall3(__HYPERVISOR_sched_op, SCHEDOP_shutdown, 418843e1988Sjohnlev (ulong_t)&sched_shutdown, start_info_mfn)); 419843e1988Sjohnlev } 420*e4b86885SCheng Sean Ye 421*e4b86885SCheng Sean Ye long 422*e4b86885SCheng Sean Ye HYPERVISOR_mca(uint32_t cmd, xen_mc_arg_t *arg) 423*e4b86885SCheng Sean Ye { 424*e4b86885SCheng Sean Ye xen_mc_t xmc; 425*e4b86885SCheng Sean Ye long rv; 426*e4b86885SCheng Sean Ye 427*e4b86885SCheng Sean Ye switch (cmd) { 428*e4b86885SCheng Sean Ye case XEN_MC_CMD_fetch: 429*e4b86885SCheng Sean Ye case XEN_MC_CMD_physcpuinfo: 430*e4b86885SCheng Sean Ye case XEN_MC_CMD_msrinject: 431*e4b86885SCheng Sean Ye case XEN_MC_CMD_mceinject: 432*e4b86885SCheng Sean Ye case XEN_MC_CMD_offlinecpu: 433*e4b86885SCheng Sean Ye if (arg == NULL) 434*e4b86885SCheng Sean Ye return (EINVAL); 435*e4b86885SCheng Sean Ye break; 436*e4b86885SCheng Sean Ye 437*e4b86885SCheng Sean Ye case XEN_MC_CMD_notifydomain: 438*e4b86885SCheng Sean Ye return (ENOTSUP); 439*e4b86885SCheng Sean Ye 440*e4b86885SCheng Sean Ye default: 441*e4b86885SCheng Sean Ye return (EINVAL); 442*e4b86885SCheng Sean Ye } 443*e4b86885SCheng Sean Ye 444*e4b86885SCheng Sean Ye xmc.interface_version = XEN_MCA_INTERFACE_VERSION; 445*e4b86885SCheng Sean Ye xmc.cmd = cmd; 446*e4b86885SCheng Sean Ye if (arg != NULL) 447*e4b86885SCheng Sean Ye xmc.u = *arg; 448*e4b86885SCheng Sean Ye 449*e4b86885SCheng Sean Ye rv = __hypercall1(__HYPERVISOR_mca, (ulong_t)&xmc); 450*e4b86885SCheng Sean Ye 451*e4b86885SCheng Sean Ye if (rv == XEN_MC_HCALL_SUCCESS && arg != NULL) 452*e4b86885SCheng Sean Ye *arg = xmc.u; 453*e4b86885SCheng Sean Ye 454*e4b86885SCheng Sean Ye return (rv); 455*e4b86885SCheng Sean Ye } 456