162306a36Sopenharmony_ci/****************************************************************************** 262306a36Sopenharmony_ci * hypercall.h 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Linux-specific hypervisor handling. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 2002-2004, K A Fraser 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or 962306a36Sopenharmony_ci * modify it under the terms of the GNU General Public License version 2 1062306a36Sopenharmony_ci * as published by the Free Software Foundation; or, when distributed 1162306a36Sopenharmony_ci * separately from the Linux kernel or incorporated into other 1262306a36Sopenharmony_ci * software packages, subject to the following license: 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 1562306a36Sopenharmony_ci * of this source file (the "Software"), to deal in the Software without 1662306a36Sopenharmony_ci * restriction, including without limitation the rights to use, copy, modify, 1762306a36Sopenharmony_ci * merge, publish, distribute, sublicense, and/or sell copies of the Software, 1862306a36Sopenharmony_ci * and to permit persons to whom the Software is furnished to do so, subject to 1962306a36Sopenharmony_ci * the following conditions: 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 2262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2762306a36Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2862306a36Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2962306a36Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 3062306a36Sopenharmony_ci * IN THE SOFTWARE. 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#ifndef _ASM_X86_XEN_HYPERCALL_H 3462306a36Sopenharmony_ci#define _ASM_X86_XEN_HYPERCALL_H 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#include <linux/kernel.h> 3762306a36Sopenharmony_ci#include <linux/spinlock.h> 3862306a36Sopenharmony_ci#include <linux/errno.h> 3962306a36Sopenharmony_ci#include <linux/string.h> 4062306a36Sopenharmony_ci#include <linux/types.h> 4162306a36Sopenharmony_ci#include <linux/pgtable.h> 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#include <trace/events/xen.h> 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#include <asm/page.h> 4662306a36Sopenharmony_ci#include <asm/smap.h> 4762306a36Sopenharmony_ci#include <asm/nospec-branch.h> 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#include <xen/interface/xen.h> 5062306a36Sopenharmony_ci#include <xen/interface/sched.h> 5162306a36Sopenharmony_ci#include <xen/interface/physdev.h> 5262306a36Sopenharmony_ci#include <xen/interface/platform.h> 5362306a36Sopenharmony_ci#include <xen/interface/xen-mca.h> 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistruct xen_dm_op_buf; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci/* 5862306a36Sopenharmony_ci * The hypercall asms have to meet several constraints: 5962306a36Sopenharmony_ci * - Work on 32- and 64-bit. 6062306a36Sopenharmony_ci * The two architectures put their arguments in different sets of 6162306a36Sopenharmony_ci * registers. 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * - Work around asm syntax quirks 6462306a36Sopenharmony_ci * It isn't possible to specify one of the rNN registers in a 6562306a36Sopenharmony_ci * constraint, so we use explicit register variables to get the 6662306a36Sopenharmony_ci * args into the right place. 6762306a36Sopenharmony_ci * 6862306a36Sopenharmony_ci * - Mark all registers as potentially clobbered 6962306a36Sopenharmony_ci * Even unused parameters can be clobbered by the hypervisor, so we 7062306a36Sopenharmony_ci * need to make sure gcc knows it. 7162306a36Sopenharmony_ci * 7262306a36Sopenharmony_ci * - Avoid compiler bugs. 7362306a36Sopenharmony_ci * This is the tricky part. Because x86_32 has such a constrained 7462306a36Sopenharmony_ci * register set, gcc versions below 4.3 have trouble generating 7562306a36Sopenharmony_ci * code when all the arg registers and memory are trashed by the 7662306a36Sopenharmony_ci * asm. There are syntactically simpler ways of achieving the 7762306a36Sopenharmony_ci * semantics below, but they cause the compiler to crash. 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * The only combination I found which works is: 8062306a36Sopenharmony_ci * - assign the __argX variables first 8162306a36Sopenharmony_ci * - list all actually used parameters as "+r" (__argX) 8262306a36Sopenharmony_ci * - clobber the rest 8362306a36Sopenharmony_ci * 8462306a36Sopenharmony_ci * The result certainly isn't pretty, and it really shows up cpp's 8562306a36Sopenharmony_ci * weakness as a macro language. Sorry. (But let's just give thanks 8662306a36Sopenharmony_ci * there aren't more than 5 arguments...) 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciextern struct { char _entry[32]; } hypercall_page[]; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci#define __HYPERCALL "call hypercall_page+%c[offset]" 9262306a36Sopenharmony_ci#define __HYPERCALL_ENTRY(x) \ 9362306a36Sopenharmony_ci [offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0])) 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#ifdef CONFIG_X86_32 9662306a36Sopenharmony_ci#define __HYPERCALL_RETREG "eax" 9762306a36Sopenharmony_ci#define __HYPERCALL_ARG1REG "ebx" 9862306a36Sopenharmony_ci#define __HYPERCALL_ARG2REG "ecx" 9962306a36Sopenharmony_ci#define __HYPERCALL_ARG3REG "edx" 10062306a36Sopenharmony_ci#define __HYPERCALL_ARG4REG "esi" 10162306a36Sopenharmony_ci#define __HYPERCALL_ARG5REG "edi" 10262306a36Sopenharmony_ci#else 10362306a36Sopenharmony_ci#define __HYPERCALL_RETREG "rax" 10462306a36Sopenharmony_ci#define __HYPERCALL_ARG1REG "rdi" 10562306a36Sopenharmony_ci#define __HYPERCALL_ARG2REG "rsi" 10662306a36Sopenharmony_ci#define __HYPERCALL_ARG3REG "rdx" 10762306a36Sopenharmony_ci#define __HYPERCALL_ARG4REG "r10" 10862306a36Sopenharmony_ci#define __HYPERCALL_ARG5REG "r8" 10962306a36Sopenharmony_ci#endif 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define __HYPERCALL_DECLS \ 11262306a36Sopenharmony_ci register unsigned long __res asm(__HYPERCALL_RETREG); \ 11362306a36Sopenharmony_ci register unsigned long __arg1 asm(__HYPERCALL_ARG1REG) = __arg1; \ 11462306a36Sopenharmony_ci register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ 11562306a36Sopenharmony_ci register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ 11662306a36Sopenharmony_ci register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ 11762306a36Sopenharmony_ci register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#define __HYPERCALL_0PARAM "=r" (__res), ASM_CALL_CONSTRAINT 12062306a36Sopenharmony_ci#define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) 12162306a36Sopenharmony_ci#define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) 12262306a36Sopenharmony_ci#define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) 12362306a36Sopenharmony_ci#define __HYPERCALL_4PARAM __HYPERCALL_3PARAM, "+r" (__arg4) 12462306a36Sopenharmony_ci#define __HYPERCALL_5PARAM __HYPERCALL_4PARAM, "+r" (__arg5) 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#define __HYPERCALL_0ARG() 12762306a36Sopenharmony_ci#define __HYPERCALL_1ARG(a1) \ 12862306a36Sopenharmony_ci __HYPERCALL_0ARG() __arg1 = (unsigned long)(a1); 12962306a36Sopenharmony_ci#define __HYPERCALL_2ARG(a1,a2) \ 13062306a36Sopenharmony_ci __HYPERCALL_1ARG(a1) __arg2 = (unsigned long)(a2); 13162306a36Sopenharmony_ci#define __HYPERCALL_3ARG(a1,a2,a3) \ 13262306a36Sopenharmony_ci __HYPERCALL_2ARG(a1,a2) __arg3 = (unsigned long)(a3); 13362306a36Sopenharmony_ci#define __HYPERCALL_4ARG(a1,a2,a3,a4) \ 13462306a36Sopenharmony_ci __HYPERCALL_3ARG(a1,a2,a3) __arg4 = (unsigned long)(a4); 13562306a36Sopenharmony_ci#define __HYPERCALL_5ARG(a1,a2,a3,a4,a5) \ 13662306a36Sopenharmony_ci __HYPERCALL_4ARG(a1,a2,a3,a4) __arg5 = (unsigned long)(a5); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci#define __HYPERCALL_CLOBBER5 "memory" 13962306a36Sopenharmony_ci#define __HYPERCALL_CLOBBER4 __HYPERCALL_CLOBBER5, __HYPERCALL_ARG5REG 14062306a36Sopenharmony_ci#define __HYPERCALL_CLOBBER3 __HYPERCALL_CLOBBER4, __HYPERCALL_ARG4REG 14162306a36Sopenharmony_ci#define __HYPERCALL_CLOBBER2 __HYPERCALL_CLOBBER3, __HYPERCALL_ARG3REG 14262306a36Sopenharmony_ci#define __HYPERCALL_CLOBBER1 __HYPERCALL_CLOBBER2, __HYPERCALL_ARG2REG 14362306a36Sopenharmony_ci#define __HYPERCALL_CLOBBER0 __HYPERCALL_CLOBBER1, __HYPERCALL_ARG1REG 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci#define _hypercall0(type, name) \ 14662306a36Sopenharmony_ci({ \ 14762306a36Sopenharmony_ci __HYPERCALL_DECLS; \ 14862306a36Sopenharmony_ci __HYPERCALL_0ARG(); \ 14962306a36Sopenharmony_ci asm volatile (__HYPERCALL \ 15062306a36Sopenharmony_ci : __HYPERCALL_0PARAM \ 15162306a36Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 15262306a36Sopenharmony_ci : __HYPERCALL_CLOBBER0); \ 15362306a36Sopenharmony_ci (type)__res; \ 15462306a36Sopenharmony_ci}) 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci#define _hypercall1(type, name, a1) \ 15762306a36Sopenharmony_ci({ \ 15862306a36Sopenharmony_ci __HYPERCALL_DECLS; \ 15962306a36Sopenharmony_ci __HYPERCALL_1ARG(a1); \ 16062306a36Sopenharmony_ci asm volatile (__HYPERCALL \ 16162306a36Sopenharmony_ci : __HYPERCALL_1PARAM \ 16262306a36Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 16362306a36Sopenharmony_ci : __HYPERCALL_CLOBBER1); \ 16462306a36Sopenharmony_ci (type)__res; \ 16562306a36Sopenharmony_ci}) 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci#define _hypercall2(type, name, a1, a2) \ 16862306a36Sopenharmony_ci({ \ 16962306a36Sopenharmony_ci __HYPERCALL_DECLS; \ 17062306a36Sopenharmony_ci __HYPERCALL_2ARG(a1, a2); \ 17162306a36Sopenharmony_ci asm volatile (__HYPERCALL \ 17262306a36Sopenharmony_ci : __HYPERCALL_2PARAM \ 17362306a36Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 17462306a36Sopenharmony_ci : __HYPERCALL_CLOBBER2); \ 17562306a36Sopenharmony_ci (type)__res; \ 17662306a36Sopenharmony_ci}) 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci#define _hypercall3(type, name, a1, a2, a3) \ 17962306a36Sopenharmony_ci({ \ 18062306a36Sopenharmony_ci __HYPERCALL_DECLS; \ 18162306a36Sopenharmony_ci __HYPERCALL_3ARG(a1, a2, a3); \ 18262306a36Sopenharmony_ci asm volatile (__HYPERCALL \ 18362306a36Sopenharmony_ci : __HYPERCALL_3PARAM \ 18462306a36Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 18562306a36Sopenharmony_ci : __HYPERCALL_CLOBBER3); \ 18662306a36Sopenharmony_ci (type)__res; \ 18762306a36Sopenharmony_ci}) 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci#define _hypercall4(type, name, a1, a2, a3, a4) \ 19062306a36Sopenharmony_ci({ \ 19162306a36Sopenharmony_ci __HYPERCALL_DECLS; \ 19262306a36Sopenharmony_ci __HYPERCALL_4ARG(a1, a2, a3, a4); \ 19362306a36Sopenharmony_ci asm volatile (__HYPERCALL \ 19462306a36Sopenharmony_ci : __HYPERCALL_4PARAM \ 19562306a36Sopenharmony_ci : __HYPERCALL_ENTRY(name) \ 19662306a36Sopenharmony_ci : __HYPERCALL_CLOBBER4); \ 19762306a36Sopenharmony_ci (type)__res; \ 19862306a36Sopenharmony_ci}) 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cistatic inline long 20162306a36Sopenharmony_cixen_single_call(unsigned int call, 20262306a36Sopenharmony_ci unsigned long a1, unsigned long a2, 20362306a36Sopenharmony_ci unsigned long a3, unsigned long a4, 20462306a36Sopenharmony_ci unsigned long a5) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci __HYPERCALL_DECLS; 20762306a36Sopenharmony_ci __HYPERCALL_5ARG(a1, a2, a3, a4, a5); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci if (call >= PAGE_SIZE / sizeof(hypercall_page[0])) 21062306a36Sopenharmony_ci return -EINVAL; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci asm volatile(CALL_NOSPEC 21362306a36Sopenharmony_ci : __HYPERCALL_5PARAM 21462306a36Sopenharmony_ci : [thunk_target] "a" (&hypercall_page[call]) 21562306a36Sopenharmony_ci : __HYPERCALL_CLOBBER5); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci return (long)__res; 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic __always_inline void __xen_stac(void) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci /* 22362306a36Sopenharmony_ci * Suppress objtool seeing the STAC/CLAC and getting confused about it 22462306a36Sopenharmony_ci * calling random code with AC=1. 22562306a36Sopenharmony_ci */ 22662306a36Sopenharmony_ci asm volatile(ANNOTATE_IGNORE_ALTERNATIVE 22762306a36Sopenharmony_ci ASM_STAC ::: "memory", "flags"); 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_cistatic __always_inline void __xen_clac(void) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci asm volatile(ANNOTATE_IGNORE_ALTERNATIVE 23362306a36Sopenharmony_ci ASM_CLAC ::: "memory", "flags"); 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic inline long 23762306a36Sopenharmony_ciprivcmd_call(unsigned int call, 23862306a36Sopenharmony_ci unsigned long a1, unsigned long a2, 23962306a36Sopenharmony_ci unsigned long a3, unsigned long a4, 24062306a36Sopenharmony_ci unsigned long a5) 24162306a36Sopenharmony_ci{ 24262306a36Sopenharmony_ci long res; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci __xen_stac(); 24562306a36Sopenharmony_ci res = xen_single_call(call, a1, a2, a3, a4, a5); 24662306a36Sopenharmony_ci __xen_clac(); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci return res; 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci#ifdef CONFIG_XEN_PV 25262306a36Sopenharmony_cistatic inline int 25362306a36Sopenharmony_ciHYPERVISOR_set_trap_table(struct trap_info *table) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci return _hypercall1(int, set_trap_table, table); 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic inline int 25962306a36Sopenharmony_ciHYPERVISOR_mmu_update(struct mmu_update *req, int count, 26062306a36Sopenharmony_ci int *success_count, domid_t domid) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci return _hypercall4(int, mmu_update, req, count, success_count, domid); 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistatic inline int 26662306a36Sopenharmony_ciHYPERVISOR_mmuext_op(struct mmuext_op *op, int count, 26762306a36Sopenharmony_ci int *success_count, domid_t domid) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci return _hypercall4(int, mmuext_op, op, count, success_count, domid); 27062306a36Sopenharmony_ci} 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_cistatic inline int 27362306a36Sopenharmony_ciHYPERVISOR_set_gdt(unsigned long *frame_list, int entries) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci return _hypercall2(int, set_gdt, frame_list, entries); 27662306a36Sopenharmony_ci} 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cistatic inline int 27962306a36Sopenharmony_ciHYPERVISOR_callback_op(int cmd, void *arg) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci return _hypercall2(int, callback_op, cmd, arg); 28262306a36Sopenharmony_ci} 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic __always_inline int 28562306a36Sopenharmony_ciHYPERVISOR_set_debugreg(int reg, unsigned long value) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci return _hypercall2(int, set_debugreg, reg, value); 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic __always_inline unsigned long 29162306a36Sopenharmony_ciHYPERVISOR_get_debugreg(int reg) 29262306a36Sopenharmony_ci{ 29362306a36Sopenharmony_ci return _hypercall1(unsigned long, get_debugreg, reg); 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic inline int 29762306a36Sopenharmony_ciHYPERVISOR_update_descriptor(u64 ma, u64 desc) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci return _hypercall2(int, update_descriptor, ma, desc); 30062306a36Sopenharmony_ci} 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_cistatic inline int 30362306a36Sopenharmony_ciHYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, 30462306a36Sopenharmony_ci unsigned long flags) 30562306a36Sopenharmony_ci{ 30662306a36Sopenharmony_ci return _hypercall3(int, update_va_mapping, va, new_val.pte, flags); 30762306a36Sopenharmony_ci} 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_cistatic inline int 31062306a36Sopenharmony_ciHYPERVISOR_set_segment_base(int reg, unsigned long value) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci return _hypercall2(int, set_segment_base, reg, value); 31362306a36Sopenharmony_ci} 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic inline void 31662306a36Sopenharmony_ciMULTI_fpu_taskswitch(struct multicall_entry *mcl, int set) 31762306a36Sopenharmony_ci{ 31862306a36Sopenharmony_ci mcl->op = __HYPERVISOR_fpu_taskswitch; 31962306a36Sopenharmony_ci mcl->args[0] = set; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci trace_xen_mc_entry(mcl, 1); 32262306a36Sopenharmony_ci} 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_cistatic inline void 32562306a36Sopenharmony_ciMULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va, 32662306a36Sopenharmony_ci pte_t new_val, unsigned long flags) 32762306a36Sopenharmony_ci{ 32862306a36Sopenharmony_ci mcl->op = __HYPERVISOR_update_va_mapping; 32962306a36Sopenharmony_ci mcl->args[0] = va; 33062306a36Sopenharmony_ci mcl->args[1] = new_val.pte; 33162306a36Sopenharmony_ci mcl->args[2] = flags; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci trace_xen_mc_entry(mcl, 3); 33462306a36Sopenharmony_ci} 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistatic inline void 33762306a36Sopenharmony_ciMULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, 33862306a36Sopenharmony_ci struct desc_struct desc) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci mcl->op = __HYPERVISOR_update_descriptor; 34162306a36Sopenharmony_ci mcl->args[0] = maddr; 34262306a36Sopenharmony_ci mcl->args[1] = *(unsigned long *)&desc; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci trace_xen_mc_entry(mcl, 2); 34562306a36Sopenharmony_ci} 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_cistatic inline void 34862306a36Sopenharmony_ciMULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req, 34962306a36Sopenharmony_ci int count, int *success_count, domid_t domid) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci mcl->op = __HYPERVISOR_mmu_update; 35262306a36Sopenharmony_ci mcl->args[0] = (unsigned long)req; 35362306a36Sopenharmony_ci mcl->args[1] = count; 35462306a36Sopenharmony_ci mcl->args[2] = (unsigned long)success_count; 35562306a36Sopenharmony_ci mcl->args[3] = domid; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci trace_xen_mc_entry(mcl, 4); 35862306a36Sopenharmony_ci} 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_cistatic inline void 36162306a36Sopenharmony_ciMULTI_mmuext_op(struct multicall_entry *mcl, struct mmuext_op *op, int count, 36262306a36Sopenharmony_ci int *success_count, domid_t domid) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci mcl->op = __HYPERVISOR_mmuext_op; 36562306a36Sopenharmony_ci mcl->args[0] = (unsigned long)op; 36662306a36Sopenharmony_ci mcl->args[1] = count; 36762306a36Sopenharmony_ci mcl->args[2] = (unsigned long)success_count; 36862306a36Sopenharmony_ci mcl->args[3] = domid; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci trace_xen_mc_entry(mcl, 4); 37162306a36Sopenharmony_ci} 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_cistatic inline void 37462306a36Sopenharmony_ciMULTI_stack_switch(struct multicall_entry *mcl, 37562306a36Sopenharmony_ci unsigned long ss, unsigned long esp) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci mcl->op = __HYPERVISOR_stack_switch; 37862306a36Sopenharmony_ci mcl->args[0] = ss; 37962306a36Sopenharmony_ci mcl->args[1] = esp; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci trace_xen_mc_entry(mcl, 2); 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci#endif 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cistatic __always_inline int 38662306a36Sopenharmony_ciHYPERVISOR_sched_op(int cmd, void *arg) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci return _hypercall2(int, sched_op, cmd, arg); 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cistatic inline long 39262306a36Sopenharmony_ciHYPERVISOR_set_timer_op(u64 timeout) 39362306a36Sopenharmony_ci{ 39462306a36Sopenharmony_ci unsigned long timeout_hi = (unsigned long)(timeout>>32); 39562306a36Sopenharmony_ci unsigned long timeout_lo = (unsigned long)timeout; 39662306a36Sopenharmony_ci return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); 39762306a36Sopenharmony_ci} 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_cistatic inline int 40062306a36Sopenharmony_ciHYPERVISOR_mca(struct xen_mc *mc_op) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci mc_op->interface_version = XEN_MCA_INTERFACE_VERSION; 40362306a36Sopenharmony_ci return _hypercall1(int, mca, mc_op); 40462306a36Sopenharmony_ci} 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_cistatic inline int 40762306a36Sopenharmony_ciHYPERVISOR_platform_op(struct xen_platform_op *op) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci op->interface_version = XENPF_INTERFACE_VERSION; 41062306a36Sopenharmony_ci return _hypercall1(int, platform_op, op); 41162306a36Sopenharmony_ci} 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_cistatic inline long 41462306a36Sopenharmony_ciHYPERVISOR_memory_op(unsigned int cmd, void *arg) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci return _hypercall2(long, memory_op, cmd, arg); 41762306a36Sopenharmony_ci} 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_cistatic inline int 42062306a36Sopenharmony_ciHYPERVISOR_multicall(void *call_list, uint32_t nr_calls) 42162306a36Sopenharmony_ci{ 42262306a36Sopenharmony_ci return _hypercall2(int, multicall, call_list, nr_calls); 42362306a36Sopenharmony_ci} 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_cistatic inline int 42662306a36Sopenharmony_ciHYPERVISOR_event_channel_op(int cmd, void *arg) 42762306a36Sopenharmony_ci{ 42862306a36Sopenharmony_ci return _hypercall2(int, event_channel_op, cmd, arg); 42962306a36Sopenharmony_ci} 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_cistatic __always_inline int 43262306a36Sopenharmony_ciHYPERVISOR_xen_version(int cmd, void *arg) 43362306a36Sopenharmony_ci{ 43462306a36Sopenharmony_ci return _hypercall2(int, xen_version, cmd, arg); 43562306a36Sopenharmony_ci} 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_cistatic inline int 43862306a36Sopenharmony_ciHYPERVISOR_console_io(int cmd, int count, char *str) 43962306a36Sopenharmony_ci{ 44062306a36Sopenharmony_ci return _hypercall3(int, console_io, cmd, count, str); 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_cistatic inline int 44462306a36Sopenharmony_ciHYPERVISOR_physdev_op(int cmd, void *arg) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci return _hypercall2(int, physdev_op, cmd, arg); 44762306a36Sopenharmony_ci} 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_cistatic inline int 45062306a36Sopenharmony_ciHYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) 45162306a36Sopenharmony_ci{ 45262306a36Sopenharmony_ci return _hypercall3(int, grant_table_op, cmd, uop, count); 45362306a36Sopenharmony_ci} 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_cistatic inline int 45662306a36Sopenharmony_ciHYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) 45762306a36Sopenharmony_ci{ 45862306a36Sopenharmony_ci return _hypercall2(int, vm_assist, cmd, type); 45962306a36Sopenharmony_ci} 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cistatic inline int 46262306a36Sopenharmony_ciHYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); 46562306a36Sopenharmony_ci} 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_cistatic inline int 46862306a36Sopenharmony_ciHYPERVISOR_suspend(unsigned long start_info_mfn) 46962306a36Sopenharmony_ci{ 47062306a36Sopenharmony_ci struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci /* 47362306a36Sopenharmony_ci * For a PV guest the tools require that the start_info mfn be 47462306a36Sopenharmony_ci * present in rdx/edx when the hypercall is made. Per the 47562306a36Sopenharmony_ci * hypercall calling convention this is the third hypercall 47662306a36Sopenharmony_ci * argument, which is start_info_mfn here. 47762306a36Sopenharmony_ci */ 47862306a36Sopenharmony_ci return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn); 47962306a36Sopenharmony_ci} 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistatic inline unsigned long __must_check 48262306a36Sopenharmony_ciHYPERVISOR_hvm_op(int op, void *arg) 48362306a36Sopenharmony_ci{ 48462306a36Sopenharmony_ci return _hypercall2(unsigned long, hvm_op, op, arg); 48562306a36Sopenharmony_ci} 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_cistatic inline int 48862306a36Sopenharmony_ciHYPERVISOR_xenpmu_op(unsigned int op, void *arg) 48962306a36Sopenharmony_ci{ 49062306a36Sopenharmony_ci return _hypercall2(int, xenpmu_op, op, arg); 49162306a36Sopenharmony_ci} 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_cistatic inline int 49462306a36Sopenharmony_ciHYPERVISOR_dm_op( 49562306a36Sopenharmony_ci domid_t dom, unsigned int nr_bufs, struct xen_dm_op_buf *bufs) 49662306a36Sopenharmony_ci{ 49762306a36Sopenharmony_ci int ret; 49862306a36Sopenharmony_ci __xen_stac(); 49962306a36Sopenharmony_ci ret = _hypercall3(int, dm_op, dom, nr_bufs, bufs); 50062306a36Sopenharmony_ci __xen_clac(); 50162306a36Sopenharmony_ci return ret; 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci#endif /* _ASM_X86_XEN_HYPERCALL_H */ 505