Index: generic/include/ddi/ddi.h
===================================================================
--- generic/include/ddi/ddi.h	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/include/ddi/ddi.h	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -36,4 +36,5 @@
 extern __native sys_physmem_map(ddi_memarg_t *uspace_mem_arg);
 extern __native sys_iospace_enable(ddi_ioarg_t *uspace_io_arg);
+extern __native sys_preempt_control(int enable);
 
 /*
Index: generic/include/security/cap.h
===================================================================
--- generic/include/security/cap.h	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/include/security/cap.h	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -42,4 +42,5 @@
 #define __CAP_H__
 
+#include <syscall/sysarg64.h>
 #include <arch/types.h>
 #include <typedefs.h>
@@ -64,7 +65,12 @@
 
 /**
- * CAP_PREEMPT_CONTROL allows its holder to disable interrupts
+ * CAP_PREEMPT_CONTROL allows its holder to disable/enable preemption.
  */
-#define CAP_PREEMPT_CONTROL         (1<<3)
+#define CAP_PREEMPT_CONTROL	(1<<3)
+
+/**
+ * CAP_IRQ_REG entitles its holder to register IRQ handlers.
+ */
+#define CAP_IRQ_REG		(1<<4) 
 
 typedef __u32 cap_t;
@@ -73,3 +79,6 @@
 extern cap_t cap_get(task_t *t);
 
+extern __native sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps);
+extern __native sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps);
+
 #endif
Index: generic/include/syscall/sysarg64.h
===================================================================
--- generic/include/syscall/sysarg64.h	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
+++ generic/include/syscall/sysarg64.h	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file	sysarg64.h
+ * @brief	Wrapper for explicit 64-bit arguments passed to syscalls.
+ */
+
+#ifndef __SYSARG64_H__
+#define __SYSARG64_H__
+
+typedef struct {
+	unsigned long long value;
+} sysarg64_t;
+
+#endif
Index: generic/include/syscall/syscall.h
===================================================================
--- generic/include/syscall/syscall.h	(revision c6c59ccd6961621330425664fc6841acad7bd8f5)
+++ generic/include/syscall/syscall.h	(revision cfffb000c1b414a3b483fb3d1b0ef9d245d2fa89)
@@ -33,5 +33,4 @@
 	SYS_IO = 0,
 	SYS_TLS_SET = 1, /* Hardcoded in AMD64,IA32 uspace - psthread.S */
-	SYS_PREEMPT_CONTROL,
 	SYS_THREAD_CREATE,
 	SYS_THREAD_EXIT,
@@ -54,6 +53,9 @@
 	SYS_IPC_REGISTER_IRQ,
 	SYS_IPC_UNREGISTER_IRQ,
+	SYS_CAP_GRANT,
+	SYS_CAP_REVOKE,
 	SYS_MAP_PHYSMEM,
 	SYS_IOSPACE_ENABLE,
+	SYS_PREEMPT_CONTROL,
 	SYSCALL_END
 } syscall_t;
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
 };
