Index: uspace/lib/c/arch/abs32le/src/fibril.c
===================================================================
--- uspace/lib/c/arch/abs32le/src/fibril.c	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/abs32le/src/fibril.c	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -30,13 +30,13 @@
  */
 
-#include <fibril.h>
+#include <setjmp.h>
 #include <stdbool.h>
 
-int context_save(context_t *ctx)
+int __setjmp(context_t *ctx)
 {
-	return 1;
+	return 0;
 }
 
-void context_restore(context_t *ctx)
+void __longjmp(context_t *ctx, int val)
 {
 	while (true);
Index: uspace/lib/c/arch/amd64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/amd64/src/fibril.S	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/amd64/src/fibril.S	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -35,7 +35,7 @@
 #
 # Save CPU context to context_t variable
-# pointed by the 1st argument. Returns 1 in EAX.
+# pointed by the 1st argument. Returns 0 in RAX.
 #
-FUNCTION_BEGIN(context_save)
+FUNCTION_BEGIN(__setjmp)
 	movq (%rsp), %rdx     # the caller's return %eip
 
@@ -54,15 +54,14 @@
 	movq %rax, CONTEXT_OFFSET_TLS(%rdi)
 
-	xorl %eax, %eax                      # context_save returns 1
-	incl %eax
+	xorq %rax, %rax                      # __setjmp returns 0
 	ret
-FUNCTION_END(context_save)
+FUNCTION_END(__setjmp)
 
 ## Restore current CPU context
 #
 # Restore CPU context from context_t variable
-# pointed by the 1st argument. Returns 0 in EAX.
+# pointed by the 1st argument. Returns second argument in RAX.
 #
-FUNCTION_BEGIN(context_restore)
+FUNCTION_BEGIN(__longjmp)
 	movq CONTEXT_OFFSET_R15(%rdi), %r15
 	movq CONTEXT_OFFSET_R14(%rdi), %r14
@@ -81,6 +80,6 @@
 	movq %rdi, %fs:0
 
-	xorl %eax, %eax                      # context_restore returns 0
+	movq %rsi, %rax                      # __longjmp returns second argument
 	ret
-FUNCTION_END(context_restore)
+FUNCTION_END(__longjmp)
 
Index: uspace/lib/c/arch/arm32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/arm32/src/fibril.S	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/arm32/src/fibril.S	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -31,20 +31,20 @@
 .text
 
-FUNCTION_BEGIN(context_save)
+FUNCTION_BEGIN(__setjmp)
 	stmia r0!, {sp, lr}
 	stmia r0!, {r4-r11}
-
-	# return 1
-	mov r0, #1
-	mov pc, lr
-FUNCTION_END(context_save)
-
-FUNCTION_BEGIN(context_restore)
-	ldmia r0!, {sp, lr}
-	ldmia r0!, {r4-r11}
 
 	# return 0
 	mov r0, #0
 	mov pc, lr
-FUNCTION_END(context_restore)
+FUNCTION_END(__setjmp)
 
+FUNCTION_BEGIN(__longjmp)
+	ldmia r0!, {sp, lr}
+	ldmia r0!, {r4-r11}
+
+	# return second argument
+	mov r0, r1
+	mov pc, lr
+FUNCTION_END(__longjmp)
+
Index: uspace/lib/c/arch/ia32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ia32/src/fibril.S	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/ia32/src/fibril.S	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -35,7 +35,7 @@
 #
 # Save CPU context to the context_t variable
-# pointed by the 1st argument. Returns 1 in EAX.
+# pointed by the 1st argument. Returns 0 in EAX.
 #
-FUNCTION_BEGIN(context_save)
+FUNCTION_BEGIN(__setjmp)
 	movl 0(%esp), %eax  # the caller's return %eip
 	movl 4(%esp), %edx  # address of the context variable to save context to
@@ -53,16 +53,16 @@
 	movl %eax, CONTEXT_OFFSET_TLS(%edx)	# tls -> ctx->tls
 
-	xorl %eax, %eax		# context_save returns 1
-	incl %eax
+	xorl %eax, %eax		# __setjmp returns 0
 	ret
-FUNCTION_END(context_save)
+FUNCTION_END(__setjmp)
 
 ## Restore saved CPU context
 #
 # Restore CPU context from context_t variable
-# pointed by the 1st argument. Returns 0 in EAX.
+# pointed by the 1st argument. Returns second argument in EAX.
 #
-FUNCTION_BEGIN(context_restore)
+FUNCTION_BEGIN(__longjmp)
 	movl 4(%esp), %eax  # address of the context variable to restore context from
+	movl 8(%esp), %ecx  # return value
 
 	# restore registers from the context structure
@@ -80,6 +80,6 @@
 	movl %edx, %gs:0
 
-	xorl %eax, %eax		# context_restore returns 0
+	movl %ecx, %eax
 	ret
-FUNCTION_END(context_restore)
+FUNCTION_END(__longjmp)
 
Index: uspace/lib/c/arch/ia64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -43,5 +43,5 @@
 
 /*
- * context_save() and context_restore() are both leaf procedures.
+ * __setjmp() and __longjmp() are both leaf procedures.
  * No need to allocate scratch area.
  */
Index: uspace/lib/c/arch/ia64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ia64/src/fibril.S	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/ia64/src/fibril.S	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -32,5 +32,5 @@
 .text
 
-FUNCTION_BEGIN(context_save)
+FUNCTION_BEGIN(__setjmp)
 	alloc loc0 = ar.pfs, 1, 49, 0, 0
 	mov loc1 = ar.unat ;;
@@ -178,10 +178,10 @@
 	mov ar.unat = loc1
 
-	add r8 = r0, r0, 1 	/* context_save returns 1 */
+	mov r8 = 0 	/* __setjmp returns 0 */
 	br.ret.sptk.many b0
-FUNCTION_END(context_save)
-
-FUNCTION_BEGIN(context_restore)
-	alloc loc0 = ar.pfs, 1, 50, 0, 0	;;
+FUNCTION_END(__setjmp)
+
+FUNCTION_BEGIN(__longjmp)
+	alloc loc0 = ar.pfs, 2, 51, 0, 0	;;
 
 	add loc9 = CONTEXT_OFFSET_AR_PFS, in0
@@ -230,5 +230,6 @@
 	add loc47 = CONTEXT_OFFSET_F29, in0
 	add loc48 = CONTEXT_OFFSET_F30, in0
-	add loc49 = CONTEXT_OFFSET_F31, in0 ;;
+	add loc49 = CONTEXT_OFFSET_F31, in0
+	mov loc50 = in1 ;;
 
 	ld8 loc0 = [loc9]	/* load ar.pfs */
@@ -335,5 +336,5 @@
 	mov ar.unat = loc1
 
-	mov r8 = r0			/* context_restore returns 0 */
+	mov r8 = loc50			/* __longjmp returns second argument */
 	br.ret.sptk.many b0
-FUNCTION_END(context_restore)
+FUNCTION_END(__longjmp)
Index: uspace/lib/c/arch/mips32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/mips32/src/fibril.S	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/mips32/src/fibril.S	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -35,5 +35,5 @@
 #include <libarch/fibril_context.h>
 
-FUNCTION_BEGIN(context_save)
+FUNCTION_BEGIN(__setjmp)
 	sw $s0, CONTEXT_OFFSET_S0($a0)
 	sw $s1, CONTEXT_OFFSET_S1($a0)
@@ -87,10 +87,10 @@
 	sw $sp, CONTEXT_OFFSET_SP($a0)
 
-	# context_save returns 1
+	# __setjmp returns 0
 	j $ra
-	li $v0, 1
-FUNCTION_END(context_save)
+	li $v0, 0
+FUNCTION_END(__setjmp)
 
-FUNCTION_BEGIN(context_restore)
+FUNCTION_BEGIN(__longjmp)
 	lw $s0, CONTEXT_OFFSET_S0($a0)
 	lw $s1, CONTEXT_OFFSET_S1($a0)
@@ -147,6 +147,6 @@
 	move $t9, $ra
 
-	# context_restore returns 0
+	# __longjmp returns second argument
 	j $ra
-	xor $v0, $v0
-FUNCTION_END(context_restore)
+	move $v0, $a1
+FUNCTION_END(__longjmp)
Index: uspace/lib/c/arch/ppc32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ppc32/src/fibril.S	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/ppc32/src/fibril.S	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -33,5 +33,5 @@
 #include <libarch/fibril_context.h>
 
-FUNCTION_BEGIN(context_save)
+FUNCTION_BEGIN(__setjmp)
 	stw sp, CONTEXT_OFFSET_SP(r3)
 	stw r2, CONTEXT_OFFSET_TLS(r3)
@@ -62,10 +62,10 @@
 	stw r4, CONTEXT_OFFSET_CR(r3)
 
-	# context_save returns 1
-	li r3, 1
+	# __setjmp returns 0
+	li r3, 0
 	blr
-FUNCTION_END(context_save)
+FUNCTION_END(__setjmp)
 
-FUNCTION_BEGIN(context_restore)
+FUNCTION_BEGIN(__longjmp)
 	lwz sp, CONTEXT_OFFSET_SP(r3)
 	lwz r2, CONTEXT_OFFSET_TLS(r3)
@@ -90,12 +90,12 @@
 	lwz r31, CONTEXT_OFFSET_R31(r3)
 
-	lwz r4, CONTEXT_OFFSET_CR(r3)
-	mtcr r4
+	lwz r5, CONTEXT_OFFSET_CR(r3)
+	mtcr r5
 
-	lwz r4, CONTEXT_OFFSET_PC(r3)
-	mtlr r4
+	lwz r5, CONTEXT_OFFSET_PC(r3)
+	mtlr r5
 
-	# context_restore returns 0
-	li r3, 0
+	# __longjmp returns second argument
+	mr r3, r4
 	blr
-FUNCTION_END(context_restore)
+FUNCTION_END(__longjmp)
Index: uspace/lib/c/arch/riscv64/src/fibril.c
===================================================================
--- uspace/lib/c/arch/riscv64/src/fibril.c	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/riscv64/src/fibril.c	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -33,10 +33,10 @@
 #include <stdbool.h>
 
-int context_save(context_t *ctx)
+int __setjmp(context_t *ctx)
 {
-	return 1;
+	return 0;
 }
 
-void context_restore(context_t *ctx)
+void __longjmp(context_t *ctx, int ret)
 {
 	while (true);
Index: uspace/lib/c/arch/sparc64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/sparc64/src/fibril.S	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/arch/sparc64/src/fibril.S	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -32,5 +32,5 @@
 .text
 
-FUNCTION_BEGIN(context_save)
+FUNCTION_BEGIN(__setjmp)
 	#
 	# We rely on the kernel to flush our active register windows to memory
@@ -57,8 +57,8 @@
 	stx %g7, [%o0 + CONTEXT_OFFSET_TP]
 	retl
-	mov 1, %o0		! context_save_arch returns 1
-FUNCTION_END(context_save)
+	mov 0, %o0		! __setjmp returns 0
+FUNCTION_END(__setjmp)
 
-FUNCTION_BEGIN(context_restore)
+FUNCTION_BEGIN(__longjmp)
 	#
 	# Flush all active windows.
@@ -89,4 +89,4 @@
 	ldx [%o0 + CONTEXT_OFFSET_TP], %g7
 	retl
-	xor %o0, %o0, %o0	! context_restore_arch returns 0
-FUNCTION_END(context_restore)
+	mov %o1, %o0	! __longjmp returns second argument
+FUNCTION_END(__longjmp)
Index: uspace/lib/c/generic/context.c
===================================================================
--- uspace/lib/c/generic/context.c	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/generic/context.c	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -28,4 +28,5 @@
 
 #include <context.h>
+#include <setjmp.h>
 #include <libarch/tls.h>
 #include <libarch/fibril.h>
@@ -42,11 +43,11 @@
 void context_swap(context_t *self, context_t *other)
 {
-	if (context_save(self))
-		context_restore(other);
+	if (!__setjmp(self))
+		__longjmp(other, 1);
 }
 
 void context_create(context_t *context, const context_create_t *arg)
 {
-	context_save(context);
+	__setjmp(context);
 	context_set(context, FADDR(arg->fn), arg->stack_base,
 	    arg->stack_size, arg->tls);
Index: uspace/lib/c/generic/setjmp.c
===================================================================
--- uspace/lib/c/generic/setjmp.c	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/generic/setjmp.c	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2013 Vojtech Horky
+ * Copyright (c) 2018 CZ.NIC, z.s.p.o.
  * All rights reserved.
  *
@@ -30,30 +31,13 @@
  * @{
  */
-/** @file Long jump implementation.
- *
- * Implementation inspired by Jiri Zarevucky's code from
- * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
- */
 
 #include <setjmp.h>
 #include <context.h>
 
-// TODO: setjmp/longjmp are basically a stronger version of
-// context_save/context_restore. It would be preferable to turn
-// those two into setjmp/longjmp (all it would need is preserving the
-// return value).
-
-/**
- * Restore environment previously stored by setjmp.
- *
- * This function never returns.
- *
- * @param env Variable with the environment previously stored by call
- * to setjmp.
- * @param val Value to fake when returning from setjmp (0 is transformed to 1).
- */
-void longjmp(jmp_buf env, int val) {
-	env[0].return_value = (val == 0) ? 1 : val;
-	context_restore(&env[0].context);
+/** Standard function implementation. */
+void longjmp(jmp_buf env, int val)
+{
+	/* __longjmp defined in assembly doesn't "correct" the value. */
+	__longjmp(env, val == 0 ? 1 : val);
 }
 
Index: uspace/lib/c/include/context.h
===================================================================
--- uspace/lib/c/include/context.h	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/include/context.h	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -46,9 +46,4 @@
 extern uintptr_t context_get_pc(context_t *ctx);
 
-// TODO: These should go away.
-
-extern int context_save(context_t *ctx) __attribute__((returns_twice));
-extern void context_restore(context_t *ctx) __attribute__((noreturn));
-
 #endif
 
Index: uspace/lib/c/include/setjmp.h
===================================================================
--- uspace/lib/c/include/setjmp.h	(revision f3d47c976431122cd3b0844f80937c7fdb899b40)
+++ uspace/lib/c/include/setjmp.h	(revision a35a3d819d4e2e4e35964eea617087b5c6431b02)
@@ -1,5 +1,4 @@
 /*
- * Copyright (c) 2008 Josef Cejka
- * Copyright (c) 2013 Vojtech Horky
+ * Copyright (c) 2018 CZ.NIC, z.s.p.o.
  * All rights reserved.
  *
@@ -31,43 +30,17 @@
  * @{
  */
-/** @file Long jump implementation.
- *
- * Implementation inspired by Jiri Zarevucky's code from
- * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
- */
 
 #ifndef LIBC_SETJMP_H_
 #define LIBC_SETJMP_H_
 
-#include <libarch/fibril.h>
+#include <libarch/fibril_context.h>
 
-struct jmp_buf_interal {
-	context_t context;
-	int return_value;
-};
-typedef struct jmp_buf_interal jmp_buf[1];
+typedef context_t jmp_buf[1];
 
-/*
- * Specified as extern to minimize number of included headers
- * because this file is used as is in libposix too.
- */
-extern int context_save(context_t *ctx) __attribute__((returns_twice));
+extern int __setjmp(jmp_buf) __attribute__((returns_twice));
+extern _Noreturn void __longjmp(jmp_buf, int);
 
-/**
- * Save current environment (registers).
- *
- * This function may return twice.
- *
- * @param env Variable where to save the environment (of type jmp_buf).
- * @return Whether the call returned after longjmp.
- * @retval 0 Environment was saved, normal execution.
- * @retval other longjmp was executed and returned here.
- */
-#define setjmp(env) \
-	((env)[0].return_value = 0, \
-	context_save(&(env)[0].context), \
-	(env)[0].return_value)
-
-extern void longjmp(jmp_buf env, int val) __attribute__((noreturn));
+#define setjmp __setjmp
+extern _Noreturn void longjmp(jmp_buf, int);
 
 #endif
