]> xenbits.xensource.com Git - unikraft/libs/libgo.git/commitdiff
Add goroutine context switch functions for ARM64
authorEduard Vintilă <eduard.vintila47@gmail.com>
Sun, 12 Nov 2023 12:39:57 +0000 (14:39 +0200)
committerRazvan Deaconescu <razvan.deaconescu@upb.ro>
Sat, 30 Dec 2023 05:26:36 +0000 (07:26 +0200)
Signed-off-by: Eduard Vintilă <eduard.vintila47@gmail.com>
Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #9

libgo/arm64/go-context.S [new file with mode: 0644]
patches/0003-Add-context-switch-functions-for-ARM64.patch [new file with mode: 0644]

diff --git a/libgo/arm64/go-context.S b/libgo/arm64/go-context.S
new file mode 100644 (file)
index 0000000..348d24e
--- /dev/null
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Goroutine context switch for AArch64
+ *
+ * Authors: Eduard Vintilă <eduard.vintila47@gmail.com>
+ *
+ * Copyright (c) 2023, University of Bucharest. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+ */
+
+
+
+#if defined(__ARM_64__)
+
+/*
+ * We save the following registers for each Goroutine context switch:
+ *
+ * x18 -> platform register
+ * x19-x28 -> callee saved registers
+ * x29 -> frame pointer
+ * x30 -> link register (i.e. return PC)
+ * sp -> stack pointer
+ *
+ * Total: 14 regs
+ */
+
+#define PC_OFF (12*8)
+#define SP_OFF (13*8)
+
+// int __go_getcontext(__go_context_t* context);
+//                                         x0
+.globl __go_getcontext
+.text
+__go_getcontext:
+
+       /* Save GP-regs */
+       stp x19, x20, [x0], #0x10
+       stp x21, x22, [x0], #0x10
+       stp x23, x24, [x0], #0x10
+       stp x25, x26, [x0], #0x10
+       stp x27, x28, [x0], #0x10
+
+       /* Save PR and FP */
+       stp x18, x29, [x0], #0x10
+
+       /* Save Return PC and SP */
+       mov x1, sp
+       stp x30, x1, [x0], #0x10
+
+       ret
+
+// int __go_setcontext(__go_context_t* context);
+//                                         x0
+.globl __go_setcontext
+.text
+__go_setcontext:
+       /* Set GP-regs */
+       ldp x19, x20, [x0], #0x10
+       ldp x21, x22, [x0], #0x10
+       ldp x23, x24, [x0], #0x10
+       ldp x25, x26, [x0], #0x10
+       ldp x27, x28, [x0], #0x10
+
+       /* Set PR and FP */
+       ldp x18, x29, [x0], #0x10
+
+       /* Set Return PC and SP */
+       ldp x30, x1, [x0], #0x10
+       mov sp, x1
+
+       ret
+
+//void __go_makecontext(__go_context_t* context, void (*)() fn, void* sp, size_t size);
+//                                          x0,             x1,       x2,         x3
+.globl __go_makecontext
+.text
+__go_makecontext:
+       /* Allocate space for the stack */
+       add x4, x2, x3
+
+       /* Align the stack pointer */
+       and x4, x4, #0xfffffffffffffff0
+
+       /* Store SP and PC in the context structure */
+       str x4, [x0, #SP_OFF]
+       str x1, [x0, #PC_OFF]
+
+       ret
+
+       .section        .note.GNU-split-stack,"",@progbits
+       .section        .note.GNU-no-split-stack,"",@progbits
+
+#endif
+
+       .section        .note.GNU-stack,"",@progbits
diff --git a/patches/0003-Add-context-switch-functions-for-ARM64.patch b/patches/0003-Add-context-switch-functions-for-ARM64.patch
new file mode 100644 (file)
index 0000000..c0e3a91
--- /dev/null
@@ -0,0 +1,41 @@
+From 1c50741ef721664dc646b9ef989838f992c59f37 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Eduard=20Vintil=C4=83?= <eduard.vintila47@gmail.com>
+Date: Wed, 8 Nov 2023 12:39:21 +0200
+Subject: [PATCH] Add context switch functions for ARM64
+
+Signed-off-by: Eduard Vintilă <eduard.vintila47@gmail.com>
+
+---
+ libgo/runtime/runtime.h | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
+index b3dc4fd24..2598fddf0 100644
+--- a/libgo/runtime/runtime.h
++++ b/libgo/runtime/runtime.h
+@@ -491,7 +491,7 @@ bool probestackmaps(void)
+ extern uint32 __go_runtime_in_callers;
+
+ // Cheaper context switch functions.  Currently only defined on
+-// Linux/AMD64.
++// Linux/AMD64 and ARM64.
+ #if defined(__x86_64__) && defined(__linux__) && !defined(__CET__)
+ typedef struct {
+       uint64 regs[8];
+@@ -499,6 +499,13 @@ typedef struct {
+ int __go_getcontext(__go_context_t*);
+ int __go_setcontext(__go_context_t*);
+ void __go_makecontext(__go_context_t*, void (*)(), void*, size_t);
++#elif defined(__ARM_64__)
++typedef struct {
++      uint64 regs[14];
++} __go_context_t;
++int __go_getcontext(__go_context_t*);
++int __go_setcontext(__go_context_t*);
++void __go_makecontext(__go_context_t*, void (*)(), void*, size_t);
+ #else
+ #define __go_context_t        ucontext_t
+ #define __go_getcontext(c)    getcontext(c)
+--
+2.42.0
+