1551bc2a6Smrj /* 2551bc2a6Smrj * CDDL HEADER START 3551bc2a6Smrj * 4551bc2a6Smrj * The contents of this file are subject to the terms of the 5551bc2a6Smrj * Common Development and Distribution License (the "License"). 6551bc2a6Smrj * You may not use this file except in compliance with the License. 7551bc2a6Smrj * 8551bc2a6Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9551bc2a6Smrj * or http://www.opensolaris.org/os/licensing. 10551bc2a6Smrj * See the License for the specific language governing permissions 11551bc2a6Smrj * and limitations under the License. 12551bc2a6Smrj * 13551bc2a6Smrj * When distributing Covered Code, include this CDDL HEADER in each 14551bc2a6Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15551bc2a6Smrj * If applicable, add the following below this CDDL HEADER, with the 16551bc2a6Smrj * fields enclosed by brackets "[]" replaced with your own identifying 17551bc2a6Smrj * information: Portions Copyright [yyyy] [name of copyright owner] 18551bc2a6Smrj * 19551bc2a6Smrj * CDDL HEADER END 20551bc2a6Smrj */ 21551bc2a6Smrj 22551bc2a6Smrj /* 23349b53ddSStuart Maybee * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24551bc2a6Smrj * Use is subject to license terms. 25551bc2a6Smrj */ 26551bc2a6Smrj 27551bc2a6Smrj /* 28551bc2a6Smrj * Provides basic C wrappers around hypervisor invocation. 29551bc2a6Smrj * 30551bc2a6Smrj * i386: eax = vector: ebx, ecx, edx, esi, edi = args 1-5 31551bc2a6Smrj * eax = return value 32551bc2a6Smrj * (argument registers may be clobbered on return) 33551bc2a6Smrj * 34551bc2a6Smrj * amd64:rax = vector: rdi, rsi, rdx, r10, r8, r9 = args 1-6 35551bc2a6Smrj * rax = return value 36551bc2a6Smrj * (arguments registers not clobbered on return; rcx, r11 are) 37551bc2a6Smrj */ 38551bc2a6Smrj 39551bc2a6Smrj #include <sys/types.h> 40349b53ddSStuart Maybee #ifndef __xpv 41551bc2a6Smrj #include <sys/xpv_support.h> 42349b53ddSStuart Maybee #else 43349b53ddSStuart Maybee #include <sys/xpv_user.h> 44551bc2a6Smrj #endif 45551bc2a6Smrj 46551bc2a6Smrj #include <sys/hypervisor.h> 47551bc2a6Smrj #include <xen/public/sched.h> 48551bc2a6Smrj #include <sys/debug.h> 49551bc2a6Smrj #include <sys/archsystm.h> 50551bc2a6Smrj 51551bc2a6Smrj long 52551bc2a6Smrj HYPERVISOR_set_trap_table(trap_info_t *table) 53551bc2a6Smrj { 54551bc2a6Smrj return (__hypercall1(__HYPERVISOR_set_trap_table, (ulong_t)table)); 55551bc2a6Smrj } 56551bc2a6Smrj 57551bc2a6Smrj int 58551bc2a6Smrj HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count, 59551bc2a6Smrj domid_t domain_id) 60551bc2a6Smrj { 61551bc2a6Smrj return (__hypercall4_int(__HYPERVISOR_mmu_update, 62551bc2a6Smrj (ulong_t)req, (long)count, (ulong_t)success_count, 63551bc2a6Smrj (ulong_t)domain_id)); 64551bc2a6Smrj } 65551bc2a6Smrj 66551bc2a6Smrj long 67551bc2a6Smrj HYPERVISOR_set_gdt(ulong_t *frame_list, int entries) 68551bc2a6Smrj { 69551bc2a6Smrj return (__hypercall2( 70551bc2a6Smrj __HYPERVISOR_set_gdt, (ulong_t)frame_list, (long)entries)); 71551bc2a6Smrj } 72551bc2a6Smrj 73551bc2a6Smrj /* 74551bc2a6Smrj * XXPV Seems like "sp" would be a better name for both amd64 and i386? 75551bc2a6Smrj * For now stay consistent with xen project source. 76551bc2a6Smrj */ 77551bc2a6Smrj long 78551bc2a6Smrj HYPERVISOR_stack_switch(ulong_t ss, ulong_t esp) 79551bc2a6Smrj { 80551bc2a6Smrj return (__hypercall2(__HYPERVISOR_stack_switch, ss, esp)); 81551bc2a6Smrj } 82551bc2a6Smrj 83551bc2a6Smrj #if defined(__amd64) 84551bc2a6Smrj 85551bc2a6Smrj long 86551bc2a6Smrj HYPERVISOR_set_callbacks(ulong_t event_address, ulong_t failsafe_address, 87551bc2a6Smrj ulong_t syscall_address) 88551bc2a6Smrj { 89551bc2a6Smrj return (__hypercall3(__HYPERVISOR_set_callbacks, 90551bc2a6Smrj event_address, failsafe_address, syscall_address)); 91551bc2a6Smrj } 92551bc2a6Smrj 93551bc2a6Smrj #elif defined(__i386) 94551bc2a6Smrj 95551bc2a6Smrj long 96551bc2a6Smrj HYPERVISOR_set_callbacks( 97551bc2a6Smrj ulong_t event_selector, ulong_t event_address, 98551bc2a6Smrj ulong_t failsafe_selector, ulong_t failsafe_address) 99551bc2a6Smrj { 100551bc2a6Smrj return (__hypercall4(__HYPERVISOR_set_callbacks, 101551bc2a6Smrj event_selector, event_address, 102551bc2a6Smrj failsafe_selector, failsafe_address)); 103551bc2a6Smrj } 104551bc2a6Smrj 105551bc2a6Smrj #endif /* __amd64 */ 106551bc2a6Smrj 107551bc2a6Smrj long 108551bc2a6Smrj HYPERVISOR_fpu_taskswitch(int set) 109551bc2a6Smrj { 110551bc2a6Smrj return (__hypercall1(__HYPERVISOR_fpu_taskswitch, (long)set)); 111551bc2a6Smrj } 112551bc2a6Smrj 113551bc2a6Smrj /* *** __HYPERVISOR_sched_op_compat *** OBSOLETED */ 114551bc2a6Smrj 115551bc2a6Smrj long 116551bc2a6Smrj HYPERVISOR_platform_op(xen_platform_op_t *platform_op) 117551bc2a6Smrj { 118551bc2a6Smrj return (__hypercall1(__HYPERVISOR_platform_op, (ulong_t)platform_op)); 119551bc2a6Smrj } 120551bc2a6Smrj 121551bc2a6Smrj /* *** __HYPERVISOR_set_debugreg *** NOT IMPLEMENTED */ 122551bc2a6Smrj 123551bc2a6Smrj /* *** __HYPERVISOR_get_debugreg *** NOT IMPLEMENTED */ 124551bc2a6Smrj 125551bc2a6Smrj long 126551bc2a6Smrj HYPERVISOR_update_descriptor(maddr_t ma, uint64_t desc) 127551bc2a6Smrj { 128551bc2a6Smrj #if defined(__amd64) 129551bc2a6Smrj 130551bc2a6Smrj return (__hypercall2(__HYPERVISOR_update_descriptor, ma, desc)); 131551bc2a6Smrj 132551bc2a6Smrj #elif defined(__i386) 133551bc2a6Smrj 134551bc2a6Smrj return (__hypercall4(__HYPERVISOR_update_descriptor, 135551bc2a6Smrj (ulong_t)ma, (ulong_t)(ma >>32), 136551bc2a6Smrj (ulong_t)desc, (ulong_t)(desc >> 32))); 137551bc2a6Smrj 138551bc2a6Smrj #endif 139551bc2a6Smrj } 140551bc2a6Smrj 141551bc2a6Smrj long 142551bc2a6Smrj HYPERVISOR_memory_op(int cmd, void *arg) 143551bc2a6Smrj { 144551bc2a6Smrj return (__hypercall2(__HYPERVISOR_memory_op, (long)cmd, 145551bc2a6Smrj (ulong_t)arg)); 146551bc2a6Smrj } 147551bc2a6Smrj 148551bc2a6Smrj long 149551bc2a6Smrj HYPERVISOR_multicall(void *call_list, uint_t nr_calls) 150551bc2a6Smrj { 151551bc2a6Smrj return (__hypercall2(__HYPERVISOR_multicall, 152551bc2a6Smrj (ulong_t)call_list, (ulong_t)nr_calls)); 153551bc2a6Smrj } 154551bc2a6Smrj 155551bc2a6Smrj int 156551bc2a6Smrj HYPERVISOR_update_va_mapping(ulong_t va, uint64_t new_pte, ulong_t flags) 157551bc2a6Smrj { 158551bc2a6Smrj #if !defined(_BOOT) 159551bc2a6Smrj if (IN_XPV_PANIC()) 160551bc2a6Smrj return (0); 161551bc2a6Smrj #endif 162551bc2a6Smrj #if defined(__amd64) 163551bc2a6Smrj 164551bc2a6Smrj return (__hypercall3_int(__HYPERVISOR_update_va_mapping, va, 165551bc2a6Smrj new_pte, flags)); 166551bc2a6Smrj 167551bc2a6Smrj #elif defined(__i386) 168551bc2a6Smrj 169551bc2a6Smrj return (__hypercall4_int(__HYPERVISOR_update_va_mapping, va, 170551bc2a6Smrj (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags)); 171551bc2a6Smrj 172551bc2a6Smrj #endif /* __i386 */ 173551bc2a6Smrj } 174551bc2a6Smrj 175551bc2a6Smrj /* 176551bc2a6Smrj * Note: this timeout must be the Xen system time not hrtime (see 177551bc2a6Smrj * xpv_timestamp.c). 178551bc2a6Smrj */ 179551bc2a6Smrj long 180551bc2a6Smrj HYPERVISOR_set_timer_op(uint64_t timeout) 181551bc2a6Smrj { 182551bc2a6Smrj #if defined(__amd64) 183551bc2a6Smrj 184551bc2a6Smrj return (__hypercall1(__HYPERVISOR_set_timer_op, timeout)); 185551bc2a6Smrj 186551bc2a6Smrj #elif defined(__i386) 187551bc2a6Smrj 188551bc2a6Smrj uint32_t timeout_hi = (uint32_t)(timeout >> 32); 189551bc2a6Smrj uint32_t timeout_lo = (uint32_t)timeout; 190551bc2a6Smrj return (__hypercall2(__HYPERVISOR_set_timer_op, 191551bc2a6Smrj (ulong_t)timeout_lo, (ulong_t)timeout_hi)); 192551bc2a6Smrj 193551bc2a6Smrj #endif /* __i386 */ 194551bc2a6Smrj } 195551bc2a6Smrj 196551bc2a6Smrj /* *** __HYPERVISOR_event_channel_op_compat *** OBSOLETED */ 197551bc2a6Smrj 198551bc2a6Smrj long 199551bc2a6Smrj HYPERVISOR_xen_version(int cmd, void *arg) 200551bc2a6Smrj { 201551bc2a6Smrj return (__hypercall2(__HYPERVISOR_xen_version, (long)cmd, 202551bc2a6Smrj (ulong_t)arg)); 203551bc2a6Smrj } 204551bc2a6Smrj 205551bc2a6Smrj long 206551bc2a6Smrj HYPERVISOR_console_io(int cmd, int count, char *str) 207551bc2a6Smrj { 208551bc2a6Smrj return (__hypercall3(__HYPERVISOR_console_io, (long)cmd, (long)count, 209551bc2a6Smrj (ulong_t)str)); 210551bc2a6Smrj } 211551bc2a6Smrj 212551bc2a6Smrj /* *** __HYPERVISOR_physdev_op_compat *** OBSOLETED */ 213551bc2a6Smrj 2147eea693dSMark Johnson /* 2157eea693dSMark Johnson * **** 2167eea693dSMark Johnson * NOTE: this hypercall should not be called directly for a 2177eea693dSMark Johnson * GNTTABOP_map_grant_ref. Instead xen_map_gref() should be called. 2187eea693dSMark Johnson * **** 2197eea693dSMark Johnson */ 220551bc2a6Smrj long 221551bc2a6Smrj HYPERVISOR_grant_table_op(uint_t cmd, void *uop, uint_t count) 222551bc2a6Smrj { 223551bc2a6Smrj int ret_val; 224551bc2a6Smrj ret_val = __hypercall3(__HYPERVISOR_grant_table_op, 225551bc2a6Smrj (long)cmd, (ulong_t)uop, (ulong_t)count); 226551bc2a6Smrj return (ret_val); 227551bc2a6Smrj } 228551bc2a6Smrj 229551bc2a6Smrj long 230551bc2a6Smrj HYPERVISOR_vm_assist(uint_t cmd, uint_t type) 231551bc2a6Smrj { 232551bc2a6Smrj return (__hypercall2(__HYPERVISOR_vm_assist, 233551bc2a6Smrj (ulong_t)cmd, (ulong_t)type)); 234551bc2a6Smrj } 235551bc2a6Smrj 236551bc2a6Smrj int 237551bc2a6Smrj HYPERVISOR_update_va_mapping_otherdomain(ulong_t va, 238551bc2a6Smrj uint64_t new_pte, ulong_t flags, domid_t domain_id) 239551bc2a6Smrj { 240551bc2a6Smrj #if defined(__amd64) 241551bc2a6Smrj 242551bc2a6Smrj return (__hypercall4_int(__HYPERVISOR_update_va_mapping_otherdomain, 243551bc2a6Smrj va, new_pte, flags, (ulong_t)domain_id)); 244551bc2a6Smrj 245551bc2a6Smrj #elif defined(__i386) 246551bc2a6Smrj 247551bc2a6Smrj return (__hypercall5_int(__HYPERVISOR_update_va_mapping_otherdomain, 248551bc2a6Smrj va, (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags, 249551bc2a6Smrj (ulong_t)domain_id)); 250551bc2a6Smrj 251551bc2a6Smrj #endif /* __i386 */ 252551bc2a6Smrj } 253551bc2a6Smrj 254551bc2a6Smrj /* 255551bc2a6Smrj * *** __HYPERVISOR_iret *** 256551bc2a6Smrj * see HYPERVISOR_IRET() macro in i86xpv/sys/machprivregs.h 257551bc2a6Smrj */ 258551bc2a6Smrj 259551bc2a6Smrj long 260551bc2a6Smrj HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args) 261551bc2a6Smrj { 262551bc2a6Smrj return (__hypercall3(__HYPERVISOR_vcpu_op, (long)cmd, (long)vcpuid, 263551bc2a6Smrj (ulong_t)extra_args)); 264551bc2a6Smrj } 265551bc2a6Smrj 266551bc2a6Smrj #if defined(__amd64) 267551bc2a6Smrj 268551bc2a6Smrj long 269551bc2a6Smrj HYPERVISOR_set_segment_base(int reg, ulong_t value) 270551bc2a6Smrj { 271551bc2a6Smrj return (__hypercall2(__HYPERVISOR_set_segment_base, (long)reg, value)); 272551bc2a6Smrj } 273551bc2a6Smrj 274551bc2a6Smrj #endif /* __amd64 */ 275551bc2a6Smrj 276551bc2a6Smrj int 277551bc2a6Smrj HYPERVISOR_mmuext_op(struct mmuext_op *req, int count, uint_t *success_count, 278551bc2a6Smrj domid_t domain_id) 279551bc2a6Smrj { 280551bc2a6Smrj return (__hypercall4_int(__HYPERVISOR_mmuext_op, 281551bc2a6Smrj (ulong_t)req, (long)count, (ulong_t)success_count, 282551bc2a6Smrj (ulong_t)domain_id)); 283551bc2a6Smrj } 284551bc2a6Smrj 285551bc2a6Smrj long 286551bc2a6Smrj HYPERVISOR_nmi_op(int cmd, void *arg) 287551bc2a6Smrj { 288551bc2a6Smrj return (__hypercall2(__HYPERVISOR_nmi_op, (long)cmd, (ulong_t)arg)); 289551bc2a6Smrj } 290551bc2a6Smrj 291551bc2a6Smrj long 292551bc2a6Smrj HYPERVISOR_sched_op(int cmd, void *arg) 293551bc2a6Smrj { 294551bc2a6Smrj return (__hypercall2(__HYPERVISOR_sched_op, 295551bc2a6Smrj (ulong_t)cmd, (ulong_t)arg)); 296551bc2a6Smrj } 297551bc2a6Smrj 298551bc2a6Smrj long 299551bc2a6Smrj HYPERVISOR_callback_op(int cmd, void *arg) 300551bc2a6Smrj { 301551bc2a6Smrj return (__hypercall2(__HYPERVISOR_callback_op, 302551bc2a6Smrj (ulong_t)cmd, (ulong_t)arg)); 303551bc2a6Smrj } 304551bc2a6Smrj 305551bc2a6Smrj /* *** __HYPERVISOR_xenoprof_op *** NOT IMPLEMENTED */ 306551bc2a6Smrj 307551bc2a6Smrj long 308551bc2a6Smrj HYPERVISOR_event_channel_op(int cmd, void *arg) 309551bc2a6Smrj { 310551bc2a6Smrj return (__hypercall2(__HYPERVISOR_event_channel_op, (long)cmd, 311551bc2a6Smrj (ulong_t)arg)); 312551bc2a6Smrj } 313551bc2a6Smrj 314551bc2a6Smrj long 315551bc2a6Smrj HYPERVISOR_physdev_op(int cmd, void *arg) 316551bc2a6Smrj { 317551bc2a6Smrj return (__hypercall2(__HYPERVISOR_physdev_op, (long)cmd, 318551bc2a6Smrj (ulong_t)arg)); 319551bc2a6Smrj } 320551bc2a6Smrj 321551bc2a6Smrj long 322551bc2a6Smrj HYPERVISOR_hvm_op(int cmd, void *arg) 323551bc2a6Smrj { 324551bc2a6Smrj return (__hypercall2(__HYPERVISOR_hvm_op, (long)cmd, (ulong_t)arg)); 325551bc2a6Smrj } 326551bc2a6Smrj 327349b53ddSStuart Maybee #if defined(__xpv) 328349b53ddSStuart Maybee long 329349b53ddSStuart Maybee HYPERVISOR_xsm_op(struct xen_acmctl *arg) 330349b53ddSStuart Maybee { 331349b53ddSStuart Maybee return (__hypercall1(__HYPERVISOR_xsm_op, (ulong_t)arg)); 332349b53ddSStuart Maybee } 333349b53ddSStuart Maybee 334551bc2a6Smrj long 335551bc2a6Smrj HYPERVISOR_sysctl(xen_sysctl_t *sysctl) 336551bc2a6Smrj { 337551bc2a6Smrj return (__hypercall1(__HYPERVISOR_sysctl, (ulong_t)sysctl)); 338551bc2a6Smrj } 339551bc2a6Smrj 340551bc2a6Smrj long 341551bc2a6Smrj HYPERVISOR_domctl(xen_domctl_t *domctl) 342551bc2a6Smrj { 343551bc2a6Smrj return (__hypercall1(__HYPERVISOR_domctl, (ulong_t)domctl)); 344551bc2a6Smrj } 345349b53ddSStuart Maybee #endif /* __xpv */ 346551bc2a6Smrj 347551bc2a6Smrj /* *** __HYPERVISOR_kexec_op *** NOT IMPLEMENTED */ 348551bc2a6Smrj 349551bc2a6Smrj /* 350551bc2a6Smrj * 351551bc2a6Smrj * HYPERCALL HELPER ROUTINES 352551bc2a6Smrj * These don't have there own unique hypercalls. 353551bc2a6Smrj * 354551bc2a6Smrj */ 355551bc2a6Smrj 356551bc2a6Smrj long 357551bc2a6Smrj HYPERVISOR_yield(void) 358551bc2a6Smrj { 359551bc2a6Smrj return (HYPERVISOR_sched_op(SCHEDOP_yield, NULL)); 360551bc2a6Smrj } 361551bc2a6Smrj 362551bc2a6Smrj long 363551bc2a6Smrj HYPERVISOR_block(void) 364551bc2a6Smrj { 365551bc2a6Smrj return (HYPERVISOR_sched_op(SCHEDOP_block, NULL)); 366551bc2a6Smrj } 367551bc2a6Smrj 368551bc2a6Smrj long 369551bc2a6Smrj HYPERVISOR_shutdown(uint_t reason) 370551bc2a6Smrj { 371551bc2a6Smrj struct sched_shutdown sched_shutdown; 372551bc2a6Smrj 373551bc2a6Smrj sched_shutdown.reason = reason; 374551bc2a6Smrj 375551bc2a6Smrj return (HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown)); 376551bc2a6Smrj } 377551bc2a6Smrj 378551bc2a6Smrj /* 379551bc2a6Smrj * Poll one or more event-channel ports, and return when pending. 380551bc2a6Smrj * An optional timeout (in nanoseconds, absolute time since boot) may be 381551bc2a6Smrj * specified. Note: this timeout must be the Xen system time not hrtime (see 382551bc2a6Smrj * xpv_timestamp.c). 383551bc2a6Smrj */ 384551bc2a6Smrj long 385551bc2a6Smrj HYPERVISOR_poll(evtchn_port_t *ports, uint_t nr_ports, uint64_t timeout) 386551bc2a6Smrj { 387551bc2a6Smrj struct sched_poll sched_poll; 388551bc2a6Smrj 389551bc2a6Smrj /*LINTED: constant in conditional context*/ 390551bc2a6Smrj set_xen_guest_handle(sched_poll.ports, ports); 391551bc2a6Smrj sched_poll.nr_ports = nr_ports; 392551bc2a6Smrj sched_poll.timeout = timeout; 393551bc2a6Smrj 394551bc2a6Smrj return (HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll)); 395551bc2a6Smrj } 396551bc2a6Smrj 397551bc2a6Smrj long 398551bc2a6Smrj HYPERVISOR_suspend(ulong_t start_info_mfn) 399551bc2a6Smrj { 400551bc2a6Smrj struct sched_shutdown sched_shutdown; 401551bc2a6Smrj 402551bc2a6Smrj sched_shutdown.reason = SHUTDOWN_suspend; 403551bc2a6Smrj 404551bc2a6Smrj return (__hypercall3(__HYPERVISOR_sched_op, SCHEDOP_shutdown, 405551bc2a6Smrj (ulong_t)&sched_shutdown, start_info_mfn)); 406551bc2a6Smrj } 407e4b86885SCheng Sean Ye 408e4b86885SCheng Sean Ye long 409*ad09f8b8SMark Johnson HYPERVISOR_mca(uint32_t cmd, xen_mc_t *xmcp) 410e4b86885SCheng Sean Ye { 411e4b86885SCheng Sean Ye long rv; 412e4b86885SCheng Sean Ye 413e4b86885SCheng Sean Ye switch (cmd) { 414349b53ddSStuart Maybee case XEN_MC_fetch: 415349b53ddSStuart Maybee case XEN_MC_physcpuinfo: 416349b53ddSStuart Maybee case XEN_MC_msrinject: 417349b53ddSStuart Maybee case XEN_MC_mceinject: 418e4b86885SCheng Sean Ye break; 419e4b86885SCheng Sean Ye 420349b53ddSStuart Maybee case XEN_MC_notifydomain: 421e4b86885SCheng Sean Ye return (ENOTSUP); 422e4b86885SCheng Sean Ye 423e4b86885SCheng Sean Ye default: 424e4b86885SCheng Sean Ye return (EINVAL); 425e4b86885SCheng Sean Ye } 426e4b86885SCheng Sean Ye 427*ad09f8b8SMark Johnson xmcp->interface_version = XEN_MCA_INTERFACE_VERSION; 428*ad09f8b8SMark Johnson xmcp->cmd = cmd; 429e4b86885SCheng Sean Ye 430*ad09f8b8SMark Johnson rv = __hypercall1(__HYPERVISOR_mca, (ulong_t)xmcp); 431e4b86885SCheng Sean Ye 432e4b86885SCheng Sean Ye return (rv); 433e4b86885SCheng Sean Ye } 434