Index: kernel/arch/arm32/src/mach/gta02/gta02.c
===================================================================
--- kernel/arch/arm32/src/mach/gta02/gta02.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/arch/arm32/src/mach/gta02/gta02.c	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -174,4 +174,5 @@
 		fb_parea.pbase = GTA02_FB_BASE;
 		fb_parea.frames = 150;
+		fb_parea.unpriv = false;
 		ddi_parea_register(&fb_parea);
 	}
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -300,4 +300,5 @@
 		fb_parea.pbase = ICP_FB;
 		fb_parea.frames = 300;
+		fb_parea.unpriv = false;
 		ddi_parea_register(&fb_parea);
 	}
Index: kernel/arch/sparc64/src/drivers/niagara.c
===================================================================
--- kernel/arch/sparc64/src/drivers/niagara.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/arch/sparc64/src/drivers/niagara.c	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -216,4 +216,5 @@
 	outbuf_parea.pbase = (uintptr_t) (KA2PA(&output_buffer));
 	outbuf_parea.frames = 1;
+	outbuf_parea.unpriv = false;
 	ddi_parea_register(&outbuf_parea);
 
@@ -221,4 +222,5 @@
 	inbuf_parea.pbase = (uintptr_t) (KA2PA(&input_buffer));
 	inbuf_parea.frames = 1;
+	inbuf_parea.unpriv = false;
 	ddi_parea_register(&inbuf_parea);
 
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/include/ddi/ddi.h	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -43,8 +43,9 @@
 /** Structure representing contiguous physical memory area. */
 typedef struct {
-	uintptr_t pbase;    /**< Physical base of the area. */
-	pfn_t frames;       /**< Number of frames in the area. */
+	link_t link;      /**< Linked list link */
 	
-	link_t link;        /**< Linked list link */
+	uintptr_t pbase;  /**< Physical base of the area. */
+	pfn_t frames;     /**< Number of frames in the area. */
+	bool unpriv;      /**< Allow mapping by unprivileged tasks. */
 } parea_t;
 
@@ -60,5 +61,4 @@
 extern int ddi_iospace_enable_arch(task_t *, uintptr_t, size_t);
 
-
 #endif
 
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/console/console.c	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -160,4 +160,5 @@
 	klog_parea.pbase = (uintptr_t) faddr;
 	klog_parea.frames = SIZE2FRAMES(sizeof(klog));
+	klog_parea.unpriv = false;
 	ddi_parea_register(&klog_parea);
 	
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/ddi/ddi.c	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -104,13 +104,17 @@
 {
 	ASSERT(TASK);
-	ASSERT((pf % FRAME_SIZE) == 0);
-	ASSERT((vp % PAGE_SIZE) == 0);
-	
-	/*
-	 * Make sure the caller is authorised to make this syscall.
-	 */
-	cap_t caps = cap_get(TASK);
-	if (!(caps & CAP_MEM_MANAGER))
-		return EPERM;
+	
+	if ((pf % FRAME_SIZE) != 0)
+		return EBADMEM;
+	
+	if ((vp % PAGE_SIZE) != 0)
+		return EBADMEM;
+	
+	/*
+	 * Unprivileged tasks are only allowed to map pareas
+	 * which are explicitly marked as such.
+	 */
+	bool priv =
+	    ((cap_get(TASK) & CAP_MEM_MANAGER) == CAP_MEM_MANAGER);
 	
 	mem_backend_data_t backend_data;
@@ -123,14 +127,27 @@
 	
 	if (znum == (size_t) -1) {
-		/* Frames not found in any zones
-		 * -> assume it is hardware device and allow mapping
+		/*
+		 * Frames not found in any zone
+		 * -> assume it is a hardware device and allow mapping
+		 *    for privileged tasks.
 		 */
 		irq_spinlock_unlock(&zones.lock, true);
+		
+		if (!priv)
+			return EPERM;
+		
 		goto map;
 	}
 	
 	if (zones.info[znum].flags & ZONE_FIRMWARE) {
-		/* Frames are part of firmware */
+		/*
+		 * Frames are part of firmware
+		 * -> allow mapping for privileged tasks.
+		 */
 		irq_spinlock_unlock(&zones.lock, true);
+		
+		if (!priv)
+			return EPERM;
+		
 		goto map;
 	}
@@ -138,6 +155,6 @@
 	if (zone_flags_available(zones.info[znum].flags)) {
 		/*
-		 * Frames are part of physical memory, check if the memory
-		 * region is enabled for mapping.
+		 * Frames are part of physical memory, check
+		 * if the memory region is enabled for mapping.
 		 */
 		irq_spinlock_unlock(&zones.lock, true);
@@ -150,5 +167,12 @@
 		if ((!parea) || (parea->frames < pages)) {
 			mutex_unlock(&parea_lock);
-			goto err;
+			return ENOENT;
+		}
+		
+		if (!priv) {
+			if (!parea->unpriv) {
+				mutex_unlock(&parea_lock);
+				return EPERM;
+			}
 		}
 		
@@ -158,6 +182,4 @@
 	
 	irq_spinlock_unlock(&zones.lock, true);
-	
-err:
 	return ENOENT;
 	
Index: kernel/generic/src/lib/rd.c
===================================================================
--- kernel/generic/src/lib/rd.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/lib/rd.c	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -90,4 +90,5 @@
 	    FRAME_SIZE);
 	rd_parea.frames = SIZE2FRAMES(dsize);
+	rd_parea.unpriv = false;
 	ddi_parea_register(&rd_parea);
 
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/time/clock.c	(revision fc5f7a8b7a00dd98ac6bacb49dbdfc61d2b775ae)
@@ -93,4 +93,5 @@
 	clock_parea.pbase = (uintptr_t) faddr;
 	clock_parea.frames = 1;
+	clock_parea.unpriv = true;
 	ddi_parea_register(&clock_parea);
 	
@@ -100,5 +101,4 @@
 	 *
 	 */
-	sysinfo_set_item_val("clock.cacheable", NULL, (sysarg_t) true);
 	sysinfo_set_item_val("clock.faddr", NULL, (sysarg_t) faddr);
 }
