Index: kernel/arch/ia64/src/mm/as.c
===================================================================
--- kernel/arch/ia64/src/mm/as.c	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/arch/ia64/src/mm/as.c	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -37,9 +37,8 @@
 #include <arch/mm/page.h>
 #include <genarch/mm/as_ht.h>
+#include <genarch/mm/page_ht.h>
 #include <genarch/mm/asid_fifo.h>
 #include <mm/asid.h>
-#include <arch.h>
 #include <arch/barrier.h>
-#include <synch/spinlock.h>
 
 /** Architecture dependent address space init. */
@@ -56,10 +55,6 @@
 void as_install_arch(as_t *as)
 {
-	ipl_t ipl;
 	region_register rr;
 	int i;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&as->lock);
 	
 	ASSERT(as->asid != ASID_INVALID);
@@ -81,7 +76,4 @@
 	srlz_d();
 	srlz_i();
-	
-	spinlock_unlock(&as->lock);
-	interrupts_restore(ipl);
 }
 
Index: kernel/arch/mips32/src/mm/as.c
===================================================================
--- kernel/arch/mips32/src/mm/as.c	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/arch/mips32/src/mm/as.c	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -35,4 +35,5 @@
 #include <arch/mm/as.h>
 #include <genarch/mm/as_pt.h>
+#include <genarch/mm/page_pt.h>
 #include <genarch/mm/asid_fifo.h>
 #include <arch/mm/tlb.h>
@@ -40,5 +41,4 @@
 #include <mm/as.h>
 #include <arch/cp0.h>
-#include <arch.h>
 
 /** Architecture dependent address space init. */
@@ -58,5 +58,4 @@
 {
 	entry_hi_t hi;
-	ipl_t ipl;
 
 	/*
@@ -65,10 +64,6 @@
 	hi.value = cp0_entry_hi_read();
 
-	ipl = interrupts_disable();
-	spinlock_lock(&as->lock);
 	hi.asid = as->asid;
 	cp0_entry_hi_write(hi.value);	
-	spinlock_unlock(&as->lock);
-	interrupts_restore(ipl);
 }
 
Index: kernel/arch/ppc32/src/mm/as.c
===================================================================
--- kernel/arch/ppc32/src/mm/as.c	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/arch/ppc32/src/mm/as.c	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -55,10 +55,6 @@
 {
 	asid_t asid;
-	ipl_t ipl;
 	uint32_t sr;
 
-	ipl = interrupts_disable();
-	spinlock_lock(&as->lock);
-	
 	asid = as->asid;
 	
@@ -80,7 +76,4 @@
 		);
 	}
-	
-	spinlock_unlock(&as->lock);
-	interrupts_restore(ipl);
 }
 
Index: kernel/arch/ppc64/src/mm/as.c
===================================================================
--- kernel/arch/ppc64/src/mm/as.c	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/arch/ppc64/src/mm/as.c	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup ppc64mm
+/** @addtogroup ppc64mm
   * @{
  */
@@ -42,5 +42,5 @@
 }
 
- /** @}
+/** @}
  */
 
Index: kernel/arch/sparc64/src/mm/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/as.c	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/arch/sparc64/src/mm/as.c	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -43,5 +43,4 @@
 #include <arch/mm/tsb.h>
 #include <arch/memstr.h>
-#include <synch/mutex.h>
 #include <arch/asm.h>
 #include <mm/frame.h>
@@ -101,11 +100,5 @@
 {
 #ifdef CONFIG_TSB
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	mutex_lock_active(&as->lock);	/* completely unnecessary, but polite */
 	tsb_invalidate(as, 0, (count_t) -1);
-	mutex_unlock(&as->lock);
-	interrupts_restore(ipl);
 #endif
 	return 0;
@@ -124,16 +117,15 @@
 	
 	/*
-	 * Note that we don't lock the address space.
-	 * That's correct - we can afford it here
-	 * because we only read members that are
-	 * currently read-only.
+	 * Note that we don't and may not lock the address space. That's ok
+	 * since we only read members that are currently read-only.
+	 *
+	 * Moreover, the as->asid is protected by asidlock, which is being held.
 	 */
 	
 	/*
-	 * Write ASID to secondary context register.
-	 * The primary context register has to be set
-	 * from TL>0 so it will be filled from the
-	 * secondary context register from the TL=1
-	 * code just before switch to userspace.
+	 * Write ASID to secondary context register. The primary context
+	 * register has to be set from TL>0 so it will be filled from the
+	 * secondary context register from the TL=1 code just before switch to
+	 * userspace.
 	 */
 	ctx.v = 0;
@@ -185,8 +177,8 @@
 
 	/*
-	 * Note that we don't lock the address space.
-	 * That's correct - we can afford it here
-	 * because we only read members that are
-	 * currently read-only.
+	 * Note that we don't and may not lock the address space. That's ok
+	 * since we only read members that are currently read-only.
+	 *
+	 * Moreover, the as->asid is protected by asidlock, which is being held.
 	 */
 
Index: kernel/genarch/src/mm/asid.c
===================================================================
--- kernel/genarch/src/mm/asid.c	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/genarch/src/mm/asid.c	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -63,12 +63,6 @@
 #include <synch/spinlock.h>
 #include <synch/mutex.h>
-#include <arch.h>
 #include <adt/list.h>
 #include <debug.h>
-
-/**
- * asidlock protects the asids_allocated counter.
- */
-SPINLOCK_INITIALIZE(asidlock);
 
 static count_t asids_allocated = 0;
@@ -91,5 +85,4 @@
 	 */
 	
-	spinlock_lock(&asidlock);
 	if (asids_allocated == ASIDS_ALLOCABLE) {
 
@@ -109,5 +102,4 @@
 		
 		as = list_get_instance(tmp, as_t, inactive_as_with_asid_link);
-		mutex_lock_active(&as->lock);
 
 		/*
@@ -131,6 +123,4 @@
 		as_invalidate_translation_cache(as, 0, (count_t) -1);
 		
-		mutex_unlock(&as->lock);
-
 		/*
 		 * Get the system rid of the stolen ASID.
@@ -157,6 +147,4 @@
 	}
 	
-	spinlock_unlock(&asidlock);
-	
 	return asid;
 }
@@ -171,14 +159,6 @@
 void asid_put(asid_t asid)
 {
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&asidlock);
-
 	asids_allocated--;
 	asid_put_arch(asid);
-	
-	spinlock_unlock(&asidlock);
-	interrupts_restore(ipl);
 }
 
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/generic/include/mm/as.h	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -90,4 +90,15 @@
 		/** Protected by asidlock. */
 		link_t inactive_as_with_asid_link;
+		/**
+		 * Number of processors on wich is this address space active.
+		 * Protected by asidlock.
+		 */
+		count_t cpu_refcount;
+		/**
+		 * Address space identifier.
+		 * Constant on architectures that do not support ASIDs.
+		 * Protected by asidlock.  
+		 */
+		asid_t asid;
 		
 		mutex_t lock;
@@ -96,15 +107,6 @@
 		count_t refcount;
 		
-		/** Number of processors on wich is this address space active. */
-		count_t cpu_refcount;
-		
 		/** B+tree of address space areas. */
 		btree_t as_area_btree;
-		
-		/**
-		 *  Address space identifier.
-		 *  Constant on architectures that do not support ASIDs.
-		 */
-		asid_t asid;
 		
 		/** Non-generic content. */
@@ -134,4 +136,15 @@
 	/** Protected by asidlock. */
 	link_t inactive_as_with_asid_link;
+	/**
+	 * Number of processors on wich is this address space active.
+	 * Protected by asidlock.
+	 */
+	count_t cpu_refcount;
+	/**
+	 * Address space identifier.
+	 * Constant on architectures that do not support ASIDs.
+	 * Protected by asidlock.
+	 */
+	asid_t asid;
 
 	mutex_t lock;
@@ -140,15 +153,6 @@
 	count_t refcount;
 
-	/** Number of processors on wich is this address space active. */
-	count_t cpu_refcount;
-
 	/** B+tree of address space areas. */
 	btree_t as_area_btree;
-	
-	/**
-	 *  Address space identifier.
-	 *  Constant on architectures that do not support ASIDs.
-	 */
-	asid_t asid;
 	
 	/** Non-generic content. */
@@ -250,5 +254,4 @@
 #endif
 
-SPINLOCK_EXTERN(inactive_as_with_asid_lock);
 extern link_t inactive_as_with_asid_head;
 
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 563c2ddc4c2e228951de3522875152bb1cf8dc51)
+++ kernel/generic/src/mm/as.c	(revision 879585a3fd47daccb6ab751ad240297f65de5bae)
@@ -96,8 +96,11 @@
 
 /**
- * This lock protects inactive_as_with_asid_head list. It must be acquired
- * before as_t mutex.
- */
-SPINLOCK_INITIALIZE(inactive_as_with_asid_lock);
+ * This lock serializes access to the ASID subsystem.
+ * It protects:
+ * - inactive_as_with_asid_head list
+ * - as->asid for each as of the as_t type
+ * - asids_allocated counter
+ */
+SPINLOCK_INITIALIZE(asidlock);
 
 /**
@@ -206,6 +209,7 @@
 	 * it is safe not to lock its mutex.
 	 */
+
 	ipl = interrupts_disable();
-	spinlock_lock(&inactive_as_with_asid_lock);
+	spinlock_lock(&asidlock);
 	if (as->asid != ASID_INVALID && as != AS_KERNEL) {
 		if (as != AS && as->cpu_refcount == 0)
@@ -213,5 +217,5 @@
 		asid_put(as->asid);
 	}
-	spinlock_unlock(&inactive_as_with_asid_lock);
+	spinlock_unlock(&asidlock);
 
 	/*
@@ -861,5 +865,6 @@
  *
  * Note that this function cannot sleep as it is essentially a part of
- * scheduling. Sleeping here would lead to deadlock on wakeup.
+ * scheduling. Sleeping here would lead to deadlock on wakeup. Another
+ * thing which is forbidden in this context is locking the address space.
  *
  * @param old Old address space or NULL.
@@ -868,9 +873,5 @@
 void as_switch(as_t *old_as, as_t *new_as)
 {
-	ipl_t ipl;
-	bool needs_asid = false;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&inactive_as_with_asid_lock);
+	spinlock_lock(&asidlock);
 
 	/*
@@ -878,5 +879,4 @@
 	 */	
 	if (old_as) {
-		mutex_lock_active(&old_as->lock);
 		ASSERT(old_as->cpu_refcount);
 		if((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
@@ -891,5 +891,4 @@
 			    &inactive_as_with_asid_head);
 		}
-		mutex_unlock(&old_as->lock);
 
 		/*
@@ -903,34 +902,13 @@
 	 * Second, prepare the new address space.
 	 */
-	mutex_lock_active(&new_as->lock);
 	if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) {
-		if (new_as->asid != ASID_INVALID) {
+		if (new_as->asid != ASID_INVALID)
 			list_remove(&new_as->inactive_as_with_asid_link);
-		} else {
-			/*
-			 * Defer call to asid_get() until new_as->lock is released.
-			 */
-			needs_asid = true;
-		}
+		else
+			new_as->asid = asid_get();
 	}
 #ifdef AS_PAGE_TABLE
 	SET_PTL0_ADDRESS(new_as->genarch.page_table);
 #endif
-	mutex_unlock(&new_as->lock);
-
-	if (needs_asid) {
-		/*
-		 * Allocation of new ASID was deferred
-		 * until now in order to avoid deadlock.
-		 */
-		asid_t asid;
-		
-		asid = asid_get();
-		mutex_lock_active(&new_as->lock);
-		new_as->asid = asid;
-		mutex_unlock(&new_as->lock);
-	}
-	spinlock_unlock(&inactive_as_with_asid_lock);
-	interrupts_restore(ipl);
 	
 	/*
@@ -939,4 +917,6 @@
 	 */
 	as_install_arch(new_as);
+
+	spinlock_unlock(&asidlock);
 	
 	AS = new_as;
