>From 8ad5602f26a0f7b9a04cbda33330ba8004d8fcc1 Mon Sep 17 00:00:00 2001 From: Elliott Mitchell Date: Mon, 7 Mar 2022 18:26:31 -0800 Subject: [PATCH] xen/arm64: implement aarch64 Xen hypercall header To: xen-devel@xxxxxxxxxxxxxxxxxxxx Match the i386/AMD64 headers in doing inline functions for the Xen hypervisor calls. This has been heavily inspired by work done by Julien Grall and Stefano Stabellini. --- sys/arm64/include/xen/hypercall.h | 148 ++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 sys/arm64/include/xen/hypercall.h diff --git a/sys/arm64/include/xen/hypercall.h b/sys/arm64/include/xen/hypercall.h new file mode 100644 index 00000000000..b8e51611f26 --- /dev/null +++ b/arm64/include/xen/hypercall.h @@ -0,0 +1,148 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause-FreeBSD + * + * Copyright (c) 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_ARM64_XEN_HYPERCALL_H__ +#define __MACHINE_ARM64_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 long \ + __hypercall_xen_##NUM(ARGS long op) \ + { \ + register long _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) long arg##n, +#define VAR(n) register long _arg##n __asm__(REGPRE __STRING(n)) = arg##n; +#define REG(n) , "+r" (_arg##n) + + +#define hypercall0(NUM, ARGS, REGVAR, REGASM) \ + hypercallf(NUM,, register long _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 hypervisor.h */ + +#define _hypercall0(type, name) \ + (type)__hypercall_xen_0(__HYPERVISOR_##name) +#define _hypercall1(type, name, arg0) \ + (type)__hypercall_xen_1((long)(arg0), __HYPERVISOR_##name) +#define _hypercall2(type, name, arg0, arg1) \ + (type)__hypercall_xen_2((long)(arg0), (long)(arg1), \ + __HYPERVISOR_##name) +#define _hypercall3(type, name, arg0, arg1, arg2) \ + (type)__hypercall_xen_3((long)(arg0), (long)(arg1), \ + (long)(arg2), __HYPERVISOR_##name) +#define _hypercall4(type, name, arg0, arg1, arg2, arg3) \ + (type)__hypercall_xen_4((long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), __HYPERVISOR_##name) +#define _hypercall5(type, name, arg0, arg1, arg2, arg3, arg4) \ + (type)__hypercall_xen_5((long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), (long)(arg4), __HYPERVISOR_##name) + +#define privcmd_hypercall(op, arg0, arg1, arg2, arg3, arg4) \ + (int)__hypercall_xen_5((arg0), (arg1), (arg2), (arg3), (arg4), (op)) + +#endif /* __MACHINE_ARM64_XEN_HYPERCALL_H__ */ -- 2.30.2