18c2ecf20Sopenharmony_ci/****************************************************************************** 28c2ecf20Sopenharmony_ci * hypercall.h 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Linux-specific hypervisor handling. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (c) 2002-2004, K A Fraser 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or 98c2ecf20Sopenharmony_ci * modify it under the terms of the GNU General Public License version 2 108c2ecf20Sopenharmony_ci * as published by the Free Software Foundation; or, when distributed 118c2ecf20Sopenharmony_ci * separately from the Linux kernel or incorporated into other 128c2ecf20Sopenharmony_ci * software packages, subject to the following license: 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 158c2ecf20Sopenharmony_ci * of this source file (the "Software"), to deal in the Software without 168c2ecf20Sopenharmony_ci * restriction, including without limitation the rights to use, copy, modify, 178c2ecf20Sopenharmony_ci * merge, publish, distribute, sublicense, and/or sell copies of the Software, 188c2ecf20Sopenharmony_ci * and to permit persons to whom the Software is furnished to do so, subject to 198c2ecf20Sopenharmony_ci * the following conditions: 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 228c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 258c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 268c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 278c2ecf20Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 288c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 298c2ecf20Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 308c2ecf20Sopenharmony_ci * IN THE SOFTWARE. 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#ifndef _ASM_X86_XEN_HYPERCALL_H 348c2ecf20Sopenharmony_ci#define _ASM_X86_XEN_HYPERCALL_H 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#include <linux/kernel.h> 378c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 388c2ecf20Sopenharmony_ci#include <linux/errno.h> 398c2ecf20Sopenharmony_ci#include <linux/string.h> 408c2ecf20Sopenharmony_ci#include <linux/types.h> 418c2ecf20Sopenharmony_ci#include <linux/pgtable.h> 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#include <trace/events/xen.h> 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#include <asm/page.h> 468c2ecf20Sopenharmony_ci#include <asm/smap.h> 478c2ecf20Sopenharmony_ci#include <asm/nospec-branch.h> 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#include <xen/interface/xen.h> 508c2ecf20Sopenharmony_ci#include <xen/interface/sched.h> 518c2ecf20Sopenharmony_ci#include <xen/interface/physdev.h> 528c2ecf20Sopenharmony_ci#include <xen/interface/platform.h> 538c2ecf20Sopenharmony_ci#include <xen/interface/xen-mca.h> 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistruct xen_dm_op_buf; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci * The hypercall asms have to meet several constraints: 598c2ecf20Sopenharmony_ci * - Work on 32- and 64-bit. 608c2ecf20Sopenharmony_ci * The two architectures put their arguments in different sets of 618c2ecf20Sopenharmony_ci * registers. 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * - Work around asm syntax quirks 648c2ecf20Sopenharmony_ci * It isn't possible to specify one of the rNN registers in a 658c2ecf20Sopenharmony_ci * constraint, so we use explicit register variables to get the 668c2ecf20Sopenharmony_ci * args into the right place. 678c2ecf20Sopenharmony_ci * 688c2ecf20Sopenharmony_ci * - Mark all registers as potentially clobbered 698c2ecf20Sopenharmony_ci * Even unused parameters can be clobbered by the hypervisor, so we 708c2ecf20Sopenharmony_ci * need to make sure gcc knows it. 718c2ecf20Sopenharmony_ci * 728c2ecf20Sopenharmony_ci * - Avoid compiler bugs. 738c2ecf20Sopenharmony_ci * This is the tricky part. Because x86_32 has such a constrained 748c2ecf20Sopenharmony_ci * register set, gcc versions below 4.3 have trouble generating 758c2ecf20Sopenharmony_ci * code when all the arg registers and memory are trashed by the 768c2ecf20Sopenharmony_ci * asm. There are syntactically simpler ways of achieving the 778c2ecf20Sopenharmony_ci * semantics below, but they cause the compiler to crash. 788c2ecf20Sopenharmony_ci * 798c2ecf20Sopenharmony_ci * The only combination I found which works is: 808c2ecf20Sopenharmony_ci * - assign the __argX variables first 818c2ecf20Sopenharmony_ci * - list all actually used parameters as "+r" (__argX) 828c2ecf20Sopenharmony_ci * - clobber the rest 838c2ecf20Sopenharmony_ci * 848c2ecf20Sopenharmony_ci * The result certainly isn't pretty, and it really shows up cpp's 858c2ecf20Sopenharmony_ci * weakness as a macro language. Sorry. (But let's just give thanks 868c2ecf20Sopenharmony_ci * there aren't more than 5 arguments...) 878c2ecf20Sopenharmony_ci */ 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ciextern struct { char _entry[32]; } hypercall_page[]; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#define __HYPERCALL "call hypercall_page+%c[offset]" 928c2ecf20Sopenharmony_ci#define __HYPERCALL_ENTRY(x) \ 938c2ecf20Sopenharmony_ci [offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0])) 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32 968c2ecf20Sopenharmony_ci#define __HYPERCALL_RETREG "eax" 978c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG1REG "ebx" 988c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG2REG "ecx" 998c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG3REG "edx" 1008c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG4REG "esi" 1018c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG5REG "edi" 1028c2ecf20Sopenharmony_ci#else 1038c2ecf20Sopenharmony_ci#define __HYPERCALL_RETREG "rax" 1048c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG1REG "rdi" 1058c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG2REG "rsi" 1068c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG3REG "rdx" 1078c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG4REG "r10" 1088c2ecf20Sopenharmony_ci#define __HYPERCALL_ARG5REG "r8" 1098c2ecf20Sopenharmony_ci#endif 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci#define __HYPERCALL_DECLS \ 1128c2ecf20Sopenharmony_ci register unsigned long __res asm(__HYPERCALL_RETREG); \ 1138c2ecf20Sopenharmony_ci register unsigned long __arg1 asm(__HYPERCALL_ARG1REG) = __arg1; \ 1148c2ecf20Sopenharmony_ci register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ 1158c2ecf20Sopenharmony_ci register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ 1168c2ecf20Sopenharmony_ci register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ 1178c2ecf20Sopenharmony_ci register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci#define __HYPERCALL_0PARAM "=r" (__res), ASM_CALL_CONSTRAINT 1208c2ecf20Sopenharmony_ci#define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) 1218c2ecf20Sopenharmony_ci#define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) 1228c2ecf20Sopenharmony_ci#define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) 1238c2ecf20Sopenharmony_ci#define __HYPERCALL_4PARAM __HYPERCALL_3PARAM, "+r" (__arg4) 1248c2ecf20Sopenharmony_ci#define __HYPERCALL_5PARAM __HYPERCALL_4PARAM, "+r" (__arg5) 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci#define __HYPERCALL_0ARG() 1278c2ecf20Sopenharmony_ci#define __HYPERCALL_1ARG(a1) \ 1288c2ecf20Sopenharmony_ci __HYPERCALL_0ARG() __arg1 = (unsigned long)(a1); 1298c2ecf20Sopenharmony_ci#define __HYPERCALL_2ARG(a1,a2) \ 1308c2ecf20Sopenharmony_ci __HYPERCALL_1ARG(a1) __arg2 = (unsigned long)(a2); 1318c2ecf20Sopenharmony_ci#define __HYPERCALL_3ARG(a1,a2,a3) \ 1328c2ecf20Sopenharmony_ci __HYPERCALL_2ARG(a1,a2) __arg3 = (unsigned long)(a3); 1338c2ecf20Sopenharmony_ci#define __HYPERCALL_4ARG(a1,a2,a3,a4) \ 1348c2ecf20Sopenharmony_ci __HYPERCALL_3ARG(a1,a2,a3) __arg4 = (unsigned long)(a4); 1358c2ecf20Sopenharmony_ci#define __HYPERCALL_5ARG(a1,a2,a3,a4,a5) \ 1368c2ecf20Sopenharmony_ci __HYPERCALL_4ARG(a1,a2,a3,a4) __arg5 = (unsigned long)(a5); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci#define __HYPERCALL_CLOBBER5 "memory" 1398c2ecf20Sopenharmony_ci#define __HYPERCALL_CLOBBER4 __HYPERCALL_CLOBBER5, __HYPERCALL_ARG5REG 1408c2ecf20Sopenharmony_ci#define __HYPERCALL_CLOBBER3 __HYPERCALL_CLOBBER4, __HYPERCALL_ARG4REG 1418c2ecf20Sopenharmony_ci#define __HYPERCALL_CLOBBER2 __HYPERCALL_CLOBBER3, __HYPERCALL_ARG3REG 1428c2ecf20Sopenharmony_ci#define __HYPERCALL_CLOBBER1 __HYPERCALL_CLOBBER2, __HYPERCALL_ARG2REG 1438c2ecf20Sopenharmony_ci#define __HYPERCALL_CLOBBER0 __HYPERCALL_CLOBBER1, __HYPERCALL_ARG1REG 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci#define _hypercall0(type, name) \ 1468c2ecf20Sopenharmony_ci({ \ 1478c2ecf20Sopenharmony_ci __HYPERCALL_DECLS; \ 1488c2ecf20Sopenharmony_ci __HYPERCALL_0ARG(); \ 1498c2ecf20Sopenharmony_ci asm volatile (__HYPERCALL \ 1508c2ecf20Sopenharmony_ci : __HYPERCALL_0PARAM \ 1518c2ecf20Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 1528c2ecf20Sopenharmony_ci : __HYPERCALL_CLOBBER0); \ 1538c2ecf20Sopenharmony_ci (type)__res; \ 1548c2ecf20Sopenharmony_ci}) 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci#define _hypercall1(type, name, a1) \ 1578c2ecf20Sopenharmony_ci({ \ 1588c2ecf20Sopenharmony_ci __HYPERCALL_DECLS; \ 1598c2ecf20Sopenharmony_ci __HYPERCALL_1ARG(a1); \ 1608c2ecf20Sopenharmony_ci asm volatile (__HYPERCALL \ 1618c2ecf20Sopenharmony_ci : __HYPERCALL_1PARAM \ 1628c2ecf20Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 1638c2ecf20Sopenharmony_ci : __HYPERCALL_CLOBBER1); \ 1648c2ecf20Sopenharmony_ci (type)__res; \ 1658c2ecf20Sopenharmony_ci}) 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci#define _hypercall2(type, name, a1, a2) \ 1688c2ecf20Sopenharmony_ci({ \ 1698c2ecf20Sopenharmony_ci __HYPERCALL_DECLS; \ 1708c2ecf20Sopenharmony_ci __HYPERCALL_2ARG(a1, a2); \ 1718c2ecf20Sopenharmony_ci asm volatile (__HYPERCALL \ 1728c2ecf20Sopenharmony_ci : __HYPERCALL_2PARAM \ 1738c2ecf20Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 1748c2ecf20Sopenharmony_ci : __HYPERCALL_CLOBBER2); \ 1758c2ecf20Sopenharmony_ci (type)__res; \ 1768c2ecf20Sopenharmony_ci}) 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci#define _hypercall3(type, name, a1, a2, a3) \ 1798c2ecf20Sopenharmony_ci({ \ 1808c2ecf20Sopenharmony_ci __HYPERCALL_DECLS; \ 1818c2ecf20Sopenharmony_ci __HYPERCALL_3ARG(a1, a2, a3); \ 1828c2ecf20Sopenharmony_ci asm volatile (__HYPERCALL \ 1838c2ecf20Sopenharmony_ci : __HYPERCALL_3PARAM \ 1848c2ecf20Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 1858c2ecf20Sopenharmony_ci : __HYPERCALL_CLOBBER3); \ 1868c2ecf20Sopenharmony_ci (type)__res; \ 1878c2ecf20Sopenharmony_ci}) 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci#define _hypercall4(type, name, a1, a2, a3, a4) \ 1908c2ecf20Sopenharmony_ci({ \ 1918c2ecf20Sopenharmony_ci __HYPERCALL_DECLS; \ 1928c2ecf20Sopenharmony_ci __HYPERCALL_4ARG(a1, a2, a3, a4); \ 1938c2ecf20Sopenharmony_ci asm volatile (__HYPERCALL \ 1948c2ecf20Sopenharmony_ci : __HYPERCALL_4PARAM \ 1958c2ecf20Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 1968c2ecf20Sopenharmony_ci : __HYPERCALL_CLOBBER4); \ 1978c2ecf20Sopenharmony_ci (type)__res; \ 1988c2ecf20Sopenharmony_ci}) 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic inline long 2018c2ecf20Sopenharmony_cixen_single_call(unsigned int call, 2028c2ecf20Sopenharmony_ci unsigned long a1, unsigned long a2, 2038c2ecf20Sopenharmony_ci unsigned long a3, unsigned long a4, 2048c2ecf20Sopenharmony_ci unsigned long a5) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci __HYPERCALL_DECLS; 2078c2ecf20Sopenharmony_ci __HYPERCALL_5ARG(a1, a2, a3, a4, a5); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci if (call >= PAGE_SIZE / sizeof(hypercall_page[0])) 2108c2ecf20Sopenharmony_ci return -EINVAL; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci asm volatile(CALL_NOSPEC 2138c2ecf20Sopenharmony_ci : __HYPERCALL_5PARAM 2148c2ecf20Sopenharmony_ci : [thunk_target] "a" (&hypercall_page[call]) 2158c2ecf20Sopenharmony_ci : __HYPERCALL_CLOBBER5); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci return (long)__res; 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic __always_inline void __xen_stac(void) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci /* 2238c2ecf20Sopenharmony_ci * Suppress objtool seeing the STAC/CLAC and getting confused about it 2248c2ecf20Sopenharmony_ci * calling random code with AC=1. 2258c2ecf20Sopenharmony_ci */ 2268c2ecf20Sopenharmony_ci asm volatile(ANNOTATE_IGNORE_ALTERNATIVE 2278c2ecf20Sopenharmony_ci ASM_STAC ::: "memory", "flags"); 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic __always_inline void __xen_clac(void) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci asm volatile(ANNOTATE_IGNORE_ALTERNATIVE 2338c2ecf20Sopenharmony_ci ASM_CLAC ::: "memory", "flags"); 2348c2ecf20Sopenharmony_ci} 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic inline long 2378c2ecf20Sopenharmony_ciprivcmd_call(unsigned int call, 2388c2ecf20Sopenharmony_ci unsigned long a1, unsigned long a2, 2398c2ecf20Sopenharmony_ci unsigned long a3, unsigned long a4, 2408c2ecf20Sopenharmony_ci unsigned long a5) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci long res; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci __xen_stac(); 2458c2ecf20Sopenharmony_ci res = xen_single_call(call, a1, a2, a3, a4, a5); 2468c2ecf20Sopenharmony_ci __xen_clac(); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci return res; 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic inline int 2528c2ecf20Sopenharmony_ciHYPERVISOR_set_trap_table(struct trap_info *table) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci return _hypercall1(int, set_trap_table, table); 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistatic inline int 2588c2ecf20Sopenharmony_ciHYPERVISOR_mmu_update(struct mmu_update *req, int count, 2598c2ecf20Sopenharmony_ci int *success_count, domid_t domid) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci return _hypercall4(int, mmu_update, req, count, success_count, domid); 2628c2ecf20Sopenharmony_ci} 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cistatic inline int 2658c2ecf20Sopenharmony_ciHYPERVISOR_mmuext_op(struct mmuext_op *op, int count, 2668c2ecf20Sopenharmony_ci int *success_count, domid_t domid) 2678c2ecf20Sopenharmony_ci{ 2688c2ecf20Sopenharmony_ci return _hypercall4(int, mmuext_op, op, count, success_count, domid); 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_cistatic inline int 2728c2ecf20Sopenharmony_ciHYPERVISOR_set_gdt(unsigned long *frame_list, int entries) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci return _hypercall2(int, set_gdt, frame_list, entries); 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic inline int 2788c2ecf20Sopenharmony_ciHYPERVISOR_callback_op(int cmd, void *arg) 2798c2ecf20Sopenharmony_ci{ 2808c2ecf20Sopenharmony_ci return _hypercall2(int, callback_op, cmd, arg); 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic inline int 2848c2ecf20Sopenharmony_ciHYPERVISOR_sched_op(int cmd, void *arg) 2858c2ecf20Sopenharmony_ci{ 2868c2ecf20Sopenharmony_ci return _hypercall2(int, sched_op, cmd, arg); 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic inline long 2908c2ecf20Sopenharmony_ciHYPERVISOR_set_timer_op(u64 timeout) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci unsigned long timeout_hi = (unsigned long)(timeout>>32); 2938c2ecf20Sopenharmony_ci unsigned long timeout_lo = (unsigned long)timeout; 2948c2ecf20Sopenharmony_ci return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistatic inline int 2988c2ecf20Sopenharmony_ciHYPERVISOR_mca(struct xen_mc *mc_op) 2998c2ecf20Sopenharmony_ci{ 3008c2ecf20Sopenharmony_ci mc_op->interface_version = XEN_MCA_INTERFACE_VERSION; 3018c2ecf20Sopenharmony_ci return _hypercall1(int, mca, mc_op); 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic inline int 3058c2ecf20Sopenharmony_ciHYPERVISOR_platform_op(struct xen_platform_op *op) 3068c2ecf20Sopenharmony_ci{ 3078c2ecf20Sopenharmony_ci op->interface_version = XENPF_INTERFACE_VERSION; 3088c2ecf20Sopenharmony_ci return _hypercall1(int, platform_op, op); 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic inline int 3128c2ecf20Sopenharmony_ciHYPERVISOR_set_debugreg(int reg, unsigned long value) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci return _hypercall2(int, set_debugreg, reg, value); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic inline unsigned long 3188c2ecf20Sopenharmony_ciHYPERVISOR_get_debugreg(int reg) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci return _hypercall1(unsigned long, get_debugreg, reg); 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_cistatic inline int 3248c2ecf20Sopenharmony_ciHYPERVISOR_update_descriptor(u64 ma, u64 desc) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci if (sizeof(u64) == sizeof(long)) 3278c2ecf20Sopenharmony_ci return _hypercall2(int, update_descriptor, ma, desc); 3288c2ecf20Sopenharmony_ci return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); 3298c2ecf20Sopenharmony_ci} 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_cistatic inline long 3328c2ecf20Sopenharmony_ciHYPERVISOR_memory_op(unsigned int cmd, void *arg) 3338c2ecf20Sopenharmony_ci{ 3348c2ecf20Sopenharmony_ci return _hypercall2(long, memory_op, cmd, arg); 3358c2ecf20Sopenharmony_ci} 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_cistatic inline int 3388c2ecf20Sopenharmony_ciHYPERVISOR_multicall(void *call_list, uint32_t nr_calls) 3398c2ecf20Sopenharmony_ci{ 3408c2ecf20Sopenharmony_ci return _hypercall2(int, multicall, call_list, nr_calls); 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic inline int 3448c2ecf20Sopenharmony_ciHYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, 3458c2ecf20Sopenharmony_ci unsigned long flags) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci if (sizeof(new_val) == sizeof(long)) 3488c2ecf20Sopenharmony_ci return _hypercall3(int, update_va_mapping, va, 3498c2ecf20Sopenharmony_ci new_val.pte, flags); 3508c2ecf20Sopenharmony_ci else 3518c2ecf20Sopenharmony_ci return _hypercall4(int, update_va_mapping, va, 3528c2ecf20Sopenharmony_ci new_val.pte, new_val.pte >> 32, flags); 3538c2ecf20Sopenharmony_ci} 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_cistatic inline int 3568c2ecf20Sopenharmony_ciHYPERVISOR_event_channel_op(int cmd, void *arg) 3578c2ecf20Sopenharmony_ci{ 3588c2ecf20Sopenharmony_ci return _hypercall2(int, event_channel_op, cmd, arg); 3598c2ecf20Sopenharmony_ci} 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_cistatic inline int 3628c2ecf20Sopenharmony_ciHYPERVISOR_xen_version(int cmd, void *arg) 3638c2ecf20Sopenharmony_ci{ 3648c2ecf20Sopenharmony_ci return _hypercall2(int, xen_version, cmd, arg); 3658c2ecf20Sopenharmony_ci} 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_cistatic inline int 3688c2ecf20Sopenharmony_ciHYPERVISOR_console_io(int cmd, int count, char *str) 3698c2ecf20Sopenharmony_ci{ 3708c2ecf20Sopenharmony_ci return _hypercall3(int, console_io, cmd, count, str); 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_cistatic inline int 3748c2ecf20Sopenharmony_ciHYPERVISOR_physdev_op(int cmd, void *arg) 3758c2ecf20Sopenharmony_ci{ 3768c2ecf20Sopenharmony_ci return _hypercall2(int, physdev_op, cmd, arg); 3778c2ecf20Sopenharmony_ci} 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_cistatic inline int 3808c2ecf20Sopenharmony_ciHYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci return _hypercall3(int, grant_table_op, cmd, uop, count); 3838c2ecf20Sopenharmony_ci} 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_cistatic inline int 3868c2ecf20Sopenharmony_ciHYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) 3878c2ecf20Sopenharmony_ci{ 3888c2ecf20Sopenharmony_ci return _hypercall2(int, vm_assist, cmd, type); 3898c2ecf20Sopenharmony_ci} 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_cistatic inline int 3928c2ecf20Sopenharmony_ciHYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args) 3938c2ecf20Sopenharmony_ci{ 3948c2ecf20Sopenharmony_ci return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); 3958c2ecf20Sopenharmony_ci} 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64 3988c2ecf20Sopenharmony_cistatic inline int 3998c2ecf20Sopenharmony_ciHYPERVISOR_set_segment_base(int reg, unsigned long value) 4008c2ecf20Sopenharmony_ci{ 4018c2ecf20Sopenharmony_ci return _hypercall2(int, set_segment_base, reg, value); 4028c2ecf20Sopenharmony_ci} 4038c2ecf20Sopenharmony_ci#endif 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_cistatic inline int 4068c2ecf20Sopenharmony_ciHYPERVISOR_suspend(unsigned long start_info_mfn) 4078c2ecf20Sopenharmony_ci{ 4088c2ecf20Sopenharmony_ci struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci /* 4118c2ecf20Sopenharmony_ci * For a PV guest the tools require that the start_info mfn be 4128c2ecf20Sopenharmony_ci * present in rdx/edx when the hypercall is made. Per the 4138c2ecf20Sopenharmony_ci * hypercall calling convention this is the third hypercall 4148c2ecf20Sopenharmony_ci * argument, which is start_info_mfn here. 4158c2ecf20Sopenharmony_ci */ 4168c2ecf20Sopenharmony_ci return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn); 4178c2ecf20Sopenharmony_ci} 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_cistatic inline unsigned long __must_check 4208c2ecf20Sopenharmony_ciHYPERVISOR_hvm_op(int op, void *arg) 4218c2ecf20Sopenharmony_ci{ 4228c2ecf20Sopenharmony_ci return _hypercall2(unsigned long, hvm_op, op, arg); 4238c2ecf20Sopenharmony_ci} 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_cistatic inline int 4268c2ecf20Sopenharmony_ciHYPERVISOR_tmem_op( 4278c2ecf20Sopenharmony_ci struct tmem_op *op) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci return _hypercall1(int, tmem_op, op); 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_cistatic inline int 4338c2ecf20Sopenharmony_ciHYPERVISOR_xenpmu_op(unsigned int op, void *arg) 4348c2ecf20Sopenharmony_ci{ 4358c2ecf20Sopenharmony_ci return _hypercall2(int, xenpmu_op, op, arg); 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic inline int 4398c2ecf20Sopenharmony_ciHYPERVISOR_dm_op( 4408c2ecf20Sopenharmony_ci domid_t dom, unsigned int nr_bufs, struct xen_dm_op_buf *bufs) 4418c2ecf20Sopenharmony_ci{ 4428c2ecf20Sopenharmony_ci int ret; 4438c2ecf20Sopenharmony_ci __xen_stac(); 4448c2ecf20Sopenharmony_ci ret = _hypercall3(int, dm_op, dom, nr_bufs, bufs); 4458c2ecf20Sopenharmony_ci __xen_clac(); 4468c2ecf20Sopenharmony_ci return ret; 4478c2ecf20Sopenharmony_ci} 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_cistatic inline void 4508c2ecf20Sopenharmony_ciMULTI_fpu_taskswitch(struct multicall_entry *mcl, int set) 4518c2ecf20Sopenharmony_ci{ 4528c2ecf20Sopenharmony_ci mcl->op = __HYPERVISOR_fpu_taskswitch; 4538c2ecf20Sopenharmony_ci mcl->args[0] = set; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci trace_xen_mc_entry(mcl, 1); 4568c2ecf20Sopenharmony_ci} 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_cistatic inline void 4598c2ecf20Sopenharmony_ciMULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va, 4608c2ecf20Sopenharmony_ci pte_t new_val, unsigned long flags) 4618c2ecf20Sopenharmony_ci{ 4628c2ecf20Sopenharmony_ci mcl->op = __HYPERVISOR_update_va_mapping; 4638c2ecf20Sopenharmony_ci mcl->args[0] = va; 4648c2ecf20Sopenharmony_ci if (sizeof(new_val) == sizeof(long)) { 4658c2ecf20Sopenharmony_ci mcl->args[1] = new_val.pte; 4668c2ecf20Sopenharmony_ci mcl->args[2] = flags; 4678c2ecf20Sopenharmony_ci } else { 4688c2ecf20Sopenharmony_ci mcl->args[1] = new_val.pte; 4698c2ecf20Sopenharmony_ci mcl->args[2] = new_val.pte >> 32; 4708c2ecf20Sopenharmony_ci mcl->args[3] = flags; 4718c2ecf20Sopenharmony_ci } 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 3 : 4); 4748c2ecf20Sopenharmony_ci} 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_cistatic inline void 4778c2ecf20Sopenharmony_ciMULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, 4788c2ecf20Sopenharmony_ci struct desc_struct desc) 4798c2ecf20Sopenharmony_ci{ 4808c2ecf20Sopenharmony_ci mcl->op = __HYPERVISOR_update_descriptor; 4818c2ecf20Sopenharmony_ci if (sizeof(maddr) == sizeof(long)) { 4828c2ecf20Sopenharmony_ci mcl->args[0] = maddr; 4838c2ecf20Sopenharmony_ci mcl->args[1] = *(unsigned long *)&desc; 4848c2ecf20Sopenharmony_ci } else { 4858c2ecf20Sopenharmony_ci u32 *p = (u32 *)&desc; 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci mcl->args[0] = maddr; 4888c2ecf20Sopenharmony_ci mcl->args[1] = maddr >> 32; 4898c2ecf20Sopenharmony_ci mcl->args[2] = *p++; 4908c2ecf20Sopenharmony_ci mcl->args[3] = *p; 4918c2ecf20Sopenharmony_ci } 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4); 4948c2ecf20Sopenharmony_ci} 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_cistatic inline void 4978c2ecf20Sopenharmony_ciMULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req, 4988c2ecf20Sopenharmony_ci int count, int *success_count, domid_t domid) 4998c2ecf20Sopenharmony_ci{ 5008c2ecf20Sopenharmony_ci mcl->op = __HYPERVISOR_mmu_update; 5018c2ecf20Sopenharmony_ci mcl->args[0] = (unsigned long)req; 5028c2ecf20Sopenharmony_ci mcl->args[1] = count; 5038c2ecf20Sopenharmony_ci mcl->args[2] = (unsigned long)success_count; 5048c2ecf20Sopenharmony_ci mcl->args[3] = domid; 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci trace_xen_mc_entry(mcl, 4); 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_cistatic inline void 5108c2ecf20Sopenharmony_ciMULTI_mmuext_op(struct multicall_entry *mcl, struct mmuext_op *op, int count, 5118c2ecf20Sopenharmony_ci int *success_count, domid_t domid) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci mcl->op = __HYPERVISOR_mmuext_op; 5148c2ecf20Sopenharmony_ci mcl->args[0] = (unsigned long)op; 5158c2ecf20Sopenharmony_ci mcl->args[1] = count; 5168c2ecf20Sopenharmony_ci mcl->args[2] = (unsigned long)success_count; 5178c2ecf20Sopenharmony_ci mcl->args[3] = domid; 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci trace_xen_mc_entry(mcl, 4); 5208c2ecf20Sopenharmony_ci} 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic inline void 5238c2ecf20Sopenharmony_ciMULTI_stack_switch(struct multicall_entry *mcl, 5248c2ecf20Sopenharmony_ci unsigned long ss, unsigned long esp) 5258c2ecf20Sopenharmony_ci{ 5268c2ecf20Sopenharmony_ci mcl->op = __HYPERVISOR_stack_switch; 5278c2ecf20Sopenharmony_ci mcl->args[0] = ss; 5288c2ecf20Sopenharmony_ci mcl->args[1] = esp; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci trace_xen_mc_entry(mcl, 2); 5318c2ecf20Sopenharmony_ci} 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci#endif /* _ASM_X86_XEN_HYPERCALL_H */ 534