Index: kernel/genarch/src/mm/asid.c
===================================================================
--- kernel/genarch/src/mm/asid.c	(revision a49a1a14068749b3ad852ac61bc415599e0339cb)
+++ kernel/genarch/src/mm/asid.c	(revision 402eda58922a8ad7839ce8ebb06d82d8f0e6710a)
@@ -126,7 +126,7 @@
 		 * Get the system rid of the stolen ASID.
 		 */
-		tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
 		tlb_invalidate_asid(asid);
-		tlb_shootdown_finalize();
+		tlb_shootdown_finalize(ipl);
 	} else {
 
@@ -142,7 +142,7 @@
 		 * Purge the allocated ASID from TLBs.
 		 */
-		tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
 		tlb_invalidate_asid(asid);
-		tlb_shootdown_finalize();
+		tlb_shootdown_finalize(ipl);
 	}
 	
Index: kernel/generic/include/mm/tlb.h
===================================================================
--- kernel/generic/include/mm/tlb.h	(revision a49a1a14068749b3ad852ac61bc415599e0339cb)
+++ kernel/generic/include/mm/tlb.h	(revision 402eda58922a8ad7839ce8ebb06d82d8f0e6710a)
@@ -68,11 +68,11 @@
 
 #ifdef CONFIG_SMP
-extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
-    uintptr_t page, size_t count);
-extern void tlb_shootdown_finalize(void);
+extern ipl_t tlb_shootdown_start(tlb_invalidate_type_t, asid_t, uintptr_t,
+    size_t);
+extern void tlb_shootdown_finalize(ipl_t);
 extern void tlb_shootdown_ipi_recv(void);
 #else
-#define tlb_shootdown_start(w, x, y, z)
-#define tlb_shootdown_finalize()
+#define tlb_shootdown_start(w, x, y, z)	(0)
+#define tlb_shootdown_finalize(i)	((i) = (i));
 #define tlb_shootdown_ipi_recv()
 #endif /* CONFIG_SMP */
@@ -84,6 +84,6 @@
 
 extern void tlb_invalidate_all(void);
-extern void tlb_invalidate_asid(asid_t asid);
-extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt);
+extern void tlb_invalidate_asid(asid_t);
+extern void tlb_invalidate_pages(asid_t, uintptr_t, size_t);
 #endif
 
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision a49a1a14068749b3ad852ac61bc415599e0339cb)
+++ kernel/generic/src/mm/as.c	(revision 402eda58922a8ad7839ce8ebb06d82d8f0e6710a)
@@ -433,6 +433,6 @@
 		 *
 		 */
-		tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
-		    pages * PAGE_SIZE, area->pages - pages);
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
+		    area->base + pages * PAGE_SIZE, area->pages - pages);
 		
 		/*
@@ -528,5 +528,5 @@
 		as_invalidate_translation_cache(as, area->base +
 		    pages * PAGE_SIZE, area->pages - pages);
-		tlb_shootdown_finalize();
+		tlb_shootdown_finalize(ipl);
 		
 		page_table_unlock(as, false);
@@ -578,5 +578,6 @@
 	 * Start TLB shootdown sequence.
 	 */
-	tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
+	ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
+	    area->pages);
 	
 	/*
@@ -625,5 +626,5 @@
 	 */
 	as_invalidate_translation_cache(as, area->base, area->pages);
-	tlb_shootdown_finalize();
+	tlb_shootdown_finalize(ipl);
 	
 	page_table_unlock(as, false);
@@ -865,5 +866,6 @@
 	 *
 	 */
-	tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
+	ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
+	    area->pages);
 	
 	/*
@@ -912,5 +914,5 @@
 	 */
 	as_invalidate_translation_cache(as, area->base, area->pages);
-	tlb_shootdown_finalize();
+	tlb_shootdown_finalize(ipl);
 	
 	page_table_unlock(as, false);
Index: kernel/generic/src/mm/tlb.c
===================================================================
--- kernel/generic/src/mm/tlb.c	(revision a49a1a14068749b3ad852ac61bc415599e0339cb)
+++ kernel/generic/src/mm/tlb.c	(revision 402eda58922a8ad7839ce8ebb06d82d8f0e6710a)
@@ -73,15 +73,19 @@
  * to all other processors.
  *
- * @param type Type describing scope of shootdown.
- * @param asid Address space, if required by type.
- * @param page Virtual page address, if required by type.
- * @param count Number of pages, if required by type.
+ * @param type		Type describing scope of shootdown.
+ * @param asid		Address space, if required by type.
+ * @param page		Virtual page address, if required by type.
+ * @param count		Number of pages, if required by type.
  *
+ * @return The interrupt priority level as it existed prior to this call.
  */
-void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
+ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
     uintptr_t page, size_t count)
 {
+	ipl_t ipl;
+
+	ipl = interrupts_disable();
 	CPU->tlb_active = false;
-	irq_spinlock_lock(&tlblock, true);
+	irq_spinlock_lock(&tlblock, false);
 	
 	size_t i;
@@ -123,13 +127,17 @@
 		if (cpus[i].tlb_active)
 			goto busy_wait;
+
+	return ipl;
 }
 
 /** Finish TLB shootdown sequence.
  *
+ * @param ipl		Previous interrupt priority level.
  */
-void tlb_shootdown_finalize(void)
+void tlb_shootdown_finalize(ipl_t ipl)
 {
-	irq_spinlock_unlock(&tlblock, true);
+	irq_spinlock_unlock(&tlblock, false);
 	CPU->tlb_active = true;
+	interrupts_restore(ipl);
 }
 
