Index: generic/src/ddi/ddi.c
===================================================================
--- generic/src/ddi/ddi.c	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/src/ddi/ddi.c	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -212,2 +212,21 @@
 	return (__native) ddi_iospace_enable((task_id_t) arg.task_id, (__address) arg.ioaddr, (size_t) arg.size);
 }
+
+/** Disable or enable preemption.
+ *
+ * @param enable If non-zero, the preemption counter will be decremented, leading to potential
+ * 		 enabling of preemption. Otherwise the preemption counter will be incremented,
+ *		 preventing preemption from occurring.
+ *
+ * @return Zero on success or EPERM if callers capabilities are not sufficient.
+ */ 
+__native sys_preempt_control(int enable)
+{
+        if (! cap_get(TASK) & CAP_PREEMPT_CONTROL)
+                return EPERM;
+        if (enable)
+                preemption_enable();
+        else
+                preemption_disable();
+        return 0;
+}
Index: generic/src/ipc/sysipc.c
===================================================================
--- generic/src/ipc/sysipc.c	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/src/ipc/sysipc.c	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -40,4 +40,5 @@
 #include <print.h>
 #include <syscall/copy.h>
+#include <security/cap.h>
 
 #define GET_CHECK_PHONE(phone,phoneid,err) { \
@@ -491,6 +492,9 @@
 __native sys_ipc_register_irq(__native irq, irq_code_t *ucode)
 {
+	if (!(cap_get(TASK) & CAP_IRQ_REG))
+		return EPERM;
+
 	if (irq >= IRQ_COUNT)
-		return -ELIMIT;
+		return (__native) ELIMIT;
 
 	irq_ipc_bind_arch(irq);
@@ -502,6 +506,9 @@
 __native sys_ipc_unregister_irq(__native irq)
 {
+	if (!(cap_get(TASK) & CAP_IRQ_REG))
+		return EPERM;
+
 	if (irq >= IRQ_COUNT)
-		return -ELIMIT;
+		return (__native) ELIMIT;
 
 	ipc_irq_unregister(&TASK->answerbox, irq);
Index: generic/src/main/kinit.c
===================================================================
--- generic/src/main/kinit.c	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/src/main/kinit.c	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -160,5 +160,5 @@
 			 * Set capabilities to init userspace tasks.
 			 */
-			cap_set(utask, CAP_CAP | CAP_MEM_MANAGER | CAP_IO_MANAGER);
+			cap_set(utask, CAP_CAP | CAP_MEM_MANAGER | CAP_IO_MANAGER | CAP_PREEMPT_CONTROL);
 			
 			if (!ipc_phone_0) 
Index: generic/src/mm/tlb.c
===================================================================
--- generic/src/mm/tlb.c	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/src/mm/tlb.c	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -30,4 +30,8 @@
  * @file	tlb.c
  * @brief	Generic TLB shootdown algorithm.
+ *
+ * The algorithm implemented here is based on the CMU TLB shootdown
+ * algorithm and is further simplified (e.g. all CPUs receive all TLB
+ * shootdown messages).
  */
 
Index: generic/src/security/cap.c
===================================================================
--- generic/src/security/cap.c	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/src/security/cap.c	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -37,6 +37,9 @@
 #include <proc/task.h>
 #include <synch/spinlock.h>
+#include <syscall/sysarg64.h>
+#include <syscall/copy.h>
 #include <arch.h>
 #include <typedefs.h>
+#include <errno.h>
 
 /** Set capabilities.
@@ -78,2 +81,88 @@
 	return caps;
 }
+
+/** Grant capabilities to a task.
+ *
+ * The calling task must have the CAP_CAP capability.
+ *
+ * @param uspace_taskid_arg Userspace structure holding destination task ID.
+ * @param caps Capabilities to grant.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ */
+__native sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps)
+{
+	sysarg64_t taskid_arg;
+	task_t *t;
+	ipl_t ipl;
+	int rc;
+	
+	if (!(cap_get(TASK) & CAP_CAP))
+		return (__native) EPERM;
+	
+	rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
+	if (rc != 0)
+		return (__native) rc;
+		
+	ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);
+	t = task_find_by_id((task_id_t) taskid_arg.value);
+	if (!t) {
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return (__native) ENOENT;
+	}
+	spinlock_unlock(&tasks_lock);
+	
+	cap_set(t, cap_get(t) | caps);
+	
+	interrupts_restore(ipl);	
+	return 0;
+}
+
+/** Revoke capabilities from a task.
+ *
+ * The calling task must have the CAP_CAP capability or the caller must
+ * attempt to revoke capabilities from itself.
+ *
+ * @param uspace_taskid_arg Userspace structure holding destination task ID.
+ * @param caps Capabilities to revoke.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ */
+__native sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps)
+{
+	sysarg64_t taskid_arg;
+	task_t *t;
+	ipl_t ipl;
+	int rc;
+	
+	rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
+	if (rc != 0)
+		return (__native) rc;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);	
+	t = task_find_by_id((task_id_t) taskid_arg.value);
+	if (!t) {
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return (__native) ENOENT;
+	}
+	spinlock_unlock(&tasks_lock);
+
+	/*
+	 * Revoking capabilities is different from granting them in that
+	 * a task can revoke capabilities from itself even if it
+	 * doesn't have CAP_CAP.
+	 */
+	if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) {
+		interrupts_restore(ipl);
+		return (__native) EPERM;
+	}
+
+	cap_set(t, cap_get(t) & ~caps);
+	
+	interrupts_restore(ipl);
+	return 0;
+}
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/src/syscall/syscall.c	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -44,4 +44,5 @@
 #include <synch/futex.h>
 #include <ddi/ddi.h>
+#include <security/cap.h>
 #include <syscall/copy.h>
 
@@ -56,15 +57,4 @@
 	
 	return count;
-}
-
-static __native sys_preempt_control(int enable)
-{
-	if (! cap_get(TASK) & CAP_PREEMPT_CONTROL)
-		return EPERM;
-	if (enable)
-		preemption_enable();
-	else
-		preemption_disable();
-	return 0;
 }
 
@@ -82,6 +72,5 @@
 	sys_io,
 	sys_tls_set,
-	sys_preempt_control,
-
+	
 	/* Thread and task related syscalls. */
 	sys_thread_create,
@@ -112,6 +101,11 @@
 	sys_ipc_unregister_irq,
 
+	/* Capabilities related syscalls. */
+	sys_cap_grant,
+	sys_cap_revoke,
+
 	/* DDI related syscalls. */
 	sys_physmem_map,
-	sys_iospace_enable
+	sys_iospace_enable,
+	sys_preempt_control
 };
