Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision fe754c80551c7034a638262c99569a02849dda22)
+++ kernel/generic/src/mm/frame.c	(revision 89bcb5201dfce10f22863fd9ae0e955003a7324c)
@@ -45,4 +45,5 @@
 #include <typedefs.h>
 #include <mm/frame.h>
+#include <mm/reserve.h>
 #include <mm/as.h>
 #include <panic.h>
@@ -472,13 +473,13 @@
  * @param frame_idx Frame index relative to zone.
  *
- */
-NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
+ * @return          Number of freed frames.
+ *
+ */
+NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t frame_idx)
 {
 	ASSERT(zone_flags_available(zone->flags));
 	
 	frame_t *frame = &zone->frames[frame_idx];
-	
-	/* Remember frame order */
-	uint8_t order = frame->buddy_order;
+	size_t size = 1 << frame->buddy_order;
 	
 	ASSERT(frame->refcount);
@@ -488,7 +489,9 @@
 		
 		/* Update zone information. */
-		zone->free_count += (1 << order);
-		zone->busy_count -= (1 << order);
-	}
+		zone->free_count += size;
+		zone->busy_count -= size;
+	}
+	
+	return size;
 }
 
@@ -645,5 +648,5 @@
 	for (i = 0; i < cframes; i++) {
 		zones.info[znum].busy_count++;
-		zone_frame_free(&zones.info[znum],
+		(void) zone_frame_free(&zones.info[znum],
 		    pfn - zones.info[znum].base + i);
 	}
@@ -683,5 +686,5 @@
 	/* Free unneeded frames */
 	for (i = count; i < (size_t) (1 << order); i++)
-		zone_frame_free(&zones.info[znum], i + frame_idx);
+		(void) zone_frame_free(&zones.info[znum], i + frame_idx);
 }
 
@@ -997,4 +1000,16 @@
 	size_t hint = pzone ? (*pzone) : 0;
 	
+	/*
+	 * If not told otherwise, we must first reserve the memory.
+	 */
+	if (!(flags & FRAME_NO_RESERVE)) {
+		if (flags & FRAME_ATOMIC) {
+			if (!reserve_try_alloc(size))
+				return NULL;
+		} else {
+			reserve_force_alloc(size);
+		}
+	}
+	
 loop:
 	irq_spinlock_lock(&zones.lock, true);
@@ -1031,4 +1046,6 @@
 		if (flags & FRAME_ATOMIC) {
 			irq_spinlock_unlock(&zones.lock, true);
+			if (!(flags & FRAME_NO_RESERVE))
+				reserve_free(size);
 			return NULL;
 		}
@@ -1108,4 +1125,6 @@
 void frame_free_generic(uintptr_t frame, frame_flags_t flags)
 {
+	size_t size;
+	
 	irq_spinlock_lock(&zones.lock, true);
 	
@@ -1115,8 +1134,9 @@
 	pfn_t pfn = ADDR2PFN(frame);
 	size_t znum = find_zone(pfn, 1, 0);
+
 	
 	ASSERT(znum != (size_t) -1);
 	
-	zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
+	size = zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
 	
 	irq_spinlock_unlock(&zones.lock, true);
@@ -1134,4 +1154,7 @@
 	}
 	mutex_unlock(&mem_avail_mtx);
+	
+	if (!(flags & FRAME_NO_RESERVE))
+		reserve_free(size);
 }
 
