diff --git a/sys/amd64/include/xen/hypercall.h b/sys/amd64/include/xen/hypercall.h --- a/sys/amd64/include/xen/hypercall.h +++ b/sys/amd64/include/xen/hypercall.h @@ -1,30 +1,32 @@ /****************************************************************************** + * SPDX-License-Identifier: MIT OR GPL-2.0-only + * * hypercall.h - * + * * FreeBSD-specific hypervisor handling. - * + * * Copyright (c) 2002-2004, K A Fraser - * + * * 64-bit updates: * Benjamin Liu * Jun Nakajima - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -39,8 +41,6 @@ #ifndef __MACHINE_XEN_HYPERCALL_H__ #define __MACHINE_XEN_HYPERCALL_H__ -#include - #ifndef __XEN_HYPERVISOR_H__ # error "please don't include this file directly" #endif @@ -54,22 +54,22 @@ #define HYPERCALL_STR(name) \ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)" -#define _hypercall0(type, name) \ -({ \ - type __res; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res) \ - : \ - : "memory" ); \ - __res; \ +#define _hypercall0(type, name) \ +({ \ + type __res; \ + __asm__ volatile ( \ + HYPERCALL_STR(name) \ + : "=a" (__res) \ + : \ + : "memory" ); \ + __res; \ }) #define _hypercall1(type, name, a1) \ ({ \ type __res; \ long __ign1; \ - __asm__ volatile ( \ + __asm__ volatile ( \ HYPERCALL_STR(name) \ : "=a" (__res), "=D" (__ign1) \ : "1" ((long)(a1)) \ @@ -81,7 +81,7 @@ ({ \ type __res; \ long __ign1, __ign2; \ - __asm__ volatile ( \ + __asm__ volatile ( \ HYPERCALL_STR(name) \ : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \ : "1" ((long)(a1)), "2" ((long)(a2)) \ @@ -93,9 +93,9 @@ ({ \ type __res; \ long __ign1, __ign2, __ign3; \ - __asm__ volatile ( \ + __asm__ volatile ( \ HYPERCALL_STR(name) \ - : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ + : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ "=d" (__ign3) \ : "1" ((long)(a1)), "2" ((long)(a2)), \ "3" ((long)(a3)) \ @@ -107,8 +107,8 @@ ({ \ type __res; \ long __ign1, __ign2, __ign3; \ - register long __arg4 __asm__("r10") = (long)(a4); \ - __asm__ volatile ( \ + register long __arg4 __asm__("r10") = (long)(a4); \ + __asm__ volatile ( \ HYPERCALL_STR(name) \ : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ "=d" (__ign3), "+r" (__arg4) \ @@ -122,9 +122,9 @@ ({ \ type __res; \ long __ign1, __ign2, __ign3; \ - register long __arg4 __asm__("r10") = (long)(a4); \ - register long __arg5 __asm__("r8") = (long)(a5); \ - __asm__ volatile ( \ + register long __arg4 __asm__("r10") = (long)(a4); \ + register long __arg5 __asm__("r8") = (long)(a5); \ + __asm__ volatile ( \ HYPERCALL_STR(name) \ : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ "=d" (__ign3), "+r" (__arg4), "+r" (__arg5) \ @@ -164,227 +164,8 @@ return _hypercall1(int, set_trap_table, table); } -static inline int __must_check -HYPERVISOR_mmu_update( - mmu_update_t *req, unsigned int count, unsigned int *success_count, - domid_t domid) -{ - return _hypercall4(int, mmu_update, req, count, success_count, domid); -} - -static inline int __must_check -HYPERVISOR_mmuext_op( - struct mmuext_op *op, unsigned int count, unsigned int *success_count, - domid_t domid) -{ - return _hypercall4(int, mmuext_op, op, count, success_count, domid); -} - -static inline int __must_check -HYPERVISOR_set_gdt( - unsigned long *frame_list, unsigned int entries) -{ - return _hypercall2(int, set_gdt, frame_list, entries); -} - -static inline int __must_check -HYPERVISOR_stack_switch( - unsigned long ss, unsigned long esp) -{ - return _hypercall2(int, stack_switch, ss, esp); -} - -static inline int __must_check -HYPERVISOR_set_callbacks( - unsigned long event_address, unsigned long failsafe_address, - unsigned long syscall_address) -{ - return _hypercall3(int, set_callbacks, - event_address, failsafe_address, syscall_address); -} - -static inline int -HYPERVISOR_fpu_taskswitch( - int set) -{ - return _hypercall1(int, fpu_taskswitch, set); -} - -static inline int __must_check -HYPERVISOR_sched_op( - int cmd, void *arg) -{ - return _hypercall2(int, sched_op, cmd, arg); -} - -static inline long __must_check -HYPERVISOR_set_timer_op( - uint64_t timeout) -{ - return _hypercall1(long, set_timer_op, timeout); -} - -static inline int __must_check -HYPERVISOR_platform_op( - struct xen_platform_op *platform_op) -{ - platform_op->interface_version = XENPF_INTERFACE_VERSION; - return _hypercall1(int, platform_op, platform_op); -} - -static inline int __must_check -HYPERVISOR_set_debugreg( - unsigned int reg, unsigned long value) -{ - return _hypercall2(int, set_debugreg, reg, value); -} - -static inline unsigned long __must_check -HYPERVISOR_get_debugreg( - unsigned int reg) -{ - return _hypercall1(unsigned long, get_debugreg, reg); -} - -static inline int __must_check -HYPERVISOR_update_descriptor( - unsigned long ma, unsigned long word) -{ - return _hypercall2(int, update_descriptor, ma, word); -} - -static inline int __must_check -HYPERVISOR_memory_op( - unsigned int cmd, void *arg) -{ - return _hypercall2(int, memory_op, cmd, arg); -} - -static inline int __must_check -HYPERVISOR_multicall( - multicall_entry_t *call_list, unsigned int nr_calls) -{ - return _hypercall2(int, multicall, call_list, nr_calls); -} - -static inline int __must_check -HYPERVISOR_update_va_mapping( - unsigned long va, uint64_t new_val, unsigned long flags) -{ - return _hypercall3(int, update_va_mapping, va, new_val, flags); -} - -static inline int __must_check -HYPERVISOR_event_channel_op( - int cmd, void *arg) -{ - return _hypercall2(int, event_channel_op, cmd, arg); -} - -static inline int __must_check -HYPERVISOR_xen_version( - int cmd, void *arg) -{ - return _hypercall2(int, xen_version, cmd, arg); -} - -static inline int __must_check -HYPERVISOR_console_io( - int cmd, unsigned int count, const char *str) -{ - return _hypercall3(int, console_io, cmd, count, str); -} - -static inline int __must_check -HYPERVISOR_physdev_op( - int cmd, void *arg) -{ - return _hypercall2(int, physdev_op, cmd, arg); -} - -static inline int __must_check -HYPERVISOR_grant_table_op( - unsigned int cmd, void *uop, unsigned int count) -{ - return _hypercall3(int, grant_table_op, cmd, uop, count); -} - -static inline int __must_check -HYPERVISOR_update_va_mapping_otherdomain( - unsigned long va, uint64_t new_val, unsigned long flags, domid_t domid) -{ - return _hypercall4(int, update_va_mapping_otherdomain, va, - new_val, flags, domid); -} - -static inline int __must_check -HYPERVISOR_vm_assist( - unsigned int cmd, unsigned int type) -{ - return _hypercall2(int, vm_assist, cmd, type); -} - -static inline int __must_check -HYPERVISOR_vcpu_op( - int cmd, unsigned int vcpuid, void *extra_args) -{ - return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); -} - -static inline int __must_check -HYPERVISOR_set_segment_base( - int reg, unsigned long value) -{ - return _hypercall2(int, set_segment_base, reg, value); -} - -static inline int __must_check -HYPERVISOR_suspend( - unsigned long srec) -{ - struct sched_shutdown sched_shutdown = { - .reason = SHUTDOWN_suspend - }; - - return _hypercall3(int, sched_op, SCHEDOP_shutdown, - &sched_shutdown, srec); -} - -static inline unsigned long __must_check -HYPERVISOR_hvm_op( - int op, void *arg) -{ - return _hypercall2(unsigned long, hvm_op, op, arg); -} - -static inline int __must_check -HYPERVISOR_callback_op( - int cmd, const void *arg) -{ - return _hypercall2(int, callback_op, cmd, arg); -} - -static inline int __must_check -HYPERVISOR_xenoprof_op( - int op, void *arg) -{ - return _hypercall2(int, xenoprof_op, op, arg); -} - -static inline int __must_check -HYPERVISOR_kexec_op( - unsigned long op, void *args) -{ - return _hypercall2(int, kexec_op, op, args); -} - -static inline int __must_check -HYPERVISOR_dm_op( - domid_t domid, unsigned int nr_bufs, const void *bufs) -{ - return _hypercall3(int, dm_op, domid, nr_bufs, bufs); -} - #undef __must_check +#include + #endif /* __MACHINE_XEN_HYPERCALL_H__ */ diff --git a/sys/arm64/include/xen/hypercall.h b/sys/arm64/include/xen/hypercall.h new file mode 100644 --- /dev/null +++ b/sys/arm64/include/xen/hypercall.h @@ -0,0 +1,167 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright © 2022 Elliott Mitchell + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __MACHINE_XEN_HYPERCALL_H__ +#define __MACHINE_XEN_HYPERCALL_H__ +__FBSDID("$FreeBSD$"); + +#ifndef __XEN_HYPERVISOR_H__ +# error "please don't include this file directly" +#endif + +/* + * See the Xen contrib header: xen/arch-arm.h for details on Xen's + * hypercall calling conventions. + * + * The hypercall number is passed in r12/x16. + * + * Input parameters are in r0-r4/x0-x4 as appropriate to the number of + * arguments. Input registers are clobbered. + * + * Return is in r0/x0. + * + * The hypercall tag for Xen is 0x0EA1. + */ + +#define hypercallf(NUM, ARGS, REGVAR, REGASM) \ + static inline register_t \ + ___xen_hypercall_##NUM(ARGS register_t op) \ + { \ + register register_t _op __asm__(OPREG) = op; \ + REGVAR \ + __asm__ volatile ( \ + "hvc #0x0EA1;\n" \ + : "+r" (_op)REGASM \ + : /* clobbered inputs, are outputs, really */ \ + : "memory" \ + ); \ + return (_arg0); \ + } + +#ifndef __ILP32__ +#define OPREG "x16" +#define REGPRE "x" +#else +#define OPREG "r12" +#define REGPRE "r" +#endif + +#define COMMAS(...) __VA_ARGS__ +#define ARG(n) register_t arg##n, +#define VAR(n) register register_t _arg##n __asm__(REGPRE __STRING(n)) = arg##n; +#define REG(n) , "+r" (_arg##n) + + +#define hypercall0(NUM, ARGS, REGVAR, REGASM) \ + hypercallf(NUM,, register register_t _arg0 __asm__(REGPRE"0");, \ + COMMAS(, "=r" (_arg0))) + +#define hypercall1(NUM, ARGS, REGVAR, REGASM) \ + hypercallf(NUM, COMMAS(ARG(0)ARGS), VAR(0)REGVAR, COMMAS(REG(0)REGASM)) + +#define hypercall2(NUM, ARGS, REGVAR, REGASM) \ + hypercall1(NUM, COMMAS(ARG(1)ARGS), VAR(1)REGVAR, COMMAS(REG(1)REGASM)) + +#define hypercall3(NUM, ARGS, REGVAR, REGASM) \ + hypercall2(NUM, COMMAS(ARG(2)ARGS), VAR(2)REGVAR, COMMAS(REG(2)REGASM)) + +#define hypercall4(NUM, ARGS, REGVAR, REGASM) \ + hypercall3(NUM, COMMAS(ARG(3)ARGS), VAR(3)REGVAR, COMMAS(REG(3)REGASM)) + +#define hypercall5(NUM, ARGS, REGVAR, REGASM) \ + hypercall4(NUM, COMMAS(ARG(4)ARGS), VAR(4)REGVAR, COMMAS(REG(4)REGASM)) + +#define hypercall(NUM) hypercall##NUM(NUM,,,) + +/* the actual inline function definitions */ + +hypercall(0) +hypercall(1) +hypercall(2) +hypercall(3) +hypercall(4) +hypercall(5) + +/* cleanup */ + +#undef hypercallf +#undef OPREG +#undef REGPRE +#undef COMMAS +#undef ARG +#undef VAR +#undef REG + +#undef hypercall0 +#undef hypercall1 +#undef hypercall2 +#undef hypercall3 +#undef hypercall4 +#undef hypercall + +/* the wrappers expected by hypercall.h */ + +/* + * The reasoning behind this is Xen/ARM wants the first argument in the first + * argument passing register, and the op code in a later register. As such the + * preprocessor is used to swap arguments with the goal of reducing argument + * shuffling in the resultant binary. + */ + +#define __xen_hypercall_0(op) ___xen_hypercall_0(op) +#define __xen_hypercall_1(op,a0) ___xen_hypercall_1(a0,op) +#define __xen_hypercall_2(op,a0,a1) ___xen_hypercall_2(a0,a1,op) +#define __xen_hypercall_3(op,a0,a1,a2) ___xen_hypercall_3(a0,a1,a2,op) +#define __xen_hypercall_4(op,a0,a1,a2,a3) ___xen_hypercall_4(a0,a1,a2,a3,op) +#define __xen_hypercall_5(op,a0,a1,a2,a3,a4) ___xen_hypercall_5(a0,a1,a2,a3,a4,op) + +/* the wrappers presently expected by hypercall.h */ + +#define _hypercall0(type, name) \ + (type)__xen_hypercall_0(__HYPERVISOR_##name) +#define _hypercall1(type, name, arg0) \ + (type)__xen_hypercall_1(__HYPERVISOR_##name, (register_t)(arg0)) +#define _hypercall2(type, name, arg0, arg1) \ + (type)__xen_hypercall_2(__HYPERVISOR_##name, (register_t)(arg0), \ + (register_t)(arg1)) +#define _hypercall3(type, name, arg0, arg1, arg2) \ + (type)__xen_hypercall_3(__HYPERVISOR_##name, (register_t)(arg0), \ + (register_t)(arg1), (register_t)(arg2)) +#define _hypercall4(type, name, arg0, arg1, arg2, arg3) \ + (type)__xen_hypercall_4(__HYPERVISOR_##name, (register_t)(arg0), \ + (register_t)(arg1), (register_t)(arg2), (register_t)(arg3)) +#define _hypercall5(type, name, arg0, arg1, arg2, arg3, arg4) \ + (type)__xen_hypercall_5(__HYPERVISOR_##name, (register_t)(arg0), \ + (register_t)(arg1), (register_t)(arg2), (register_t)(arg3), \ + (register_t)(arg4)) + +#define privcmd_hypercall(op, arg0, arg1, arg2, arg3, arg4) \ + (int)__xen_hypercall_5((op), (arg0), (arg1), (arg2), (arg3), (arg4)) + +#include + +#endif /* __MACHINE_XEN_HYPERCALL_H__ */ diff --git a/sys/i386/include/xen/hypercall.h b/sys/i386/include/xen/hypercall.h --- a/sys/i386/include/xen/hypercall.h +++ b/sys/i386/include/xen/hypercall.h @@ -1,23 +1,25 @@ /****************************************************************************** + * SPDX-License-Identifier: MIT OR GPL-2.0-only + * * hypercall.h - * + * * Linux-specific hypervisor handling. - * + * * Copyright (c) 2002-2004, K A Fraser - * + * * This file may be distributed separately from the Linux kernel, or * incorporated into other software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -27,93 +29,93 @@ * IN THE SOFTWARE. */ -#ifndef __HYPERCALL_H__ -#define __HYPERCALL_H__ +#ifndef __MACHINE_XEN_HYPERCALL_H__ +#define __MACHINE_XEN_HYPERCALL_H__ -#include -#include -#include +#ifndef __XEN_HYPERVISOR_H__ +# error "please don't include this file directly" +#endif extern char *hypercall_page; #define __STR(x) #x #define STR(x) __STR(x) -#define HYPERCALL_STR(name) \ - "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)" - -#define _hypercall0(type, name) \ -({ \ - long __res; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res) \ - : \ - : "memory" ); \ - (type)__res; \ +#define HYPERCALL_STR(name) \ + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)" + +#define _hypercall0(type, name) \ +({ \ + long __res; \ + __asm__ volatile ( \ + HYPERCALL_STR(name) \ + : "=a" (__res) \ + : \ + : "memory" ); \ + (type)__res; \ }) -#define _hypercall1(type, name, a1) \ -({ \ - long __res, __ign1; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=b" (__ign1) \ - : "1" ((long)(a1)) \ - : "memory" ); \ - (type)__res; \ +#define _hypercall1(type, name, a1) \ +({ \ + long __res, __ign1; \ + __asm__ volatile ( \ + HYPERCALL_STR(name) \ + : "=a" (__res), "=b" (__ign1) \ + : "1" ((long)(a1)) \ + : "memory" ); \ + (type)__res; \ }) -#define _hypercall2(type, name, a1, a2) \ -({ \ - long __res, __ign1, __ign2; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ - : "1" ((long)(a1)), "2" ((long)(a2)) \ - : "memory" ); \ - (type)__res; \ +#define _hypercall2(type, name, a1, a2) \ +({ \ + long __res, __ign1, __ign2; \ + __asm__ volatile ( \ + HYPERCALL_STR(name) \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ + : "1" ((long)(a1)), "2" ((long)(a2)) \ + : "memory" ); \ + (type)__res; \ }) -#define _hypercall3(type, name, a1, a2, a3) \ -({ \ - long __res, __ign1, __ign2, __ign3; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ - "=d" (__ign3) \ - : "1" ((long)(a1)), "2" ((long)(a2)), \ - "3" ((long)(a3)) \ - : "memory" ); \ - (type)__res; \ +#define _hypercall3(type, name, a1, a2, a3) \ +({ \ + long __res, __ign1, __ign2, __ign3; \ + __asm__ volatile ( \ + HYPERCALL_STR(name) \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3) \ + : "1" ((long)(a1)), "2" ((long)(a2)), \ + "3" ((long)(a3)) \ + : "memory" ); \ + (type)__res; \ }) -#define _hypercall4(type, name, a1, a2, a3, a4) \ -({ \ - long __res, __ign1, __ign2, __ign3, __ign4; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ - "=d" (__ign3), "=S" (__ign4) \ - : "1" ((long)(a1)), "2" ((long)(a2)), \ - "3" ((long)(a3)), "4" ((long)(a4)) \ - : "memory" ); \ - (type)__res; \ +#define _hypercall4(type, name, a1, a2, a3, a4) \ +({ \ + long __res, __ign1, __ign2, __ign3, __ign4; \ + __asm__ volatile ( \ + HYPERCALL_STR(name) \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3), "=S" (__ign4) \ + : "1" ((long)(a1)), "2" ((long)(a2)), \ + "3" ((long)(a3)), "4" ((long)(a4)) \ + : "memory" ); \ + (type)__res; \ }) -#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ -({ \ - long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ - "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ - : "1" ((long)(a1)), "2" ((long)(a2)), \ - "3" ((long)(a3)), "4" ((long)(a4)), \ - "5" ((long)(a5)) \ - : "memory" ); \ - (type)__res; \ -}) +#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ +({ \ + long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ + __asm__ volatile ( \ + HYPERCALL_STR(name) \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ + : "1" ((long)(a1)), "2" ((long)(a2)), \ + "3" ((long)(a3)), "4" ((long)(a4)), \ + "5" ((long)(a5)) \ + : "memory" ); \ + (type)__res; \ +}) static inline long privcmd_hypercall(long op, long a1, long a2, long a3, long a4, long a5) @@ -127,10 +129,10 @@ __asm__ volatile ( "call *%[call]" : "=a" (__res), "=b" (__ign1), "=c" (__ign2), - "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) - : "1" ((long)(a1)), "2" ((long)(a2)), - "3" ((long)(a3)), "4" ((long)(a4)), - "5" ((long)(a5)), [call] "a" (__call) + "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) + : "1" ((long)(a1)), "2" ((long)(a2)), + "3" ((long)(a3)), "4" ((long)(a4)), + "5" ((long)(a5)), [call] "a" (__call) : "memory" ); return __res; @@ -143,239 +145,6 @@ return _hypercall1(int, set_trap_table, table); } -static inline int -HYPERVISOR_mmu_update( - mmu_update_t *req, int count, int *success_count, domid_t domid) -{ - return _hypercall4(int, mmu_update, req, count, success_count, domid); -} - -static inline int -HYPERVISOR_mmuext_op( - mmuext_op_t *op, int count, int *success_count, domid_t domid) -{ - return _hypercall4(int, mmuext_op, op, count, success_count, domid); -} - -static inline int -HYPERVISOR_set_gdt( - unsigned long *frame_list, int entries) -{ - return _hypercall2(int, set_gdt, frame_list, entries); -} +#include -static inline int -HYPERVISOR_stack_switch( - unsigned long ss, unsigned long esp) -{ - return _hypercall2(int, stack_switch, ss, esp); -} - -static inline int -HYPERVISOR_set_callbacks( - unsigned long event_selector, unsigned long event_address, - unsigned long failsafe_selector, unsigned long failsafe_address) -{ - return _hypercall4(int, set_callbacks, - event_selector, event_address, - failsafe_selector, failsafe_address); -} - -static inline int -HYPERVISOR_fpu_taskswitch( - int set) -{ - return _hypercall1(int, fpu_taskswitch, set); -} - -static inline int -HYPERVISOR_sched_op( - int cmd, void *arg) -{ - return _hypercall2(int, sched_op, cmd, arg); -} - -static inline long -HYPERVISOR_set_timer_op( - uint64_t timeout) -{ - unsigned long timeout_hi = (unsigned long)(timeout>>32); - unsigned long timeout_lo = (unsigned long)timeout; - return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); -} - -static inline int -HYPERVISOR_platform_op( - struct xen_platform_op *platform_op) -{ - platform_op->interface_version = XENPF_INTERFACE_VERSION; - return _hypercall1(int, platform_op, platform_op); -} - -static inline int -HYPERVISOR_set_debugreg( - int reg, unsigned long value) -{ - return _hypercall2(int, set_debugreg, reg, value); -} - -static inline unsigned long -HYPERVISOR_get_debugreg( - int reg) -{ - return _hypercall1(unsigned long, get_debugreg, reg); -} - -static inline int -HYPERVISOR_update_descriptor( - uint64_t ma, uint64_t desc) -{ - return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); -} - -static inline int -HYPERVISOR_memory_op( - unsigned int cmd, void *arg) -{ - return _hypercall2(int, memory_op, cmd, arg); -} - -static inline int -HYPERVISOR_multicall( - void *call_list, int nr_calls) -{ - return _hypercall2(int, multicall, call_list, nr_calls); -} - -static inline int -HYPERVISOR_update_va_mapping( - unsigned long va, uint64_t new_val, unsigned long flags) -{ - uint32_t hi, lo; - - lo = (uint32_t)(new_val & 0xffffffff); - hi = (uint32_t)(new_val >> 32); - - return _hypercall4(int, update_va_mapping, va, - lo, hi, flags); -} - -static inline int -HYPERVISOR_event_channel_op( - int cmd, void *arg) -{ - return _hypercall2(int, event_channel_op, cmd, arg); -} - -static inline int -HYPERVISOR_xen_version( - int cmd, void *arg) -{ - return _hypercall2(int, xen_version, cmd, arg); -} - -static inline int -HYPERVISOR_console_io( - int cmd, int count, const char *str) -{ - return _hypercall3(int, console_io, cmd, count, str); -} - -static inline int -HYPERVISOR_physdev_op( - int cmd, void *arg) -{ - return _hypercall2(int, physdev_op, cmd, arg); -} - -static inline int -HYPERVISOR_grant_table_op( - unsigned int cmd, void *uop, unsigned int count) -{ - return _hypercall3(int, grant_table_op, cmd, uop, count); -} - -static inline int -HYPERVISOR_update_va_mapping_otherdomain( - unsigned long va, uint64_t new_val, unsigned long flags, domid_t domid) -{ - uint32_t hi, lo; - - lo = (uint32_t)(new_val & 0xffffffff); - hi = (uint32_t)(new_val >> 32); - - return _hypercall5(int, update_va_mapping_otherdomain, va, - lo, hi, flags, domid); -} - -static inline int -HYPERVISOR_vm_assist( - unsigned int cmd, unsigned int type) -{ - return _hypercall2(int, vm_assist, cmd, type); -} - -static inline int -HYPERVISOR_vcpu_op( - int cmd, int vcpuid, void *extra_args) -{ - return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); -} - -static inline int -HYPERVISOR_suspend( - unsigned long srec) -{ - struct sched_shutdown sched_shutdown = { - .reason = SHUTDOWN_suspend - }; - - return _hypercall3(int, sched_op, SCHEDOP_shutdown, - &sched_shutdown, srec); -} - -static inline int -HYPERVISOR_callback_op( - int cmd, void *arg) -{ - return _hypercall2(int, callback_op, cmd, arg); -} - -static inline unsigned long -HYPERVISOR_hvm_op( - int op, void *arg) -{ - return _hypercall2(unsigned long, hvm_op, op, arg); -} - -static inline int -HYPERVISOR_xenoprof_op( - int op, void *arg) -{ - return _hypercall2(int, xenoprof_op, op, arg); -} - -static inline int -HYPERVISOR_kexec_op( - unsigned long op, void *args) -{ - return _hypercall2(int, kexec_op, op, args); -} - -static inline int -HYPERVISOR_dm_op( - domid_t domid, unsigned int nr_bufs, const void *bufs) -{ - return _hypercall3(int, dm_op, domid, nr_bufs, bufs); -} -#endif /* __HYPERCALL_H__ */ - -/* - * Local variables: - * c-file-style: "linux" - * indent-tabs-mode: t - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - */ +#endif /* __MACHINE_XEN_HYPERCALL_H__ */ diff --git a/sys/amd64/include/xen/hypercall.h b/sys/xen/hypercall.h copy from sys/amd64/include/xen/hypercall.h copy to sys/xen/hypercall.h --- a/sys/amd64/include/xen/hypercall.h +++ b/sys/xen/hypercall.h @@ -1,30 +1,32 @@ /****************************************************************************** + * SPDX-License-Identifier: MIT OR GPL-2.0-only + * * hypercall.h - * + * * FreeBSD-specific hypervisor handling. - * + * * Copyright (c) 2002-2004, K A Fraser - * + * * 64-bit updates: * Benjamin Liu * Jun Nakajima - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -36,134 +38,29 @@ * $FreeBSD$ */ -#ifndef __MACHINE_XEN_HYPERCALL_H__ -#define __MACHINE_XEN_HYPERCALL_H__ +#ifndef __XEN_HYPERCALL_H__ +#define __XEN_HYPERCALL_H__ -#include - -#ifndef __XEN_HYPERVISOR_H__ +#ifndef __MACHINE_XEN_HYPERCALL_H__ # error "please don't include this file directly" #endif -extern char *hypercall_page; +/* + * Architecture hypercall.h must provide the following 7 macros/functions: + * + * _hypercall[0-5](type, name[, arg0[, arg1[, arg2[, arg3[, arg4]]]]]); + * int privcmd_hypercall(op, arg0, arg1, arg2, arg3, arg4); + * + * Where _hypercall#() returns "type", hypercall0() takes no arguments, and + * _hypercall5() takes 5 arguments. The "name" does not include the leading + * __HYPERVISOR_ for the Xen call name. + * + * All arguments to privcmd_hypercall() are assumed to be full register size + * (long). + */ -#define __STR(x) #x -#define STR(x) __STR(x) #define __must_check -#define HYPERCALL_STR(name) \ - "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)" - -#define _hypercall0(type, name) \ -({ \ - type __res; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res) \ - : \ - : "memory" ); \ - __res; \ -}) - -#define _hypercall1(type, name, a1) \ -({ \ - type __res; \ - long __ign1; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=D" (__ign1) \ - : "1" ((long)(a1)) \ - : "memory" ); \ - __res; \ -}) - -#define _hypercall2(type, name, a1, a2) \ -({ \ - type __res; \ - long __ign1, __ign2; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \ - : "1" ((long)(a1)), "2" ((long)(a2)) \ - : "memory" ); \ - __res; \ -}) - -#define _hypercall3(type, name, a1, a2, a3) \ -({ \ - type __res; \ - long __ign1, __ign2, __ign3; \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ - "=d" (__ign3) \ - : "1" ((long)(a1)), "2" ((long)(a2)), \ - "3" ((long)(a3)) \ - : "memory" ); \ - __res; \ -}) - -#define _hypercall4(type, name, a1, a2, a3, a4) \ -({ \ - type __res; \ - long __ign1, __ign2, __ign3; \ - register long __arg4 __asm__("r10") = (long)(a4); \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ - "=d" (__ign3), "+r" (__arg4) \ - : "1" ((long)(a1)), "2" ((long)(a2)), \ - "3" ((long)(a3)) \ - : "memory" ); \ - __res; \ -}) - -#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ -({ \ - type __res; \ - long __ign1, __ign2, __ign3; \ - register long __arg4 __asm__("r10") = (long)(a4); \ - register long __arg5 __asm__("r8") = (long)(a5); \ - __asm__ volatile ( \ - HYPERCALL_STR(name) \ - : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ - "=d" (__ign3), "+r" (__arg4), "+r" (__arg5) \ - : "1" ((long)(a1)), "2" ((long)(a2)), \ - "3" ((long)(a3)) \ - : "memory" ); \ - __res; \ -}) - -static inline int -privcmd_hypercall(long op, long a1, long a2, long a3, long a4, long a5) -{ - int __res; - long __ign1, __ign2, __ign3; - register long __arg4 __asm__("r10") = (long)(a4); - register long __arg5 __asm__("r8") = (long)(a5); - long __call = (long)&hypercall_page + (op * 32); - - if (op >= PAGE_SIZE / 32) - return -EINVAL; - - __asm__ volatile ( - "call *%[call]" - : "=a" (__res), "=D" (__ign1), "=S" (__ign2), - "=d" (__ign3), "+r" (__arg4), "+r" (__arg5) - : "1" ((long)(a1)), "2" ((long)(a2)), - "3" ((long)(a3)), [call] "a" (__call) - : "memory" ); - - return (__res); -} - -static inline int __must_check -HYPERVISOR_set_trap_table( - const trap_info_t *table) -{ - return _hypercall1(int, set_trap_table, table); -} - static inline int __must_check HYPERVISOR_mmu_update( mmu_update_t *req, unsigned int count, unsigned int *success_count, @@ -174,7 +71,7 @@ static inline int __must_check HYPERVISOR_mmuext_op( - struct mmuext_op *op, unsigned int count, unsigned int *success_count, + mmuext_op_t *op, unsigned int count, unsigned int *success_count, domid_t domid) { return _hypercall4(int, mmuext_op, op, count, success_count, domid); @@ -196,11 +93,12 @@ static inline int __must_check HYPERVISOR_set_callbacks( - unsigned long event_address, unsigned long failsafe_address, - unsigned long syscall_address) + unsigned long event_selector, unsigned long event_address, + unsigned long failsafe_selector, unsigned long failsafe_address) { - return _hypercall3(int, set_callbacks, - event_address, failsafe_address, syscall_address); + return _hypercall4(int, set_callbacks, + event_selector, event_address, + failsafe_selector, failsafe_address); } static inline int @@ -221,12 +119,19 @@ HYPERVISOR_set_timer_op( uint64_t timeout) { +#ifndef __ILP32__ return _hypercall1(long, set_timer_op, timeout); +#else + unsigned long timeout_hi = (unsigned long)(timeout>>32); + unsigned long timeout_lo = (unsigned long)timeout; + + return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); +#endif } static inline int __must_check HYPERVISOR_platform_op( - struct xen_platform_op *platform_op) + xen_platform_op_t *platform_op) { platform_op->interface_version = XENPF_INTERFACE_VERSION; return _hypercall1(int, platform_op, platform_op); @@ -248,9 +153,13 @@ static inline int __must_check HYPERVISOR_update_descriptor( - unsigned long ma, unsigned long word) + uint64_t ma, uint64_t desc) { - return _hypercall2(int, update_descriptor, ma, word); +#ifndef __ILP32__ + return _hypercall2(int, update_descriptor, ma, desc); +#else + return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); +#endif } static inline int __must_check @@ -271,7 +180,16 @@ HYPERVISOR_update_va_mapping( unsigned long va, uint64_t new_val, unsigned long flags) { +#ifndef __ILP32__ return _hypercall3(int, update_va_mapping, va, new_val, flags); +#else + uint32_t hi, lo; + + lo = (uint32_t)(new_val & 0xffffffff); + hi = (uint32_t)(new_val >> 32); + + return _hypercall4(int, update_va_mapping, va, lo, hi, flags); +#endif } static inline int __must_check @@ -313,8 +231,18 @@ HYPERVISOR_update_va_mapping_otherdomain( unsigned long va, uint64_t new_val, unsigned long flags, domid_t domid) { +#ifndef __ILP32__ return _hypercall4(int, update_va_mapping_otherdomain, va, new_val, flags, domid); +#else + uint32_t hi, lo; + + lo = (uint32_t)(new_val & 0xffffffff); + hi = (uint32_t)(new_val >> 32); + + return _hypercall5(int, update_va_mapping_otherdomain, va, + lo, hi, flags, domid); +#endif } static inline int __must_check @@ -342,7 +270,7 @@ HYPERVISOR_suspend( unsigned long srec) { - struct sched_shutdown sched_shutdown = { + sched_shutdown_t sched_shutdown = { .reason = SHUTDOWN_suspend }; @@ -352,9 +280,9 @@ static inline unsigned long __must_check HYPERVISOR_hvm_op( - int op, void *arg) + int op, void *arg) { - return _hypercall2(unsigned long, hvm_op, op, arg); + return _hypercall2(unsigned long, hvm_op, op, arg); } static inline int __must_check @@ -387,4 +315,4 @@ #undef __must_check -#endif /* __MACHINE_XEN_HYPERCALL_H__ */ +#endif /* __XEN_HYPERCALL_H__ */