[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |