From: Elliot Berman <quic_eberman@quicinc.com>
To: Bjorn Andersson <bjorn.andersson@linaro.org>,
<linux-kernel@vger.kernel.org>
Cc: Elliot Berman <quic_eberman@quicinc.com>,
Trilok Soni <quic_tsoni@quicinc.com>,
Murali Nalajala <quic_mnalajala@quicinc.com>,
Srivatsa Vaddagiri <quic_svaddagiri@quicinc.com>,
Carl van Schaik <quic_cvanscha@quicinc.com>,
Andy Gross <agross@kernel.org>, <linux-arm-msm@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>
Subject: [PATCH 03/11] arm64: gunyah: Add Gunyah hypercalls ABI
Date: Wed, 23 Feb 2022 15:37:21 -0800 [thread overview]
Message-ID: <20220223233729.1571114-4-quic_eberman@quicinc.com> (raw)
In-Reply-To: <20220223233729.1571114-1-quic_eberman@quicinc.com>
Add initial support to perform Gunyah hypercalls. The arm64 ABI for
Gunyah hypercalls generally follows the AAPCS64, and can be summarized:
- Function identifier is passed through the imm operand
- [r0,r7] are parameter and result registers
- [r8-r18] are temporary and saved by the caller (VM)
- [r19-r31] are preserved and saved by the hypervisor
The preprocessor macors for creating the necessary HVC instruction
roughly follows the SMCCC 1.1 implementation in
include/linux/arm-smccc.h.
Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
---
MAINTAINERS | 1 +
arch/arm64/include/asm/gunyah/hypercall.h | 193 ++++++++++++++++++++++
2 files changed, 194 insertions(+)
create mode 100644 arch/arm64/include/asm/gunyah/hypercall.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a918f653eac..7e6a8488fa3e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8402,6 +8402,7 @@ L: linux-arm-msm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/gunyah/
F: Documentation/virt/gunyah/
+F: arch/arm64/include/asm/gunyah/
H8/300 ARCHITECTURE
M: Yoshinori Sato <ysato@users.sourceforge.jp>
diff --git a/arch/arm64/include/asm/gunyah/hypercall.h b/arch/arm64/include/asm/gunyah/hypercall.h
new file mode 100644
index 000000000000..626163500e32
--- /dev/null
+++ b/arch/arm64/include/asm/gunyah/hypercall.h
@@ -0,0 +1,193 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef __ASM_GH_HYPERCALL_H
+#define __ASM_GH_HYPERCALL_H
+
+#include <linux/types.h>
+
+#define ___gh_count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
+
+#define __gh_count_args(...) \
+ ___gh_count_args(_, ## __VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+#define __gh_skip_0(...) __VA_ARGS__
+#define __gh_skip_1(a, ...) __VA_ARGS__
+#define __gh_skip_2(a, b, ...) __VA_ARGS__
+#define __gh_skip_3(a, b, c, ...) __VA_ARGS__
+#define __gh_skip_4(a, b, c, d, ...) __VA_ARGS__
+#define __gh_skip_5(a, b, c, d, e, ...) __VA_ARGS__
+#define __gh_skip_6(a, b, c, d, e, f, ...) __VA_ARGS__
+#define __gh_skip_7(a, b, c, d, e, f, g, ...) __VA_ARGS__
+#define __gh_skip_8(a, b, c, d, e, f, g, h, ...) __VA_ARGS__
+
+#define __gh_declare_arg_0(...)
+
+#define __gh_declare_arg_1(a1, ...) \
+ typeof(a1) __gh_a1 = (a1); \
+ register uintptr_t arg1 asm("r0") = __gh_a1
+
+#define __gh_declare_arg_2(a1, a2, ...) \
+ __gh_declare_arg_1(a1); \
+ typeof(a2) __gh_a2 = (a2); \
+ register uintptr_t arg2 asm("r1") = __gh_a2
+
+#define __gh_declare_arg_3(a1, a2, a3, ...) \
+ __gh_declare_arg_2(a1, a2); \
+ typeof(a3) __gh_a3 = (a3); \
+ register uintptr_t arg3 asm("r2") = __gh_a3
+
+#define __gh_declare_arg_4(a1, a2, a3, a4, ...) \
+ __gh_declare_arg_3(a1, a2, a3); \
+ typeof(a4) __gh_a4 = (a4); \
+ register uintptr_t arg4 asm("r3") = __gh_a4
+
+#define __gh_declare_arg_5(a1, a2, a3, a4, a5, ...) \
+ __gh_declare_arg_4(a1, a2, a3, a4); \
+ typeof(a5) __gh_a5 = (a5); \
+ register uintptr_t arg5 asm("r4") = __gh_a5
+
+#define __gh_declare_arg_6(a1, a2, a3, a4, a5, a6, ...) \
+ __gh_declare_arg_5(a1, a2, a3, a4, a5); \
+ typeof(a6) __gh_a6 = (a6); \
+ register uintptr_t arg6 asm("r5") = __gh_a6
+
+#define __gh_declare_arg_7(a1, a2, a3, a4, a5, a6, a7, ...) \
+ __gh_declare_arg_6(a1, a2, a3, a4, a5, a6); \
+ typeof(a7) __gh_a7 = (a7); \
+ register uintptr_t arg7 asm("r6") = __gh_a7
+
+#define __gh_declare_arg_8(a1, a2, a3, a4, a5, a6, a7, a8, ...) \
+ __gh_declare_arg_7(a1, a2, a3, a4, a5, a6, a7); \
+ typeof(a8) __gh_a8 = (a8); \
+ register uintptr_t arg8 asm("r7") = __gh_a8
+
+#define ___gh_declare_args(nargs) __gh_declare_arg_ ## nargs
+#define __gh_declare_args(nargs) ___gh_declare_args(nargs)
+#define _gh_declare_args(nargs, ...) __gh_declare_args(nargs)(__VA_ARGS__)
+
+#define __gh_constraint_arg_0
+#define __gh_constraint_arg_1 "r" (arg1),
+#define __gh_constraint_arg_2 __gh_constraint_arg_1 "r" (arg2),
+#define __gh_constraint_arg_3 __gh_constraint_arg_2 "r" (arg3),
+#define __gh_constraint_arg_4 __gh_constraint_arg_3 "r" (arg4),
+#define __gh_constraint_arg_5 __gh_constraint_arg_4 "r" (arg5),
+#define __gh_constraint_arg_6 __gh_constraint_arg_5 "r" (arg6),
+#define __gh_constraint_arg_7 __gh_constraint_arg_6 "r" (arg7),
+#define __gh_constraint_arg_8 __gh_constraint_arg_7 "r" (arg8),
+
+#define _gh_constraint_args(nargs) __gh_constraint_arg_ ## nargs
+
+#define __gh_to_res(nargs, ...) __gh_skip_ ## nargs (__VA_ARGS__)
+
+#define __gh_declare_res_0
+
+#define __gh_declare_res_1 \
+ register uintptr_t res1 asm("r0")
+
+#define __gh_declare_res_2 \
+ __gh_declare_res_1; \
+ register uintptr_t res2 asm("r1")
+
+#define __gh_declare_res_3 \
+ __gh_declare_res_2; \
+ register uintptr_t res3 asm("r2")
+
+#define __gh_declare_res_4 \
+ __gh_declare_res_3; \
+ register uintptr_t res4 asm("r3")
+
+#define __gh_declare_res_5 \
+ __gh_declare_res_4; \
+ register uintptr_t res5 asm("r4")
+
+#define __gh_declare_res_6 \
+ __gh_declare_res_5; \
+ register uintptr_t res6 asm("r5")
+
+#define __gh_declare_res_7 \
+ __gh_declare_res_6; \
+ register uintptr_t res7 asm("r6")
+
+#define __gh_declare_res_8 \
+ __gh_declare_res_7; \
+ register uintptr_t res8 asm("r7")
+
+#define ___gh_declare_res(nargs) __gh_declare_res_ ## nargs
+#define __gh_declare_res(nargs) ___gh_declare_res(nargs)
+#define _gh_declare_res(...) __gh_declare_res(__gh_count_args(__VA_ARGS__))
+
+#define __gh_constraint_res_0
+#define __gh_constraint_res_1 "=r" (res1)
+#define __gh_constraint_res_2 __gh_constraint_res_1, "=r" (res2)
+#define __gh_constraint_res_3 __gh_constraint_res_2, "=r" (res3)
+#define __gh_constraint_res_4 __gh_constraint_res_3, "=r" (res4)
+#define __gh_constraint_res_5 __gh_constraint_res_4, "=r" (res5)
+#define __gh_constraint_res_6 __gh_constraint_res_5, "=r" (res6)
+#define __gh_constraint_res_7 __gh_constraint_res_6, "=r" (res7)
+#define __gh_constraint_res_8 __gh_constraint_res_7, "=r" (res8)
+
+#define ___gh_constraint_res(nargs) __gh_constraint_res_ ## nargs
+#define __gh_constraint_res(nargs) ___gh_constraint_res(nargs)
+#define _gh_constraint_res(...) \
+ __gh_constraint_res(__gh_count_args(__VA_ARGS__))
+
+#define __gh_assign_res_0(...)
+
+#define __gh_assign_res_1(r1) \
+ r1 = res1;
+
+#define __gh_assign_res_2(r1, r2) \
+ __gh_assign_res_1(r1); \
+ r2 = res2
+
+#define __gh_assign_res_3(r1, r2, r3) \
+ __gh_assign_res_2(r1, r2); \
+ r3 = res3
+
+#define __gh_assign_res_4(r1, r2, r3, r4) \
+ __gh_assign_res_3(r1, r2, r3); \
+ r4 = res4
+
+#define __gh_assign_res_5(r1, r2, r3, r4, r5) \
+ __gh_assign_res_4(r1, r2, r3, r4); \
+ r5 = res5
+
+#define __gh_assign_res_6(r1, r2, r3, r4, r5, r6) \
+ __gh_assign_res_5(r1, r2, r3, r4, r5); \
+ r6 = res6
+
+#define __gh_assign_res_7(r1, r2, r3, r4, r5, r6, r7) \
+ __gh_assign_res_6(r1, r2, r3, r4, r5, r6); \
+ r7 = res7
+
+#define __gh_assign_res_8(r1, r2, r3, r4, r5, r6, r7, r8) \
+ __gh_assign_res_7(r1, r2, r3, r4, r5, r6, r7); \
+ r8 = res8
+
+#define ___gh_assign_res(nargs) __gh_assign_res_ ## nargs
+#define __gh_assign_res(nargs) ___gh_assign_res(nargs)
+#define _gh_assign_res(...) __gh_assign_res(__gh_count_args(__VA_ARGS__))(__VA_ARGS__)
+
+/**
+ * arch_gh_hypercall() - Performs an AArch64-specific call into hypervisor using Gunyah ABI
+ * @hcall_num: Hypercall function ID to invoke
+ * @nargs: Number of input arguments
+ * @...: First nargs are the input arguments. Remaining arguments are output variables.
+ */
+#define arch_gh_hypercall(hcall_num, nargs, ...) \
+ do { \
+ _gh_declare_res(__gh_to_res(nargs, __VA_ARGS__)); \
+ _gh_declare_args(nargs, __VA_ARGS__); \
+ asm volatile( \
+ "hvc %[num]\n" \
+ : _gh_constraint_res(__gh_to_res(nargs, __VA_ARGS__)) \
+ : _gh_constraint_args(nargs) \
+ [num] "i" (hcall_num) \
+ : "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", \
+ "memory"); \
+ _gh_assign_res(__gh_to_res(nargs, __VA_ARGS__)); \
+ } while (0)
+
+#endif
--
2.25.1
next prev parent reply other threads:[~2022-02-23 23:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-23 23:37 [PATCH 00/11] Gunyah Hypervisor drivers Elliot Berman
2022-02-23 23:37 ` [PATCH 01/11] docs: gunyah: Introduce Gunyah Hypervisor Elliot Berman
2022-02-23 23:37 ` [PATCH 02/11] dt-bindings: Add binding for gunyah hypervisor Elliot Berman
2022-02-25 20:01 ` Rob Herring
2022-03-02 23:53 ` Elliot Berman
2022-02-23 23:37 ` Elliot Berman [this message]
2022-02-24 10:10 ` [PATCH 03/11] arm64: gunyah: Add Gunyah hypercalls ABI Mark Rutland
2022-02-24 10:26 ` Marc Zyngier
2022-04-13 17:09 ` Elliot Berman
2022-02-23 23:37 ` [PATCH 04/11] gunyah: Common types and error codes for Gunyah hypercalls Elliot Berman
2022-02-23 23:37 ` [PATCH 05/11] virt: gunyah: Add sysfs nodes Elliot Berman
2022-02-23 23:37 ` [PATCH 06/11] virt: gunyah: Add capabilities bus and devices Elliot Berman
2022-02-23 23:37 ` [PATCH 07/11] gunyah: msgq: Add Gunyah message queues Elliot Berman
2022-02-23 23:37 ` [PATCH 08/11] gunyah: rsc_mgr: Add resource manager RPC core Elliot Berman
2022-02-23 23:37 ` [PATCH 09/11] gunyah: rsc_mgr: Add auxiliary devices for console Elliot Berman
2022-02-23 23:37 ` [PATCH 10/11] gunyah: rsc_mgr: Add RPC for console services Elliot Berman
2022-02-23 23:37 ` [PATCH 11/11] gunyah: Add tty console driver for RM Console Serivces Elliot Berman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220223233729.1571114-4-quic_eberman@quicinc.com \
--to=quic_eberman@quicinc.com \
--cc=agross@kernel.org \
--cc=bjorn.andersson@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=quic_cvanscha@quicinc.com \
--cc=quic_mnalajala@quicinc.com \
--cc=quic_svaddagiri@quicinc.com \
--cc=quic_tsoni@quicinc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox