git: 7a58bf04433f - main - arm64: Enabling new hypercalls using HvCallSetVpRegisters and HvCallGetVpRegisters

From: Wei Hu <whu_at_FreeBSD.org>
Date: Mon, 26 Sep 2022 07:04:45 UTC
The branch main has been updated by whu:

URL: https://cgit.FreeBSD.org/src/commit/?id=7a58bf04433f711e1db6b2c263d8d07c7fd0819b

commit 7a58bf04433f711e1db6b2c263d8d07c7fd0819b
Author:     Wei Hu <whu@FreeBSD.org>
AuthorDate: 2022-09-26 06:30:37 +0000
Commit:     Wei Hu <whu@FreeBSD.org>
CommitDate: 2022-09-26 06:30:37 +0000

    arm64: Enabling new hypercalls using HvCallSetVpRegisters and HvCallGetVpRegisters
    
    Enabling HvCallSetVpRegisters and HvCallGetVpRegisters for hypercalls to
    read and write to specific MSRs. This is required for implementing wrmsr
    and rdmsr, which is required for Hyper-V vmbus driver for ARM64.
    
    Also we need to use arm smccc hvc 1.2 version as we need to access
    registers beyond X0-X3 for HvCallGetVpRegisters. Currently scoping
    it only for Hyper-V.
    
    Reviewed by:    lwhsu, andrew, whu
    Tested by:      Souradeep Chakrabarti <schakrabarti@microsoft.com>
    Signed-off-by:  Souradeep Chakrabarti <schakrabarti@microsoft.com>
    Sponsored by:   Microsoft
    Differential Revision:  https://reviews.freebsd.org/D36256
---
 sys/dev/psci/smccc.h       | 25 +++++++++++++++++++++++++
 sys/dev/psci/smccc_arm64.S | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/sys/dev/psci/smccc.h b/sys/dev/psci/smccc.h
index 6bb4dbcf7076..4dc4c089df65 100644
--- a/sys/dev/psci/smccc.h
+++ b/sys/dev/psci/smccc.h
@@ -91,4 +91,29 @@ int arm_smccc_smc(register_t, register_t, register_t, register_t, register_t,
 int arm_smccc_hvc(register_t, register_t, register_t, register_t, register_t,
     register_t, register_t, register_t, struct arm_smccc_res *res);
 
+struct arm_smccc_1_2_regs {
+	register_t a0;
+	register_t a1;
+	register_t a2;
+	register_t a3;
+	register_t a4;
+	register_t a5;
+	register_t a6;
+	register_t a7;
+	register_t a8;
+	register_t a9;
+	register_t a10;
+	register_t a11;
+	register_t a12;
+	register_t a13;
+	register_t a14;
+	register_t a15;
+	register_t a16;
+	register_t a17;
+};
+
+int arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
+    struct arm_smccc_1_2_regs *res);
+int arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
+    struct arm_smccc_1_2_regs *res);
 #endif /* _PSCI_SMCCC_H_ */
diff --git a/sys/dev/psci/smccc_arm64.S b/sys/dev/psci/smccc_arm64.S
index ba10f7493e71..41e602563222 100644
--- a/sys/dev/psci/smccc_arm64.S
+++ b/sys/dev/psci/smccc_arm64.S
@@ -51,3 +51,38 @@ END(arm_smccc_\insn)
  */
 arm_smccc_1_0	hvc
 arm_smccc_1_0	smc
+
+.macro arm_smccc_1_2	insn
+ENTRY(arm_smccc_1_2_\insn)
+	stp	x1, x19, [sp, #-16]!
+	mov	x19, x0
+	ldp	x0, x1, [x19, #16 * 0]
+	ldp	x2, x3, [x19, #16 * 1]
+	ldp	x4, x5, [x19, #16 * 2]
+	ldp	x6, x7, [x19, #16 * 3]
+	ldp	x8, x9, [x19, #16 * 4]
+	ldp	x10, x11, [x19, #16 * 5]
+	ldp	x12, x13, [x19, #16 * 6]
+	ldp	x14, x15, [x19, #16 * 7]
+	ldp	x16, x17, [x19, #16 * 8]
+	\insn	#0
+	ldr	x19, [sp]
+	cbz	x19, 1f
+	stp	x0, x1, [x19, #16 * 0]
+	stp	x2, x3, [x19, #16 * 1]
+	stp	x4, x5, [x19, #16 * 2]
+	stp	x6, x7, [x19, #16 * 3]
+	stp	x8, x9, [x19, #16 * 4]
+	stp	x10, x11, [x19, #16 * 5]
+	stp	x12, x13, [x19, #16 * 6]
+	stp	x14, x15, [x19, #16 * 7]
+	stp	x16, x17, [x19, #16 * 8]
+	ldp	xzr, x19, [sp], #16
+1:	ret
+END(arm_smccc_1_2\insn)
+.endm
+/* int arm_smccc_1_2_*(const struct arm_smccc_1_2_regs *args,
+ *     struct arm_smccc_1_2_regs *res)
+ */
+arm_smccc_1_2	hvc
+arm_smccc_1_2	smc