15741Smrj /* 25741Smrj * CDDL HEADER START 35741Smrj * 45741Smrj * The contents of this file are subject to the terms of the 55741Smrj * Common Development and Distribution License (the "License"). 65741Smrj * You may not use this file except in compliance with the License. 75741Smrj * 85741Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95741Smrj * or http://www.opensolaris.org/os/licensing. 105741Smrj * See the License for the specific language governing permissions 115741Smrj * and limitations under the License. 125741Smrj * 135741Smrj * When distributing Covered Code, include this CDDL HEADER in each 145741Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155741Smrj * If applicable, add the following below this CDDL HEADER, with the 165741Smrj * fields enclosed by brackets "[]" replaced with your own identifying 175741Smrj * information: Portions Copyright [yyyy] [name of copyright owner] 185741Smrj * 195741Smrj * CDDL HEADER END 205741Smrj */ 215741Smrj 225741Smrj /* 2310175SStuart.Maybee@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245741Smrj * Use is subject to license terms. 255741Smrj */ 265741Smrj 275741Smrj /* 285741Smrj * Provides basic C wrappers around hypervisor invocation. 295741Smrj * 305741Smrj * i386: eax = vector: ebx, ecx, edx, esi, edi = args 1-5 315741Smrj * eax = return value 325741Smrj * (argument registers may be clobbered on return) 335741Smrj * 345741Smrj * amd64:rax = vector: rdi, rsi, rdx, r10, r8, r9 = args 1-6 355741Smrj * rax = return value 365741Smrj * (arguments registers not clobbered on return; rcx, r11 are) 375741Smrj */ 385741Smrj 395741Smrj #include <sys/types.h> 4010175SStuart.Maybee@Sun.COM #ifndef __xpv 415741Smrj #include <sys/xpv_support.h> 4210175SStuart.Maybee@Sun.COM #else 4310175SStuart.Maybee@Sun.COM #include <sys/xpv_user.h> 445741Smrj #endif 455741Smrj 465741Smrj #include <sys/hypervisor.h> 475741Smrj #include <xen/public/sched.h> 485741Smrj #include <sys/debug.h> 495741Smrj #include <sys/archsystm.h> 505741Smrj 515741Smrj long 525741Smrj HYPERVISOR_set_trap_table(trap_info_t *table) 535741Smrj { 545741Smrj return (__hypercall1(__HYPERVISOR_set_trap_table, (ulong_t)table)); 555741Smrj } 565741Smrj 575741Smrj int 585741Smrj HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count, 595741Smrj domid_t domain_id) 605741Smrj { 615741Smrj return (__hypercall4_int(__HYPERVISOR_mmu_update, 625741Smrj (ulong_t)req, (long)count, (ulong_t)success_count, 635741Smrj (ulong_t)domain_id)); 645741Smrj } 655741Smrj 665741Smrj long 675741Smrj HYPERVISOR_set_gdt(ulong_t *frame_list, int entries) 685741Smrj { 695741Smrj return (__hypercall2( 705741Smrj __HYPERVISOR_set_gdt, (ulong_t)frame_list, (long)entries)); 715741Smrj } 725741Smrj 735741Smrj /* 745741Smrj * XXPV Seems like "sp" would be a better name for both amd64 and i386? 755741Smrj * For now stay consistent with xen project source. 765741Smrj */ 775741Smrj long 785741Smrj HYPERVISOR_stack_switch(ulong_t ss, ulong_t esp) 795741Smrj { 805741Smrj return (__hypercall2(__HYPERVISOR_stack_switch, ss, esp)); 815741Smrj } 825741Smrj 835741Smrj #if defined(__amd64) 845741Smrj 855741Smrj long 865741Smrj HYPERVISOR_set_callbacks(ulong_t event_address, ulong_t failsafe_address, 875741Smrj ulong_t syscall_address) 885741Smrj { 895741Smrj return (__hypercall3(__HYPERVISOR_set_callbacks, 905741Smrj event_address, failsafe_address, syscall_address)); 915741Smrj } 925741Smrj 935741Smrj #elif defined(__i386) 945741Smrj 955741Smrj long 965741Smrj HYPERVISOR_set_callbacks( 975741Smrj ulong_t event_selector, ulong_t event_address, 985741Smrj ulong_t failsafe_selector, ulong_t failsafe_address) 995741Smrj { 1005741Smrj return (__hypercall4(__HYPERVISOR_set_callbacks, 1015741Smrj event_selector, event_address, 1025741Smrj failsafe_selector, failsafe_address)); 1035741Smrj } 1045741Smrj 1055741Smrj #endif /* __amd64 */ 1065741Smrj 1075741Smrj long 1085741Smrj HYPERVISOR_fpu_taskswitch(int set) 1095741Smrj { 1105741Smrj return (__hypercall1(__HYPERVISOR_fpu_taskswitch, (long)set)); 1115741Smrj } 1125741Smrj 1135741Smrj /* *** __HYPERVISOR_sched_op_compat *** OBSOLETED */ 1145741Smrj 1155741Smrj long 1165741Smrj HYPERVISOR_platform_op(xen_platform_op_t *platform_op) 1175741Smrj { 1185741Smrj return (__hypercall1(__HYPERVISOR_platform_op, (ulong_t)platform_op)); 1195741Smrj } 1205741Smrj 1215741Smrj /* *** __HYPERVISOR_set_debugreg *** NOT IMPLEMENTED */ 1225741Smrj 1235741Smrj /* *** __HYPERVISOR_get_debugreg *** NOT IMPLEMENTED */ 1245741Smrj 1255741Smrj long 1265741Smrj HYPERVISOR_update_descriptor(maddr_t ma, uint64_t desc) 1275741Smrj { 1285741Smrj #if defined(__amd64) 1295741Smrj 1305741Smrj return (__hypercall2(__HYPERVISOR_update_descriptor, ma, desc)); 1315741Smrj 1325741Smrj #elif defined(__i386) 1335741Smrj 1345741Smrj return (__hypercall4(__HYPERVISOR_update_descriptor, 1355741Smrj (ulong_t)ma, (ulong_t)(ma >>32), 1365741Smrj (ulong_t)desc, (ulong_t)(desc >> 32))); 1375741Smrj 1385741Smrj #endif 1395741Smrj } 1405741Smrj 1415741Smrj long 1425741Smrj HYPERVISOR_memory_op(int cmd, void *arg) 1435741Smrj { 1445741Smrj return (__hypercall2(__HYPERVISOR_memory_op, (long)cmd, 1455741Smrj (ulong_t)arg)); 1465741Smrj } 1475741Smrj 1485741Smrj long 1495741Smrj HYPERVISOR_multicall(void *call_list, uint_t nr_calls) 1505741Smrj { 1515741Smrj return (__hypercall2(__HYPERVISOR_multicall, 1525741Smrj (ulong_t)call_list, (ulong_t)nr_calls)); 1535741Smrj } 1545741Smrj 1555741Smrj int 1565741Smrj HYPERVISOR_update_va_mapping(ulong_t va, uint64_t new_pte, ulong_t flags) 1575741Smrj { 1585741Smrj #if !defined(_BOOT) 1595741Smrj if (IN_XPV_PANIC()) 1605741Smrj return (0); 1615741Smrj #endif 1625741Smrj #if defined(__amd64) 1635741Smrj 1645741Smrj return (__hypercall3_int(__HYPERVISOR_update_va_mapping, va, 1655741Smrj new_pte, flags)); 1665741Smrj 1675741Smrj #elif defined(__i386) 1685741Smrj 1695741Smrj return (__hypercall4_int(__HYPERVISOR_update_va_mapping, va, 1705741Smrj (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags)); 1715741Smrj 1725741Smrj #endif /* __i386 */ 1735741Smrj } 1745741Smrj 1755741Smrj /* 1765741Smrj * Note: this timeout must be the Xen system time not hrtime (see 1775741Smrj * xpv_timestamp.c). 1785741Smrj */ 1795741Smrj long 1805741Smrj HYPERVISOR_set_timer_op(uint64_t timeout) 1815741Smrj { 1825741Smrj #if defined(__amd64) 1835741Smrj 1845741Smrj return (__hypercall1(__HYPERVISOR_set_timer_op, timeout)); 1855741Smrj 1865741Smrj #elif defined(__i386) 1875741Smrj 1885741Smrj uint32_t timeout_hi = (uint32_t)(timeout >> 32); 1895741Smrj uint32_t timeout_lo = (uint32_t)timeout; 1905741Smrj return (__hypercall2(__HYPERVISOR_set_timer_op, 1915741Smrj (ulong_t)timeout_lo, (ulong_t)timeout_hi)); 1925741Smrj 1935741Smrj #endif /* __i386 */ 1945741Smrj } 1955741Smrj 1965741Smrj /* *** __HYPERVISOR_event_channel_op_compat *** OBSOLETED */ 1975741Smrj 1985741Smrj long 1995741Smrj HYPERVISOR_xen_version(int cmd, void *arg) 2005741Smrj { 2015741Smrj return (__hypercall2(__HYPERVISOR_xen_version, (long)cmd, 2025741Smrj (ulong_t)arg)); 2035741Smrj } 2045741Smrj 2055741Smrj long 2065741Smrj HYPERVISOR_console_io(int cmd, int count, char *str) 2075741Smrj { 2085741Smrj return (__hypercall3(__HYPERVISOR_console_io, (long)cmd, (long)count, 2095741Smrj (ulong_t)str)); 2105741Smrj } 2115741Smrj 2125741Smrj /* *** __HYPERVISOR_physdev_op_compat *** OBSOLETED */ 2135741Smrj 2147756SMark.Johnson@Sun.COM /* 2157756SMark.Johnson@Sun.COM * **** 2167756SMark.Johnson@Sun.COM * NOTE: this hypercall should not be called directly for a 2177756SMark.Johnson@Sun.COM * GNTTABOP_map_grant_ref. Instead xen_map_gref() should be called. 2187756SMark.Johnson@Sun.COM * **** 2197756SMark.Johnson@Sun.COM */ 2205741Smrj long 2215741Smrj HYPERVISOR_grant_table_op(uint_t cmd, void *uop, uint_t count) 2225741Smrj { 2235741Smrj int ret_val; 2245741Smrj ret_val = __hypercall3(__HYPERVISOR_grant_table_op, 2255741Smrj (long)cmd, (ulong_t)uop, (ulong_t)count); 2265741Smrj return (ret_val); 2275741Smrj } 2285741Smrj 2295741Smrj long 2305741Smrj HYPERVISOR_vm_assist(uint_t cmd, uint_t type) 2315741Smrj { 2325741Smrj return (__hypercall2(__HYPERVISOR_vm_assist, 2335741Smrj (ulong_t)cmd, (ulong_t)type)); 2345741Smrj } 2355741Smrj 2365741Smrj int 2375741Smrj HYPERVISOR_update_va_mapping_otherdomain(ulong_t va, 2385741Smrj uint64_t new_pte, ulong_t flags, domid_t domain_id) 2395741Smrj { 2405741Smrj #if defined(__amd64) 2415741Smrj 2425741Smrj return (__hypercall4_int(__HYPERVISOR_update_va_mapping_otherdomain, 2435741Smrj va, new_pte, flags, (ulong_t)domain_id)); 2445741Smrj 2455741Smrj #elif defined(__i386) 2465741Smrj 2475741Smrj return (__hypercall5_int(__HYPERVISOR_update_va_mapping_otherdomain, 2485741Smrj va, (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags, 2495741Smrj (ulong_t)domain_id)); 2505741Smrj 2515741Smrj #endif /* __i386 */ 2525741Smrj } 2535741Smrj 2545741Smrj /* 2555741Smrj * *** __HYPERVISOR_iret *** 2565741Smrj * see HYPERVISOR_IRET() macro in i86xpv/sys/machprivregs.h 2575741Smrj */ 2585741Smrj 2595741Smrj long 2605741Smrj HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args) 2615741Smrj { 2625741Smrj return (__hypercall3(__HYPERVISOR_vcpu_op, (long)cmd, (long)vcpuid, 2635741Smrj (ulong_t)extra_args)); 2645741Smrj } 2655741Smrj 2665741Smrj #if defined(__amd64) 2675741Smrj 2685741Smrj long 2695741Smrj HYPERVISOR_set_segment_base(int reg, ulong_t value) 2705741Smrj { 2715741Smrj return (__hypercall2(__HYPERVISOR_set_segment_base, (long)reg, value)); 2725741Smrj } 2735741Smrj 2745741Smrj #endif /* __amd64 */ 2755741Smrj 2765741Smrj int 2775741Smrj HYPERVISOR_mmuext_op(struct mmuext_op *req, int count, uint_t *success_count, 2785741Smrj domid_t domain_id) 2795741Smrj { 2805741Smrj return (__hypercall4_int(__HYPERVISOR_mmuext_op, 2815741Smrj (ulong_t)req, (long)count, (ulong_t)success_count, 2825741Smrj (ulong_t)domain_id)); 2835741Smrj } 2845741Smrj 2855741Smrj long 2865741Smrj HYPERVISOR_nmi_op(int cmd, void *arg) 2875741Smrj { 2885741Smrj return (__hypercall2(__HYPERVISOR_nmi_op, (long)cmd, (ulong_t)arg)); 2895741Smrj } 2905741Smrj 2915741Smrj long 2925741Smrj HYPERVISOR_sched_op(int cmd, void *arg) 2935741Smrj { 2945741Smrj return (__hypercall2(__HYPERVISOR_sched_op, 2955741Smrj (ulong_t)cmd, (ulong_t)arg)); 2965741Smrj } 2975741Smrj 2985741Smrj long 2995741Smrj HYPERVISOR_callback_op(int cmd, void *arg) 3005741Smrj { 3015741Smrj return (__hypercall2(__HYPERVISOR_callback_op, 3025741Smrj (ulong_t)cmd, (ulong_t)arg)); 3035741Smrj } 3045741Smrj 3055741Smrj /* *** __HYPERVISOR_xenoprof_op *** NOT IMPLEMENTED */ 3065741Smrj 3075741Smrj long 3085741Smrj HYPERVISOR_event_channel_op(int cmd, void *arg) 3095741Smrj { 3105741Smrj return (__hypercall2(__HYPERVISOR_event_channel_op, (long)cmd, 3115741Smrj (ulong_t)arg)); 3125741Smrj } 3135741Smrj 3145741Smrj long 3155741Smrj HYPERVISOR_physdev_op(int cmd, void *arg) 3165741Smrj { 3175741Smrj return (__hypercall2(__HYPERVISOR_physdev_op, (long)cmd, 3185741Smrj (ulong_t)arg)); 3195741Smrj } 3205741Smrj 3215741Smrj long 3225741Smrj HYPERVISOR_hvm_op(int cmd, void *arg) 3235741Smrj { 3245741Smrj return (__hypercall2(__HYPERVISOR_hvm_op, (long)cmd, (ulong_t)arg)); 3255741Smrj } 3265741Smrj 32710175SStuart.Maybee@Sun.COM #if defined(__xpv) 32810175SStuart.Maybee@Sun.COM long 32910175SStuart.Maybee@Sun.COM HYPERVISOR_xsm_op(struct xen_acmctl *arg) 33010175SStuart.Maybee@Sun.COM { 33110175SStuart.Maybee@Sun.COM return (__hypercall1(__HYPERVISOR_xsm_op, (ulong_t)arg)); 33210175SStuart.Maybee@Sun.COM } 33310175SStuart.Maybee@Sun.COM 3345741Smrj long 3355741Smrj HYPERVISOR_sysctl(xen_sysctl_t *sysctl) 3365741Smrj { 3375741Smrj return (__hypercall1(__HYPERVISOR_sysctl, (ulong_t)sysctl)); 3385741Smrj } 3395741Smrj 3405741Smrj long 3415741Smrj HYPERVISOR_domctl(xen_domctl_t *domctl) 3425741Smrj { 3435741Smrj return (__hypercall1(__HYPERVISOR_domctl, (ulong_t)domctl)); 3445741Smrj } 34510175SStuart.Maybee@Sun.COM #endif /* __xpv */ 3465741Smrj 3475741Smrj /* *** __HYPERVISOR_kexec_op *** NOT IMPLEMENTED */ 3485741Smrj 3495741Smrj /* 3505741Smrj * 3515741Smrj * HYPERCALL HELPER ROUTINES 3525741Smrj * These don't have there own unique hypercalls. 3535741Smrj * 3545741Smrj */ 3555741Smrj 3565741Smrj long 3575741Smrj HYPERVISOR_yield(void) 3585741Smrj { 3595741Smrj return (HYPERVISOR_sched_op(SCHEDOP_yield, NULL)); 3605741Smrj } 3615741Smrj 3625741Smrj long 3635741Smrj HYPERVISOR_block(void) 3645741Smrj { 3655741Smrj return (HYPERVISOR_sched_op(SCHEDOP_block, NULL)); 3665741Smrj } 3675741Smrj 3685741Smrj long 3695741Smrj HYPERVISOR_shutdown(uint_t reason) 3705741Smrj { 3715741Smrj struct sched_shutdown sched_shutdown; 3725741Smrj 3735741Smrj sched_shutdown.reason = reason; 3745741Smrj 3755741Smrj return (HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown)); 3765741Smrj } 3775741Smrj 3785741Smrj /* 3795741Smrj * Poll one or more event-channel ports, and return when pending. 3805741Smrj * An optional timeout (in nanoseconds, absolute time since boot) may be 3815741Smrj * specified. Note: this timeout must be the Xen system time not hrtime (see 3825741Smrj * xpv_timestamp.c). 3835741Smrj */ 3845741Smrj long 3855741Smrj HYPERVISOR_poll(evtchn_port_t *ports, uint_t nr_ports, uint64_t timeout) 3865741Smrj { 3875741Smrj struct sched_poll sched_poll; 3885741Smrj 3895741Smrj /*LINTED: constant in conditional context*/ 3905741Smrj set_xen_guest_handle(sched_poll.ports, ports); 3915741Smrj sched_poll.nr_ports = nr_ports; 3925741Smrj sched_poll.timeout = timeout; 3935741Smrj 3945741Smrj return (HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll)); 3955741Smrj } 3965741Smrj 3975741Smrj long 3985741Smrj HYPERVISOR_suspend(ulong_t start_info_mfn) 3995741Smrj { 4005741Smrj struct sched_shutdown sched_shutdown; 4015741Smrj 4025741Smrj sched_shutdown.reason = SHUTDOWN_suspend; 4035741Smrj 4045741Smrj return (__hypercall3(__HYPERVISOR_sched_op, SCHEDOP_shutdown, 4055741Smrj (ulong_t)&sched_shutdown, start_info_mfn)); 4065741Smrj } 4077532SSean.Ye@Sun.COM 4087532SSean.Ye@Sun.COM long 409*11120SMark.Johnson@Sun.COM HYPERVISOR_mca(uint32_t cmd, xen_mc_t *xmcp) 4107532SSean.Ye@Sun.COM { 4117532SSean.Ye@Sun.COM long rv; 4127532SSean.Ye@Sun.COM 4137532SSean.Ye@Sun.COM switch (cmd) { 41410175SStuart.Maybee@Sun.COM case XEN_MC_fetch: 41510175SStuart.Maybee@Sun.COM case XEN_MC_physcpuinfo: 41610175SStuart.Maybee@Sun.COM case XEN_MC_msrinject: 41710175SStuart.Maybee@Sun.COM case XEN_MC_mceinject: 4187532SSean.Ye@Sun.COM break; 4197532SSean.Ye@Sun.COM 42010175SStuart.Maybee@Sun.COM case XEN_MC_notifydomain: 4217532SSean.Ye@Sun.COM return (ENOTSUP); 4227532SSean.Ye@Sun.COM 4237532SSean.Ye@Sun.COM default: 4247532SSean.Ye@Sun.COM return (EINVAL); 4257532SSean.Ye@Sun.COM } 4267532SSean.Ye@Sun.COM 427*11120SMark.Johnson@Sun.COM xmcp->interface_version = XEN_MCA_INTERFACE_VERSION; 428*11120SMark.Johnson@Sun.COM xmcp->cmd = cmd; 4297532SSean.Ye@Sun.COM 430*11120SMark.Johnson@Sun.COM rv = __hypercall1(__HYPERVISOR_mca, (ulong_t)xmcp); 4317532SSean.Ye@Sun.COM 4327532SSean.Ye@Sun.COM return (rv); 4337532SSean.Ye@Sun.COM } 434