Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 1066041e4e1803c9b6506af8a869b03669a25957)
+++ kernel/generic/src/mm/as.c	(revision 7cfe5c035807f24eb685752e38192c922b60c893)
@@ -665,10 +665,4 @@
 		
 		page_table_lock(as, false);
-		
-		/*
-		 * Start TLB shootdown sequence.
-		 */
-		ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
-		    area->base + P2SZ(pages), area->pages - pages);
 		
 		/*
@@ -726,4 +720,20 @@
 				}
 				
+				/*
+				 * Start TLB shootdown sequence.
+				 *
+				 * The sequence is rather short and can be
+				 * repeated multiple times. The reason is that
+				 * we don't want to have used_space_remove()
+				 * inside the sequence as it may use a blocking
+				 * memory allocation for its B+tree. Blocking
+				 * while holding the tlblock spinlock is
+				 * forbidden and would hit a kernel assertion.
+				 */
+
+				ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES,
+				    as->asid, area->base + P2SZ(pages),
+				    area->pages - pages);
+		
 				for (; i < size; i++) {
 					pte_t *pte = page_mapping_find(as,
@@ -743,22 +753,23 @@
 					page_mapping_remove(as, ptr + P2SZ(i));
 				}
+		
+				/*
+				 * Finish TLB shootdown sequence.
+				 */
+		
+				tlb_invalidate_pages(as->asid,
+				    area->base + P2SZ(pages),
+				    area->pages - pages);
+		
+				/*
+				 * Invalidate software translation caches
+				 * (e.g. TSB on sparc64, PHT on ppc32).
+				 */
+				as_invalidate_translation_cache(as,
+				    area->base + P2SZ(pages),
+				    area->pages - pages);
+				tlb_shootdown_finalize(ipl);
 			}
 		}
-		
-		/*
-		 * Finish TLB shootdown sequence.
-		 */
-		
-		tlb_invalidate_pages(as->asid, area->base + P2SZ(pages),
-		    area->pages - pages);
-		
-		/*
-		 * Invalidate software translation caches
-		 * (e.g. TSB on sparc64, PHT on ppc32).
-		 */
-		as_invalidate_translation_cache(as, area->base + P2SZ(pages),
-		    area->pages - pages);
-		tlb_shootdown_finalize(ipl);
-		
 		page_table_unlock(as, false);
 	} else {
Index: kernel/generic/src/mm/tlb.c
===================================================================
--- kernel/generic/src/mm/tlb.c	(revision 1066041e4e1803c9b6506af8a869b03669a25957)
+++ kernel/generic/src/mm/tlb.c	(revision 7cfe5c035807f24eb685752e38192c922b60c893)
@@ -162,5 +162,5 @@
 	
 	size_t i;
-	for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) {
+	for (i = 0; i < CPU->tlb_messages_count; i++) {
 		tlb_invalidate_type_t type = CPU->tlb_messages[i].type;
 		asid_t asid = CPU->tlb_messages[i].asid;
@@ -188,4 +188,5 @@
 	}
 	
+	CPU->tlb_messages_count = 0;
 	irq_spinlock_unlock(&CPU->lock, false);
 	CPU->tlb_active = true;
