Index: kernel/arch/abs32le/src/proc/thread.c
===================================================================
--- kernel/arch/abs32le/src/proc/thread.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/abs32le/src/proc/thread.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -35,6 +35,7 @@
 #include <proc/thread.h>
 
-void thread_create_arch(thread_t *t)
+errno_t thread_create_arch(thread_t *t, thread_flags_t flags)
 {
+	return EOK;
 }
 
Index: kernel/arch/amd64/src/proc/thread.c
===================================================================
--- kernel/arch/amd64/src/proc/thread.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/amd64/src/proc/thread.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -42,5 +42,5 @@
  *
  */
-void thread_create_arch(thread_t *thread)
+errno_t thread_create_arch(thread_t *thread, thread_flags_t flags)
 {
 	/*
@@ -49,4 +49,5 @@
 	thread->arch.kstack_rsp =
 	    (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(istate_t)];
+	return EOK;
 }
 
Index: kernel/arch/arm32/include/arch/proc/thread.h
===================================================================
--- kernel/arch/arm32/include/arch/proc/thread.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/arm32/include/arch/proc/thread.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -42,5 +42,5 @@
 #define thr_constructor_arch(t)
 #define thr_destructor_arch(t)
-#define thread_create_arch(t)
+#define thread_create_arch(t, flags) (EOK)
 
 #endif
Index: kernel/arch/ia32/src/proc/thread.c
===================================================================
--- kernel/arch/ia32/src/proc/thread.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/ia32/src/proc/thread.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -39,6 +39,7 @@
  * @param t Thread to be initialized.
  */
-void thread_create_arch(thread_t *t)
+errno_t thread_create_arch(thread_t *t, thread_flags_t flags)
 {
+	return EOK;
 }
 
Index: kernel/arch/ia64/include/arch/proc/thread.h
===================================================================
--- kernel/arch/ia64/include/arch/proc/thread.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/ia64/include/arch/proc/thread.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -41,5 +41,5 @@
 #define thr_constructor_arch(t)
 #define thr_destructor_arch(t)
-#define thread_create_arch(t)
+#define thread_create_arch(t, flags) (EOK)
 
 #endif
Index: kernel/arch/mips32/include/arch/proc/thread.h
===================================================================
--- kernel/arch/mips32/include/arch/proc/thread.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/mips32/include/arch/proc/thread.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -41,5 +41,5 @@
 #define thr_constructor_arch(t)
 #define thr_destructor_arch(t)
-#define thread_create_arch(t)
+#define thread_create_arch(t, flags) (EOK)
 
 #endif
Index: kernel/arch/ppc32/include/arch/proc/thread.h
===================================================================
--- kernel/arch/ppc32/include/arch/proc/thread.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/ppc32/include/arch/proc/thread.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -41,5 +41,5 @@
 #define thr_constructor_arch(t)
 #define thr_destructor_arch(t)
-#define thread_create_arch(t)
+#define thread_create_arch(t, flags) (EOK)
 
 #endif
Index: kernel/arch/riscv64/src/proc/thread.c
===================================================================
--- kernel/arch/riscv64/src/proc/thread.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/riscv64/src/proc/thread.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -35,6 +35,7 @@
 #include <proc/thread.h>
 
-void thread_create_arch(thread_t *t)
+errno_t thread_create_arch(thread_t *t, thread_flags_t flags)
 {
+	return EOK;
 }
 
Index: kernel/arch/sparc64/src/proc/thread.c
===================================================================
--- kernel/arch/sparc64/src/proc/thread.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/arch/sparc64/src/proc/thread.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -62,12 +62,14 @@
 }
 
-void thread_create_arch(thread_t *t)
+errno_t thread_create_arch(thread_t *t, thread_flags_t flags)
 {
-	if ((t->uspace) && (!t->arch.uspace_window_buffer)) {
+	if ((flags & THREAD_FLAG_USPACE) && (!t->arch.uspace_window_buffer)) {
 		/*
 		 * The thread needs userspace window buffer and the object
 		 * returned from the slab allocator doesn't have any.
 		 */
-		t->arch.uspace_window_buffer = slab_alloc(uwb_cache, 0);
+		t->arch.uspace_window_buffer = slab_alloc(uwb_cache, FRAME_ATOMIC);
+		if (!t->arch.uspace_window_buffer)
+			return ENOMEM;
 	} else {
 		uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
@@ -80,4 +82,5 @@
 		    UWB_ALIGNMENT);
 	}
+	return EOK;
 }
 
Index: kernel/genarch/src/mm/asid_fifo.c
===================================================================
--- kernel/genarch/src/mm/asid_fifo.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/genarch/src/mm/asid_fifo.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -65,4 +65,10 @@
 #if (!FIFO_STATIC)
 	fifo_create(free_asids);
+	if (!free_asids.fifo)
+		panic("Not enough memory to allocate ASID FIFO");
+	// TODO: There really is no reason not to statically allocate it
+	//       except to keep binary size low. Once kernel is a regular ELF
+	//       binary supporting .bss section (wip as of the late 2018),
+	//       the dynamic option should be removed.
 #endif
 
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -386,5 +386,7 @@
 static void ofw_tree_node_sysinfo(ofw_tree_node_t *node, const char *path)
 {
-	char *cur_path = (char *) nfmalloc(PATH_MAX_LEN);
+	char *cur_path = malloc(PATH_MAX_LEN);
+	if (!cur_path)
+		panic("Not enough memory to process OFW tree.");
 
 	for (ofw_tree_node_t *cur = node; cur; cur = cur->peer) {
Index: kernel/generic/include/adt/fifo.h
===================================================================
--- kernel/generic/include/adt/fifo.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/include/adt/fifo.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -115,5 +115,5 @@
  */
 #define fifo_create(name) \
-	name.fifo = nfmalloc(sizeof(*name.fifo) * name.items)
+	name.fifo = malloc(sizeof(*name.fifo) * name.items)
 
 #endif
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/include/ipc/ipc.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -47,4 +47,5 @@
 struct answerbox;
 struct task;
+struct call;
 
 typedef enum {
@@ -67,4 +68,6 @@
 	struct task *caller;
 	struct answerbox *callee;
+	/* A call prepared for hangup ahead of time, so that it cannot fail. */
+	struct call *hangup_call;
 	ipc_phone_state_t state;
 	atomic_t active_calls;
@@ -171,8 +174,5 @@
 extern void ipc_init(void);
 
-extern call_t *ipc_call_alloc(unsigned int);
-extern void ipc_call_free(call_t *);
-extern void ipc_call_hold(call_t *);
-extern void ipc_call_release(call_t *);
+extern call_t *ipc_call_alloc(void);
 
 extern errno_t ipc_call_sync(phone_t *, call_t *);
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/include/mm/as.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -325,5 +325,5 @@
 
 /* Introspection functions. */
-extern void as_get_area_info(as_t *, as_area_info_t **, size_t *);
+extern as_area_info_t *as_get_area_info(as_t *, size_t *);
 extern void as_print(as_t *);
 
Index: kernel/generic/include/mm/slab.h
===================================================================
--- kernel/generic/include/mm/slab.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/include/mm/slab.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -146,7 +146,4 @@
 extern void free(void *);
 
-extern void *nfmalloc(size_t)
-    __attribute__((malloc, returns_nonnull));
-
 #endif
 
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/include/proc/thread.h	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -225,5 +225,5 @@
 
 #ifndef thread_create_arch
-extern void thread_create_arch(thread_t *);
+extern errno_t thread_create_arch(thread_t *, thread_flags_t);
 #endif
 
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/console/kconsole.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -219,8 +219,14 @@
 	const char *hint;
 	const char *help;
-	char *output = nfmalloc(MAX_CMDLINE);
 	size_t hints_to_show = MAX_TAB_HINTS - 1;
 	size_t total_hints_shown = 0;
 	bool continue_showing_hints = true;
+
+	char *output = malloc(MAX_CMDLINE);
+	if (!output) {
+		// TODO: fix the function so that it does not need allocation
+		printf("Can't complete command, out of memory.\n");
+		return 0;
+	}
 
 	output[0] = 0;
@@ -325,5 +331,6 @@
 }
 
-NO_TRACE static wchar_t *clever_readline(const char *prompt, indev_t *indev)
+NO_TRACE static wchar_t *clever_readline(const char *prompt, indev_t *indev,
+    char *tmp)
 {
 	printf("%s> ", prompt);
@@ -332,5 +339,4 @@
 	wchar_t *current = history[history_pos];
 	current[0] = 0;
-	char *tmp = nfmalloc(STR_BOUNDS(MAX_CMDLINE));
 
 	while (true) {
@@ -534,5 +540,4 @@
 	}
 
-	free(tmp);
 	return current;
 }
@@ -809,7 +814,16 @@
 		printf("Type \"exit\" to leave the console.\n");
 
-	char *cmdline = nfmalloc(STR_BOUNDS(MAX_CMDLINE));
+	char *buffer = malloc(STR_BOUNDS(MAX_CMDLINE));
+	char *cmdline = malloc(STR_BOUNDS(MAX_CMDLINE));
+	if (!buffer || !cmdline) {
+		// TODO: fix the function so that it does not need allocations
+		printf("Can't start console, out of memory.\n");
+		free(buffer);
+		free(cmdline);
+		return;
+	}
+
 	while (true) {
-		wchar_t *tmp = clever_readline((char *) prompt, stdin);
+		wchar_t *tmp = clever_readline((char *) prompt, stdin, buffer);
 		size_t len = wstr_length(tmp);
 		if (!len)
@@ -827,4 +841,5 @@
 		(void) cmd_info->func(cmd_info->argv);
 	}
+	free(buffer);
 	free(cmdline);
 }
Index: kernel/generic/src/ipc/event.c
===================================================================
--- kernel/generic/src/ipc/event.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/ipc/event.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -147,5 +147,5 @@
 	if (event->answerbox != NULL) {
 		if (!event->masked) {
-			call_t *call = ipc_call_alloc(FRAME_ATOMIC);
+			call_t *call = ipc_call_alloc();
 
 			if (call) {
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/ipc/ipc.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -108,22 +108,16 @@
  * TASK->answerbox.
  *
- * @param flags Parameters for slab_alloc (e.g FRAME_ATOMIC).
- *
- * @return If flags permit it, return NULL, or initialized kernel
- *         call structure with one reference.
- *
- */
-call_t *ipc_call_alloc(unsigned int flags)
-{
-	call_t *call = slab_alloc(call_cache, flags);
+ * @return Initialized kernel call structure with one reference, or NULL.
+ *
+ */
+call_t *ipc_call_alloc(void)
+{
+	// TODO: Allocate call and kobject in single allocation
+
+	call_t *call = slab_alloc(call_cache, FRAME_ATOMIC);
 	if (!call)
 		return NULL;
 
-	kobject_t *kobj;
-	if (flags & FRAME_ATOMIC)
-		kobj = (kobject_t *) malloc(sizeof(kobject_t));
-	else
-		kobj = (kobject_t *) nfmalloc(sizeof(kobject_t));
-
+	kobject_t *kobj = (kobject_t *) malloc(sizeof(kobject_t));
 	if (!kobj) {
 		slab_free(call_cache, call);
@@ -219,5 +213,8 @@
 errno_t ipc_call_sync(phone_t *phone, call_t *request)
 {
-	answerbox_t *mybox = slab_alloc(answerbox_cache, 0);
+	answerbox_t *mybox = slab_alloc(answerbox_cache, FRAME_ATOMIC);
+	if (!mybox)
+		return ENOMEM;
+
 	ipc_answerbox_init(mybox, TASK);
 
@@ -483,5 +480,8 @@
 		kobject_put(phone->kobject);
 
-		call_t *call = ipc_call_alloc(0);
+		call_t *call = phone->hangup_call;
+		phone->hangup_call = NULL;
+		assert(call);
+
 		IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
 		call->request_method = IPC_M_PHONE_HUNGUP;
@@ -685,5 +685,8 @@
 			 * to exist as soon as we release it.
 			 */
-			call_t *call = ipc_call_alloc(0);
+			call_t *call = phone->hangup_call;
+			phone->hangup_call = NULL;
+			assert(call);
+
 			IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
 			call->request_method = IPC_M_PHONE_HUNGUP;
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -46,4 +46,6 @@
 {
 	phone_t *phone = (phone_t *) arg;
+	if (phone->hangup_call)
+		kobject_put(phone->hangup_call->kobject);
 	slab_free(phone_cache, phone);
 }
@@ -79,7 +81,15 @@
 			return ENOMEM;
 		}
+		call_t *hcall = ipc_call_alloc();
+		if (!hcall) {
+			cap_free(TASK, handle);
+			slab_free(phone_cache, phone);
+			free(kobj);
+			return ENOMEM;
+		}
 
 		ipc_phone_init(phone, task);
 		phone->state = IPC_PHONE_CONNECTING;
+		phone->hangup_call = hcall;
 
 		kobject_initialize(kobj, KOBJECT_TYPE_PHONE, phone,
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/ipc/irq.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -529,5 +529,5 @@
 
 	if (irq->notif_cfg.answerbox) {
-		call_t *call = ipc_call_alloc(FRAME_ATOMIC);
+		call_t *call = ipc_call_alloc();
 		if (!call)
 			return;
@@ -565,5 +565,5 @@
 
 	if (irq->notif_cfg.answerbox) {
-		call_t *call = ipc_call_alloc(FRAME_ATOMIC);
+		call_t *call = ipc_call_alloc();
 		if (!call) {
 			irq_spinlock_unlock(&irq->lock, true);
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/ipc/sysipc.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -267,4 +267,5 @@
  * @return EOK on success.
  * @return ENOENT if there is no such phone handle.
+ * @return ENOMEM if not enough memory to make the call
  *
  */
@@ -276,5 +277,10 @@
 		return ENOENT;
 
-	call_t *call = ipc_call_alloc(0);
+	call_t *call = ipc_call_alloc();
+	if (!call) {
+		kobject_put(kobj);
+		return ENOMEM;
+	}
+
 	call->priv = priv;
 	memcpy(call->data.args, data->args, sizeof(data->args));
@@ -373,5 +379,10 @@
 	}
 
-	call_t *call = ipc_call_alloc(0);
+	call_t *call = ipc_call_alloc();
+	if (!call) {
+		kobject_put(kobj);
+		return ENOMEM;
+	}
+
 	IPC_SET_IMETHOD(call->data, imethod);
 	IPC_SET_ARG1(call->data, arg1);
@@ -420,5 +431,10 @@
 	}
 
-	call_t *call = ipc_call_alloc(0);
+	call_t *call = ipc_call_alloc();
+	if (!call) {
+		kobject_put(kobj);
+		return ENOMEM;
+	}
+
 	errno_t rc = copy_from_uspace(&call->data.args, &data->args,
 	    sizeof(call->data.args));
Index: kernel/generic/src/lib/str.c
===================================================================
--- kernel/generic/src/lib/str.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/lib/str.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -635,6 +635,7 @@
 {
 	size_t size = str_size(src) + 1;
-	char *dest = nfmalloc(size);
-	assert(dest);
+	char *dest = malloc(size);
+	if (!dest)
+		return NULL;
 
 	str_cpy(dest, size, src);
@@ -668,6 +669,7 @@
 		size = n;
 
-	char *dest = nfmalloc(size + 1);
-	assert(dest);
+	char *dest = malloc(size + 1);
+	if (!dest)
+		return NULL;
 
 	str_ncpy(dest, size + 1, src, size);
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/main/kinit.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -120,10 +120,9 @@
 		thread = thread_create(kmp, NULL, TASK,
 		    THREAD_FLAG_UNCOUNTED, "kmp");
-		if (thread != NULL) {
-			thread_wire(thread, &cpus[0]);
-			thread_ready(thread);
-		} else
+		if (!thread)
 			panic("Unable to create kmp thread.");
 
+		thread_wire(thread, &cpus[0]);
+		thread_ready(thread);
 		thread_join(thread);
 		thread_detach(thread);
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/mm/as.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -151,5 +151,8 @@
 as_t *as_create(unsigned int flags)
 {
-	as_t *as = (as_t *) slab_alloc(as_cache, 0);
+	as_t *as = (as_t *) slab_alloc(as_cache, FRAME_ATOMIC);
+	if (!as)
+		return NULL;
+
 	(void) as_create_arch(as, 0);
 
@@ -2237,5 +2240,5 @@
  *
  */
-void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
+as_area_info_t *as_get_area_info(as_t *as, size_t *osize)
 {
 	mutex_lock(&as->lock);
@@ -2245,5 +2248,9 @@
 
 	size_t isize = area_cnt * sizeof(as_area_info_t);
-	as_area_info_t *info = nfmalloc(isize);
+	as_area_info_t *info = malloc(isize);
+	if (!info) {
+		mutex_unlock(&as->lock);
+		return NULL;
+	}
 
 	/* Record area data. */
@@ -2267,6 +2274,6 @@
 	mutex_unlock(&as->lock);
 
-	*obuf = info;
 	*osize = isize;
+	return info;
 }
 
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/mm/slab.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -667,5 +667,8 @@
     size_t (*destructor)(void *obj), unsigned int flags)
 {
-	slab_cache_t *cache = slab_alloc(&slab_cache_cache, 0);
+	slab_cache_t *cache = slab_alloc(&slab_cache_cache, FRAME_ATOMIC);
+	if (!cache)
+		panic("Not enough memory to allocate slab cache %s.", name);
+
 	_slab_cache_create(cache, name, size, align, constructor, destructor,
 	    flags);
@@ -730,4 +733,7 @@
 NO_TRACE static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
 {
+	if (!obj)
+		return;
+
 	ipl_t ipl = interrupts_disable();
 
@@ -954,5 +960,5 @@
 }
 
-static void *_malloc(size_t size, unsigned int flags)
+void *malloc(size_t size)
 {
 	assert(_slab_initialized);
@@ -964,21 +970,8 @@
 	uint8_t idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
 
-	return slab_alloc(malloc_caches[idx], flags);
-}
-
-void *malloc(size_t size)
-{
-	return _malloc(size, FRAME_ATOMIC);
-}
-
-/** Non-failing malloc.
- *  Never returns NULL, but may block forever if no memory is available.
- */
-void *nfmalloc(size_t size)
-{
-	return _malloc(size, 0);
-}
-
-static void *_realloc(void *ptr, size_t size, unsigned int flags)
+	return slab_alloc(malloc_caches[idx], FRAME_ATOMIC);
+}
+
+void *realloc(void *ptr, size_t size)
 {
 	assert(_slab_initialized);
@@ -992,5 +985,5 @@
 		uint8_t idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
 
-		new_ptr = slab_alloc(malloc_caches[idx], flags);
+		new_ptr = slab_alloc(malloc_caches[idx], FRAME_ATOMIC);
 	} else
 		new_ptr = NULL;
@@ -1007,9 +1000,4 @@
 }
 
-void *realloc(void *ptr, size_t size)
-{
-	return _realloc(ptr, size, FRAME_ATOMIC);
-}
-
 void free(void *ptr)
 {
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/proc/scheduler.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -134,5 +134,4 @@
 void scheduler_fpu_lazy_request(void)
 {
-restart:
 	fpu_enable();
 	irq_spinlock_lock(&CPU->lock, false);
@@ -153,15 +152,4 @@
 		fpu_context_restore(THREAD->saved_fpu_context);
 	} else {
-		/* Allocate FPU context */
-		if (!THREAD->saved_fpu_context) {
-			/* Might sleep */
-			irq_spinlock_unlock(&THREAD->lock, false);
-			irq_spinlock_unlock(&CPU->lock, false);
-			THREAD->saved_fpu_context =
-			    (fpu_context_t *) slab_alloc(fpu_context_cache, 0);
-
-			/* We may have switched CPUs during slab_alloc */
-			goto restart;
-		}
 		fpu_init();
 		THREAD->fpu_context_exists = true;
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/proc/task.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -199,8 +199,7 @@
 task_t *task_create(as_t *as, const char *name)
 {
-	task_t *task = (task_t *) slab_alloc(task_cache, 0);
-	if (task == NULL) {
+	task_t *task = (task_t *) slab_alloc(task_cache, FRAME_ATOMIC);
+	if (!task)
 		return NULL;
-	}
 
 	task_create_arch(task);
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/proc/thread.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -165,11 +165,8 @@
 
 #ifdef CONFIG_FPU
-#ifdef CONFIG_FPU_LAZY
-	thread->saved_fpu_context = NULL;
-#else /* CONFIG_FPU_LAZY */
-	thread->saved_fpu_context = slab_alloc(fpu_context_cache, kmflags);
+	thread->saved_fpu_context = slab_alloc(fpu_context_cache,
+	    FRAME_ATOMIC | kmflags);
 	if (!thread->saved_fpu_context)
 		return ENOMEM;
-#endif /* CONFIG_FPU_LAZY */
 #endif /* CONFIG_FPU */
 
@@ -200,6 +197,6 @@
 	if (!stack_phys) {
 #ifdef CONFIG_FPU
-		if (thread->saved_fpu_context)
-			slab_free(fpu_context_cache, thread->saved_fpu_context);
+		assert(thread->saved_fpu_context);
+		slab_free(fpu_context_cache, thread->saved_fpu_context);
 #endif
 		return ENOMEM;
@@ -226,6 +223,6 @@
 
 #ifdef CONFIG_FPU
-	if (thread->saved_fpu_context)
-		slab_free(fpu_context_cache, thread->saved_fpu_context);
+	assert(thread->saved_fpu_context);
+	slab_free(fpu_context_cache, thread->saved_fpu_context);
 #endif
 
@@ -342,7 +339,12 @@
     thread_flags_t flags, const char *name)
 {
-	thread_t *thread = (thread_t *) slab_alloc(thread_cache, 0);
+	thread_t *thread = (thread_t *) slab_alloc(thread_cache, FRAME_ATOMIC);
 	if (!thread)
 		return NULL;
+
+	if (thread_create_arch(thread, flags) != EOK) {
+		slab_free(thread_cache, thread);
+		return NULL;
+	}
 
 	/* Not needed, but good for debugging */
@@ -407,7 +409,4 @@
 	udebug_thread_initialize(&thread->udebug);
 #endif
-
-	/* Might depend on previous initialization */
-	thread_create_arch(thread);
 
 	if ((flags & THREAD_FLAG_NOATTACH) != THREAD_FLAG_NOATTACH)
@@ -654,4 +653,8 @@
 
 	return waitq_sleep_timeout(&thread->join_wq, usec, flags, NULL);
+
+	// FIXME: join should deallocate the thread.
+	//        Current code calls detach after join, that's contrary to how
+	//        join is used in other threading APIs.
 }
 
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -204,16 +204,25 @@
 
 		*psubtree =
-		    (sysinfo_item_t *) slab_alloc(sysinfo_item_cache, 0);
-		assert(*psubtree);
+		    (sysinfo_item_t *) slab_alloc(sysinfo_item_cache, FRAME_ATOMIC);
+		if (!*psubtree)
+			return NULL;
 
 		/* Fill in item name up to the delimiter */
 		(*psubtree)->name = str_ndup(name, i);
-		assert((*psubtree)->name);
+		if (!(*psubtree)->name) {
+			slab_free(sysinfo_item_cache, *psubtree);
+			return NULL;
+		}
 
 		/* Create subtree items */
 		if (name[i] == '.') {
 			(*psubtree)->subtree_type = SYSINFO_SUBTREE_TABLE;
-			return sysinfo_create_path(name + i + 1,
+			sysinfo_item_t *item = sysinfo_create_path(name + i + 1,
 			    &((*psubtree)->subtree.table));
+			if (!item) {
+				free((*psubtree)->name);
+				slab_free(sysinfo_item_cache, *psubtree);
+			}
+			return item;
 		}
 
@@ -271,6 +280,7 @@
 
 			sysinfo_item_t *item =
-			    (sysinfo_item_t *) slab_alloc(sysinfo_item_cache, 0);
-			assert(item);
+			    (sysinfo_item_t *) slab_alloc(sysinfo_item_cache, FRAME_ATOMIC);
+			if (!item)
+				return NULL;
 
 			cur->next = item;
@@ -278,11 +288,20 @@
 			/* Fill in item name up to the delimiter */
 			item->name = str_ndup(name, i);
-			assert(item->name);
+			if (!item->name) {
+				slab_free(sysinfo_item_cache, item);
+				return NULL;
+			}
 
 			/* Create subtree items */
 			if (name[i] == '.') {
 				item->subtree_type = SYSINFO_SUBTREE_TABLE;
-				return sysinfo_create_path(name + i + 1,
-				    &(item->subtree.table));
+				sysinfo_item_t *sub = sysinfo_create_path(
+				    name + i + 1, &(item->subtree.table));
+				if (!sub) {
+					free(item->name);
+					slab_free(sysinfo_item_cache, item);
+					return NULL;
+				}
+				return sub;
 			}
 
@@ -318,4 +337,6 @@
 		item->val_type = SYSINFO_VAL_VAL;
 		item->val.val = val;
+	} else {
+		printf("Could not set sysinfo item %s.\n", name);
 	}
 
@@ -350,4 +371,6 @@
 		item->val.data.data = data;
 		item->val.data.size = size;
+	} else {
+		printf("Could not set sysinfo item %s.\n", name);
 	}
 
@@ -378,4 +401,6 @@
 		item->val.gen_val.fn = fn;
 		item->val.gen_val.data = data;
+	} else {
+		printf("Could not set sysinfo item %s.\n", name);
 	}
 
@@ -411,4 +436,6 @@
 		item->val.gen_data.fn = fn;
 		item->val.gen_data.data = data;
+	} else {
+		printf("Could not set sysinfo item %s.\n", name);
 	}
 
@@ -434,4 +461,6 @@
 	if (item != NULL)
 		item->val_type = SYSINFO_VAL_UNDEFINED;
+	else
+		printf("Could not set sysinfo item %s.\n", name);
 
 	mutex_unlock(&sysinfo_lock);
@@ -466,4 +495,6 @@
 		item->subtree.generator.fn = fn;
 		item->subtree.generator.data = data;
+	} else {
+		printf("Could not set sysinfo item %s.\n", name);
 	}
 
@@ -654,6 +685,8 @@
 		return ret;
 
-	char *path = (char *) nfmalloc(size + 1);
-	assert(path);
+	// TODO: Change this so that allocation is not needed.
+	char *path = malloc(size + 1);
+	if (!path)
+		return ret;
 
 	if ((copy_from_uspace(path, ptr, size + 1) == 0) &&
@@ -763,6 +796,8 @@
 		return ret;
 
-	char *path = (char *) nfmalloc(size + 1);
-	assert(path);
+	// TODO: Change this so that allocation is not needed.
+	char *path = malloc(size + 1);
+	if (!path)
+		return ret;
 
 	if ((copy_from_uspace(path, ptr, size + 1) == 0) &&
Index: kernel/generic/src/udebug/udebug_ipc.c
===================================================================
--- kernel/generic/src/udebug/udebug_ipc.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/generic/src/udebug/udebug_ipc.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -266,5 +266,5 @@
 	size_t data_size;
 	size_t buf_size;
-	void *data;
+	as_area_info_t *data;
 
 	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
@@ -274,5 +274,10 @@
 	 * Read area list.
 	 */
-	as_get_area_info(AS, (as_area_info_t **) &data, &data_size);
+	data = as_get_area_info(AS, &data_size);
+	if (!data) {
+		IPC_SET_RETVAL(call->data, ENOMEM);
+		ipc_answer(&TASK->kb.box, call);
+		return;
+	}
 
 	/* Copy MAX(buf_size, data_size) bytes */
@@ -297,5 +302,5 @@
 
 	IPC_SET_ARG3(call->data, data_size);
-	call->buffer = data;
+	call->buffer = (uint8_t *) data;
 
 	ipc_answer(&TASK->kb.box, call);
Index: kernel/test/mm/slab1.c
===================================================================
--- kernel/test/mm/slab1.c	(revision 88e43bc385a97c7449a8a8bdd10a598a9497c134)
+++ kernel/test/mm/slab1.c	(revision 436a0a5d2cce1b5f7720cb379a4bd818e1599d4d)
@@ -50,6 +50,7 @@
 
 	for (i = 0; i < count; i++) {
-		data[i] = slab_alloc(cache, 0);
-		memsetb(data[i], size, 0);
+		data[i] = slab_alloc(cache, FRAME_ATOMIC);
+		if (data[i])
+			memsetb(data[i], size, 0);
 	}
 
@@ -66,6 +67,7 @@
 
 	for (i = 0; i < count; i++) {
-		data[i] = slab_alloc(cache, 0);
-		memsetb(data[i], size, 0);
+		data[i] = slab_alloc(cache, FRAME_ATOMIC);
+		if (data[i])
+			memsetb(data[i], size, 0);
 	}
 
@@ -82,6 +84,7 @@
 
 	for (i = count / 2; i < count; i++) {
-		data[i] = slab_alloc(cache, 0);
-		memsetb(data[i], size, 0);
+		data[i] = slab_alloc(cache, FRAME_ATOMIC);
+		if (data[i])
+			memsetb(data[i], size, 0);
 	}
 
@@ -131,9 +134,9 @@
 	for (j = 0; j < 10; j++) {
 		for (i = 0; i < THR_MEM_COUNT; i++)
-			thr_data[offs][i] = slab_alloc(thr_cache, 0);
+			thr_data[offs][i] = slab_alloc(thr_cache, FRAME_ATOMIC);
 		for (i = 0; i < THR_MEM_COUNT / 2; i++)
 			slab_free(thr_cache, thr_data[offs][i]);
 		for (i = 0; i < THR_MEM_COUNT / 2; i++)
-			thr_data[offs][i] = slab_alloc(thr_cache, 0);
+			thr_data[offs][i] = slab_alloc(thr_cache, FRAME_ATOMIC);
 		for (i = 0; i < THR_MEM_COUNT; i++)
 			slab_free(thr_cache, thr_data[offs][i]);
