[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 4/4] lib/ukcontext: add {get, set, swap, make, start}context implementation



Copied from https://github.com/AdelieLinux/libucontext with some small
changes.

Commits:
getcontext.S:   6046eb4
setcontext.S:   6046eb4
startcontext.S: 0622245
swapcontext.S:  790ed28
makecontext.c:  da10e5a

Signed-off by: Charalampos Mainas <charalampos.mainas@xxxxxxxxx>
---
 lib/ukucontext/Makefile.uk    |  6 ++-
 lib/ukucontext/exportsyms.uk  |  4 ++
 lib/ukucontext/getcontext.S   | 49 ++++++++++++++++++++++
 lib/ukucontext/makecontext.c  | 78 +++++++++++++++++++++++++++++++++++
 lib/ukucontext/setcontext.S   | 45 ++++++++++++++++++++
 lib/ukucontext/startcontext.S | 33 +++++++++++++++
 lib/ukucontext/swapcontext.S  | 75 +++++++++++++++++++++++++++++++++
 7 files changed, 289 insertions(+), 1 deletion(-)
 create mode 100644 lib/ukucontext/getcontext.S
 create mode 100644 lib/ukucontext/makecontext.c
 create mode 100644 lib/ukucontext/setcontext.S
 create mode 100644 lib/ukucontext/startcontext.S
 create mode 100644 lib/ukucontext/swapcontext.S

diff --git a/lib/ukucontext/Makefile.uk b/lib/ukucontext/Makefile.uk
index 0f92b6ca..e42f9bb9 100644
--- a/lib/ukucontext/Makefile.uk
+++ b/lib/ukucontext/Makefile.uk
@@ -44,4 +44,8 @@ $(eval $(call addlib_s,libucontext,$(CONFIG_LIBUCONTEXT)))
 CINCLUDES-$(CONFIG_LIBUCONTEXT)    += -I$(LIBUCONTEXT_BASE)/include      
 CXXINCLUDES-$(CONFIG_LIBUCONTEXT)  += -I$(LIBUCONTEXT_BASE)/include      
 
-
+LIBUCONTEXT_SRCS-y += $(LIBUCONTEXT_BASE)/getcontext.S
+LIBUCONTEXT_SRCS-y += $(LIBUCONTEXT_BASE)/swapcontext.S
+LIBUCONTEXT_SRCS-y += $(LIBUCONTEXT_BASE)/setcontext.S
+LIBUCONTEXT_SRCS-y += $(LIBUCONTEXT_BASE)/startcontext.S
+LIBUCONTEXT_SRCS-y += $(LIBUCONTEXT_BASE)/makecontext.c
diff --git a/lib/ukucontext/exportsyms.uk b/lib/ukucontext/exportsyms.uk
index e69de29b..ade29ee7 100644
--- a/lib/ukucontext/exportsyms.uk
+++ b/lib/ukucontext/exportsyms.uk
@@ -0,0 +1,4 @@
+makecontext
+setcontext
+swapcontext
+getcontext
diff --git a/lib/ukucontext/getcontext.S b/lib/ukucontext/getcontext.S
new file mode 100644
index 00000000..ee4c9af1
--- /dev/null
+++ b/lib/ukucontext/getcontext.S
@@ -0,0 +1,49 @@
+// Taken from https://github.com/AdelieLinux/libucontext
+/*
+ * Copyright (c) 2018 William Pitcock <nenolod@xxxxxxxxxxxxxxxx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied.  In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+.globl __getcontext;
+__getcontext:
+       /* copy all of the current registers into the ucontext structure */
+       movq    %r8, 40(%rdi)
+       movq    %r9, 48(%rdi)
+       movq    %r10, 56(%rdi)
+       movq    %r11, 64(%rdi)
+       movq    %r12, 72(%rdi)
+       movq    %r13, 80(%rdi)
+       movq    %r14, 88(%rdi)
+       movq    %r15, 96(%rdi)
+       movq    %rdi, 104(%rdi)
+       movq    %rsi, 112(%rdi)
+       movq    %rbp, 120(%rdi)
+       movq    %rbx, 128(%rdi)
+       movq    %rdx, 136(%rdi)
+       movq    $1, 144(%rdi)           /* $1 is %rax */
+       movq    %rcx, 152(%rdi)
+
+       /* the first argument on the stack is the jump target (%rip), so we 
store it in the RIP
+          register in the ucontext structure. */
+       movq    (%rsp), %rcx
+       movq    %rcx, 168(%rdi)
+
+       /* finally take the stack pointer address (%rsp) offsetting by 8 to 
skip over the jump
+          target. */
+       leaq    8(%rsp), %rcx
+       movq    %rcx, 160(%rdi)
+
+       /* we're all done here, return 0 */
+       xorl    %eax, %eax
+       ret
+
+
+.weak getcontext;
+getcontext = __getcontext;
diff --git a/lib/ukucontext/makecontext.c b/lib/ukucontext/makecontext.c
new file mode 100644
index 00000000..b5a32eee
--- /dev/null
+++ b/lib/ukucontext/makecontext.c
@@ -0,0 +1,78 @@
+// Taken from https://github.com/AdelieLinux/libucontext
+/*
+ * Copyright (c) 2018 William Pitcock <nenolod@xxxxxxxxxxxxxxxx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied.  In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+#define _GNU_SOURCE
+#include <stddef.h>
+#include <stdarg.h>
+#include <ucontext.h>
+#include <string.h>
+#include <stdint.h>
+
+
+extern void __start_context(void);
+
+
+void
+__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
+{
+       greg_t *sp;
+       va_list va;
+       int i;
+       unsigned int uc_link;
+
+       uc_link = (argc > 6 ? argc - 6 : 0) + 1;
+
+       sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + 
ucp->uc_stack.ss_size);
+       sp -= uc_link;
+       sp = (greg_t *) (((uintptr_t) sp & -16L) - 8);
+
+       ucp->uc_mcontext.gregs[REG_RIP] = (uintptr_t) func;
+       ucp->uc_mcontext.gregs[REG_RBX] = (uintptr_t) &sp[uc_link];
+       ucp->uc_mcontext.gregs[REG_RSP] = (uintptr_t) sp;
+
+       sp[0] = (uintptr_t) &__start_context;
+       sp[uc_link] = (uintptr_t) ucp->uc_link;
+
+       va_start(va, argc);
+
+       for (i = 0; i < argc; i++)
+               switch (i)
+               {
+               case 0:
+                       ucp->uc_mcontext.gregs[REG_RDI] = va_arg (va, greg_t);
+                       break;
+               case 1:
+                       ucp->uc_mcontext.gregs[REG_RSI] = va_arg (va, greg_t);
+                       break;
+               case 2:
+                       ucp->uc_mcontext.gregs[REG_RDX] = va_arg (va, greg_t);
+                       break;
+               case 3:
+                       ucp->uc_mcontext.gregs[REG_RCX] = va_arg (va, greg_t);
+                       break;
+               case 4:
+                       ucp->uc_mcontext.gregs[REG_R8] = va_arg (va, greg_t);
+                       break;
+               case 5:
+                       ucp->uc_mcontext.gregs[REG_R9] = va_arg (va, greg_t);
+                       break;
+               default:
+                       sp[i - 5] = va_arg (va, greg_t);
+                       break;
+               }
+
+       va_end(va);
+}
+
+
+extern __typeof(__makecontext) makecontext __attribute__((weak, 
__alias__("__makecontext")));
diff --git a/lib/ukucontext/setcontext.S b/lib/ukucontext/setcontext.S
new file mode 100644
index 00000000..d1807e21
--- /dev/null
+++ b/lib/ukucontext/setcontext.S
@@ -0,0 +1,45 @@
+// Taken from https://github.com/AdelieLinux/libucontext
+/*
+ * Copyright (c) 2018 William Pitcock <nenolod@xxxxxxxxxxxxxxxx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied.  In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+.globl __setcontext;
+__setcontext:
+       /* set all of the registers */
+       movq    40(%rdi), %r8
+       movq    48(%rdi), %r9
+       movq    56(%rdi), %r10
+       movq    64(%rdi), %r11
+       movq    72(%rdi), %r12
+       movq    80(%rdi), %r13
+       movq    88(%rdi), %r14
+       movq    96(%rdi), %r15
+       movq    112(%rdi), %rsi
+       movq    120(%rdi), %rbp
+       movq    128(%rdi), %rbx
+       movq    136(%rdi), %rdx
+       movq    144(%rdi), %rax
+       movq    152(%rdi), %rcx
+       movq    160(%rdi), %rsp
+
+       /* set the jump target by pushing it to the stack.
+          ret will pop the new %rip from the stack, causing us to jump there. 
*/
+       pushq   168(%rdi)
+
+       /* finally, set %rdi correctly. */
+       movq    104(%rdi), %rdi
+
+       /* we're all done here, return 0 */
+       xorl    %eax, %eax
+       ret
+
+.weak setcontext;
+setcontext = __setcontext;
diff --git a/lib/ukucontext/startcontext.S b/lib/ukucontext/startcontext.S
new file mode 100644
index 00000000..26cccbac
--- /dev/null
+++ b/lib/ukucontext/startcontext.S
@@ -0,0 +1,33 @@
+// Taken from https://github.com/AdelieLinux/libucontext
+/*
+ * Copyright (c) 2018 William Pitcock <nenolod@xxxxxxxxxxxxxxxx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied.  In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+.globl __start_context;
+__start_context:
+       /* get the proper context into position and test for NULL */
+       movq    %rbx, %rsp
+       movq    (%rsp), %rdi
+       testq   %rdi, %rdi
+
+       /* if we have no linked context, lets get out of here */
+       je      no_linked_context
+
+       /* call setcontext to switch to the linked context */
+       call    __setcontext@plt
+       movq    %rax, %rdi
+
+no_linked_context:
+       /* we are returning into a null context, it seems, so maybe we should 
exit */
+       call    ukplat_terminate@plt
+
+       /* something is really hosed, call hlt to force termination */
+       hlt
diff --git a/lib/ukucontext/swapcontext.S b/lib/ukucontext/swapcontext.S
new file mode 100644
index 00000000..c0e7bae3
--- /dev/null
+++ b/lib/ukucontext/swapcontext.S
@@ -0,0 +1,75 @@
+//Taken from https://github.com/AdelieLinux/libucontext
+/*
+ * Copyright (c) 2018 William Pitcock <nenolod@xxxxxxxxxxxxxxxx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied.  In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+.globl __swapcontext;
+__swapcontext:
+       /* copy all of the current registers into the ucontext structure 
pointed by
+          the first argument */
+       movq    %r8, 40(%rdi)
+       movq    %r9, 48(%rdi)
+       movq    %r10, 56(%rdi)
+       movq    %r11, 64(%rdi)
+       movq    %r12, 72(%rdi)
+       movq    %r13, 80(%rdi)
+       movq    %r14, 88(%rdi)
+       movq    %r15, 96(%rdi)
+       movq    %rdi, 104(%rdi)
+       movq    %rsi, 112(%rdi)
+       movq    %rbp, 120(%rdi)
+       movq    %rbx, 128(%rdi)
+       movq    %rdx, 136(%rdi)
+       movq    $1, 144(%rdi)           /* $1 is %rax */
+       movq    %rcx, 152(%rdi)
+
+       /* the first argument on the stack is the jump target (%rip), so we 
store it in the RIP
+          register in the ucontext structure. */
+       movq    (%rsp), %rcx
+       movq    %rcx, 168(%rdi)
+
+       /* finally take the stack pointer address (%rsp) offsetting by 8 to 
skip over the jump
+          target. */
+       leaq    8(%rsp), %rcx
+       movq    %rcx, 160(%rdi)
+
+       /* set all of the registers to their new states, stored in the second
+          ucontext structure */        
+       movq    40(%rsi), %r8
+       movq    48(%rsi), %r9
+       movq    56(%rsi), %r10
+       movq    64(%rsi), %r11
+       movq    72(%rsi), %r12
+       movq    80(%rsi), %r13
+       movq    88(%rsi), %r14
+       movq    96(%rsi), %r15
+       movq    104(%rsi), %rdi
+       movq    120(%rsi), %rbp
+       movq    128(%rsi), %rbx
+       movq    136(%rsi), %rdx
+       movq    144(%rsi), %rax
+       movq    152(%rsi), %rcx
+       movq    160(%rsi), %rsp
+
+       /* set the jump target by pushing it to the stack.
+          ret will pop the new %rip from the stack, causing us to jump there. 
*/
+       pushq   168(%rsi)
+
+       /* finally, set %rsi correctly since we do not need it anymore. */
+       movq    112(%rsi), %rsi
+
+       /* we're all done here, return 0 */
+       xorl    %eax, %eax
+       ret
+
+
+.weak swapcontext;
+swapcontext = __swapcontext;
-- 
2.17.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.