Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/Makefile	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -92,6 +92,6 @@
 endif
 
-ifeq ($(CONFIG_VIRT_IDX_CACHE),y)
-	DEFS += -DCONFIG_VIRT_IDX_CACHE
+ifeq ($(CONFIG_VIRT_IDX_DCACHE),y)
+	DEFS += -DCONFIG_VIRT_IDX_DCACHE
 endif
 
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/Makefile.inc	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -85,4 +85,5 @@
 	arch/$(ARCH)/src/mm/as.c \
 	arch/$(ARCH)/src/mm/cache.c \
+	arch/$(ARCH)/src/mm/cache_asm.S \
 	arch/$(ARCH)/src/mm/frame.c \
 	arch/$(ARCH)/src/mm/page.c \
Index: kernel/arch/sparc64/include/cpu.h
===================================================================
--- kernel/arch/sparc64/include/cpu.h	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/include/cpu.h	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -56,4 +56,5 @@
 	ver_reg_t ver;
 	uint32_t clock_frequency;	/**< Processor frequency in MHz. */
+	int dcache_active;		/**< When non-zero, the D-cache is not being shot down. */
 };
 	
Index: kernel/arch/sparc64/include/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/interrupt.h	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/include/interrupt.h	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -44,6 +44,11 @@
 #define IVT_FIRST	1
 
+/* This needs to be defined for inter-architecture API portability. */
 #define VECTOR_TLB_SHOOTDOWN_IPI	0
-#define IPI_TLB_SHOOTDOWN		VECTOR_TLB_SHOOTDOWN_IPI
+
+enum {
+	IPI_TLB_SHOOTDOWN = VECTOR_TLB_SHOOTDOWN_IPI,
+	IPI_DCACHE_SHOOTDOWN
+};		
 
 struct istate {
Index: kernel/arch/sparc64/include/mm/as.h
===================================================================
--- kernel/arch/sparc64/include/mm/as.h	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/include/mm/as.h	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -53,5 +53,5 @@
 	tsb_entry_t *itsb;
 	tsb_entry_t *dtsb;
-#endif
+#endif /* CONFIG_TSB */
 } as_arch_t;
 
Index: kernel/arch/sparc64/include/mm/cache.h
===================================================================
--- kernel/arch/sparc64/include/mm/cache.h	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/include/mm/cache.h	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -36,4 +36,14 @@
 #define KERN_sparc64_CACHE_H_
 
+#ifdef CONFIG_SMP
+extern void dcache_shootdown_start(void);
+extern void dcache_shootdown_finalize(void);
+extern void dcache_shootdown_ipi_recv(void);
+#else /* CONFIG_SMP */
+#define dcache_shootdown_start();
+#define dcache_shootdown_finalize();
+#define dcache_shootdown_ipi_recv();
+#endif /* CONFIG_SMP */
+
 extern void dcache_flush(void);
 
Index: kernel/arch/sparc64/src/cpu/cpu.c
===================================================================
--- kernel/arch/sparc64/src/cpu/cpu.c	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/src/cpu/cpu.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -93,4 +93,9 @@
 	}
 
+	/*
+	 * Set the D-cache active flag.
+	 * Needed for the D-cache to work.
+	 */
+	CPU->arch.dcache_active = 1;
 }
 
Index: kernel/arch/sparc64/src/mm/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/as.c	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/src/mm/as.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -48,5 +48,9 @@
 #include <bitops.h>
 #include <macros.h>
-#endif
+#endif /* CONFIG_TSB */
+
+#ifdef CONFIG_VIRT_IDX_DCACHE
+#include <arch/mm/cache.h>
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 
 /** Architecture dependent address space init. */
@@ -159,4 +163,21 @@
 	dtsb_base_write(tsb_base.value);
 #endif
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	if (as->dcache_flush_on_install) {
+		/*
+		 * Some mappings in this address space are illegal address
+		 * aliases. Upon their creation, the flush_dcache_on_install
+		 * flag was set.
+		 *
+		 * We are now obliged to flush the D-cache in order to guarantee
+		 * that there will be at most one cache line for each address
+		 * alias.
+		 *
+		 * This flush performs a cleanup after another address space in
+		 * which the alias might have existed.
+		 */
+		dcache_flush();
+	}
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 }
 
@@ -193,4 +214,24 @@
 	}
 #endif
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	if (as->dcache_flush_on_deinstall) {
+		/*
+		 * Some mappings in this address space are illegal address
+		 * aliases. Upon their creation, the flush_dcache_on_deinstall
+		 * flag was set.
+		 *
+		 * We are now obliged to flush the D-cache in order to guarantee
+		 * that there will be at most one cache line for each address
+		 * alias.
+		 *
+		 * This flush performs a cleanup after this address space. It is
+		 * necessary because other address spaces that contain the same
+		 * alias are not necessarily aware of the need to carry out the
+		 * cache flush. The only address spaces that are aware of it are
+		 * those that created the illegal alias. 
+		 */
+		dcache_flush();
+	}
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 }
 
Index: rnel/arch/sparc64/src/mm/cache.S
===================================================================
--- kernel/arch/sparc64/src/mm/cache.S	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (C) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <arch/arch.h>
-
-#define DCACHE_SIZE		(16*1024)
-#define DCACHE_LINE_SIZE	64
-
-.global dcache_flush
-dcache_flush:
-	set (DCACHE_SIZE - DCACHE_LINE_SIZE), %g1
-	stxa %g0, [%g1] ASI_DCACHE_TAG
-0:	membar #Sync
-	subcc %g1, DCACHE_LINE_SIZE, %g1
-	bnz,pt %xcc, 0b
-	stxa %g0, [%g1] ASI_DCACHE_TAG
-	retl
-	membar #Sync
-
Index: kernel/arch/sparc64/src/mm/cache.c
===================================================================
--- kernel/arch/sparc64/src/mm/cache.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
+++ kernel/arch/sparc64/src/mm/cache.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/**
+ * @file
+ * @brief	D-cache shootdown algorithm.
+ */
+
+#include <arch/mm/cache.h>
+
+#ifdef CONFIG_SMP
+
+#include <smp/ipi.h>
+#include <arch/interrupt.h>
+#include <synch/spinlock.h>
+#include <arch.h>
+#include <debug.h>
+
+/**
+ * This spinlock is used by the processors to synchronize during the D-cache
+ * shootdown.
+ */
+SPINLOCK_INITIALIZE(dcachelock);
+
+/** Initialize the D-cache shootdown sequence.
+ *
+ * Start the shootdown sequence by sending out an IPI and wait until all
+ * processors spin on the dcachelock spinlock.
+ */
+void dcache_shootdown_start(void)
+{
+	int i;
+
+	CPU->arch.dcache_active = 0;
+	spinlock_lock(&dcachelock);
+
+	ipi_broadcast(IPI_DCACHE_SHOOTDOWN);	
+
+busy_wait:
+	for (i = 0; i < config.cpu_count; i++)
+		if (cpus[i].arch.dcache_active)
+			goto busy_wait;
+}
+
+/** Finish the D-cache shootdown sequence. */
+void dcache_shootdown_finalize(void)
+{
+	spinlock_unlock(&dcachelock);
+	CPU->arch.dcache_active = 1;
+}
+
+/** Process the D-cache shootdown IPI. */
+void dcache_shootdown_ipi_recv(void)
+{
+	ASSERT(CPU);
+
+	CPU->arch.dcache_active = 0;
+	spinlock_lock(&dcachelock);
+	spinlock_unlock(&dcachelock);
+	
+	dcache_flush();
+
+	CPU->arch.dcache_active = 1;
+}
+
+#endif /* CONFIG_SMP */
+
+/** @}
+ */
+
Index: kernel/arch/sparc64/src/mm/cache_asm.S
===================================================================
--- kernel/arch/sparc64/src/mm/cache_asm.S	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
+++ kernel/arch/sparc64/src/mm/cache_asm.S	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch/arch.h>
+
+#define DCACHE_SIZE		(16*1024)
+#define DCACHE_LINE_SIZE	64
+
+.global dcache_flush
+dcache_flush:
+	set (DCACHE_SIZE - DCACHE_LINE_SIZE), %g1
+	stxa %g0, [%g1] ASI_DCACHE_TAG
+0:	membar #Sync
+	subcc %g1, DCACHE_LINE_SIZE, %g1
+	bnz,pt %xcc, 0b
+	stxa %g0, [%g1] ASI_DCACHE_TAG
+	retl
+	membar #Sync
+
Index: kernel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -112,7 +112,7 @@
 	data.l = locked;
 	data.cp = cacheable;
-#ifdef CONFIG_VIRT_IDX_CACHE
+#ifdef CONFIG_VIRT_IDX_DCACHE
 	data.cv = cacheable;
-#endif /* CONFIG_VIRT_IDX_CACHE */
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 	data.p = true;
 	data.w = true;
@@ -149,7 +149,7 @@
 	data.l = false;
 	data.cp = t->c;
-#ifdef CONFIG_VIRT_IDX_CACHE
+#ifdef CONFIG_VIRT_IDX_DCACHE
 	data.cv = t->c;
-#endif /* CONFIG_VIRT_IDX_CACHE */
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 	data.p = t->k;		/* p like privileged */
 	data.w = ro ? false : t->w;
@@ -185,7 +185,4 @@
 	data.l = false;
 	data.cp = t->c;
-#ifdef CONFIG_VIRT_IDX_CACHE
-	data.cv = t->c;
-#endif /* CONFIG_VIRT_IDX_CACHE */
 	data.p = t->k;		/* p like privileged */
 	data.w = false;
Index: kernel/arch/sparc64/src/mm/tsb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tsb.c	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/src/mm/tsb.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -101,7 +101,4 @@
 	tsb->data.pfn = t->frame >> FRAME_WIDTH;
 	tsb->data.cp = t->c;
-#ifdef CONFIG_VIRT_IDX_CACHE
-	tsb->data.cv = t->c;
-#endif /* CONFIG_VIRT_IDX_CACHE */
 	tsb->data.p = t->k;		/* p as privileged */
 	tsb->data.v = t->p;
@@ -143,7 +140,7 @@
 	tsb->data.pfn = t->frame >> FRAME_WIDTH;
 	tsb->data.cp = t->c;
-#ifdef CONFIG_VIRT_IDX_CACHE
+#ifdef CONFIG_VIRT_IDX_DCACHE
 	tsb->data.cv = t->c;
-#endif /* CONFIG_VIRT_IDX_CACHE */
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 	tsb->data.p = t->k;		/* p as privileged */
 	tsb->data.w = ro ? false : t->w;
Index: kernel/arch/sparc64/src/smp/ipi.c
===================================================================
--- kernel/arch/sparc64/src/smp/ipi.c	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/src/smp/ipi.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -39,4 +39,5 @@
 #include <config.h>
 #include <mm/tlb.h>
+#include <arch/mm/cache.h>
 #include <arch/interrupt.h>
 #include <arch/trap/interrupt.h>
@@ -121,4 +122,7 @@
 		func = tlb_shootdown_ipi_recv;
 		break;
+	case IPI_DCACHE_SHOOTDOWN:
+		func = dcache_shootdown_ipi_recv;
+		break;
 	default:
 		panic("Unknown IPI (%d).\n", ipi);
Index: kernel/arch/sparc64/src/start.S
===================================================================
--- kernel/arch/sparc64/src/start.S	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/src/start.S	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -123,9 +123,9 @@
 	membar #Sync
 
-#ifdef CONFIG_VIRT_IDX_CACHE
+#ifdef CONFIG_VIRT_IDX_DCACHE
 #define TTE_LOW_DATA(imm) 	(TTE_CP | TTE_CV | TTE_P | LMA | (imm))
-#else /* CONFIG_VIRT_IDX_CACHE */
+#else /* CONFIG_VIRT_IDX_DCACHE */
 #define TTE_LOW_DATA(imm) 	(TTE_CP | TTE_P | LMA | (imm))
-#endif /* CONFIG_VIRT_IDX_CACHE */
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 
 #define SET_TLB_DATA(r1, r2, imm) \
@@ -361,7 +361,7 @@
 .global kernel_8k_tlb_data_template
 kernel_8k_tlb_data_template:
-#ifdef CONFIG_VIRT_IDX_CACHE
+#ifdef CONFIG_VIRT_IDX_DCACHE
 	.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | TTE_CV | TTE_P | TTE_W)
-#else /* CONFIG_VIRT_IDX_CACHE */
+#else /* CONFIG_VIRT_IDX_DCACHE */
 	.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | TTE_P | TTE_W)
-#endif /* CONFIG_VIRT_IDX_CACHE */
+#endif /* CONFIG_VIRT_IDX_DCACHE */
Index: kernel/arch/sparc64/src/trap/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/interrupt.c	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/arch/sparc64/src/trap/interrupt.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -45,4 +45,5 @@
 #include <arch.h>
 #include <mm/tlb.h>
+#include <arch/mm/cache.h>
 #include <config.h>
 #include <synch/spinlock.h>
@@ -91,4 +92,6 @@
 		if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
 			tlb_shootdown_ipi_recv();
+		} else if (data0 == (uintptr_t) dcache_shootdown_ipi_recv) {
+			dcache_shootdown_ipi_recv();
 		}
 #endif
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/generic/include/mm/as.h	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -95,4 +95,9 @@
 	asid_t asid;
 	
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	bool dcache_flush_on_install;
+	bool dcache_flush_on_deinstall;
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+
 	/** Architecture specific content. */
 	as_arch_t arch;
@@ -161,4 +166,10 @@
 	/** Data to be used by the backend. */
 	mem_backend_data_t backend_data;
+
+	/** 
+	 * Virtual color of the original address space area that was at the beginning
+	 * of the share chain.
+	 */
+	int orig_color; 
 };
 
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/generic/src/mm/as.c	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -79,4 +79,8 @@
 #include <arch/interrupt.h>
 
+#ifdef CONFIG_VIRT_IDX_DCACHE
+#include <arch/mm/cache.h>
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+
 /**
  * Each architecture decides what functions will be used to carry out
@@ -162,4 +166,9 @@
 	as->cpu_refcount = 0;
 	as->page_table = page_table_create(flags);
+
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	as->dcache_flush_on_install = false;
+	as->dcache_flush_on_deinstall = false;
+#endif	/* CONFIG_VIRT_IDX_DCACHE */
 
 	return as;
@@ -269,4 +278,16 @@
 	else
 		memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0);
+
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	/*
+	 * When the area is being created with the AS_AREA_ATTR_PARTIAL flag, the
+	 * orig_color is probably wrong until the flag is reset. In other words, it is
+	 * initialized with the color of the area being created and not with the color
+	 * of the original address space area at the beginning of the share chain. Of
+	 * course, the correct color is set by as_area_share() before the flag is
+	 * reset.
+	 */
+	a->orig_color = PAGE_COLOR(base);
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 
 	btree_create(&a->used_space);
@@ -555,7 +576,5 @@
  * or ENOMEM if there was a problem in allocating destination address space
  * area. ENOTSUP is returned if the address space area backend does not support
- * sharing. It can be also returned if the architecture uses virtually indexed
- * caches and the source and destination areas start at pages with different
- * page colors.
+ * sharing.
  */
 int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
@@ -565,4 +584,5 @@
 	int src_flags;
 	size_t src_size;
+	int src_orig_color;
 	as_area_t *src_area, *dst_area;
 	share_info_t *sh_info;
@@ -582,9 +602,9 @@
 	}
 	
-#if 0	/* disable the check for now */
-#ifdef CONFIG_VIRT_IDX_CACHE
-	if (PAGE_COLOR(src_area->base) != PAGE_COLOR(dst_base)) {
-		/*
-		 * Refuse to create illegal address alias.
+
+	if (!src_area->backend || !src_area->backend->share) {
+		/*
+		 * There is no backend or the backend does not
+		 * know how to share the area.
 		 */
 		mutex_unlock(&src_area->lock);
@@ -593,17 +613,4 @@
 		return ENOTSUP;
 	}
-#endif /* CONFIG_VIRT_IDX_CACHE */
-#endif
-
-	if (!src_area->backend || !src_area->backend->share) {
-		/*
-		 * There is no backend or the backend does not
-		 * know how to share the area.
-		 */
-		mutex_unlock(&src_area->lock);
-		mutex_unlock(&src_as->lock);
-		interrupts_restore(ipl);
-		return ENOTSUP;
-	}
 	
 	src_size = src_area->pages * PAGE_SIZE;
@@ -611,4 +618,5 @@
 	src_backend = src_area->backend;
 	src_backend_data = src_area->backend_data;
+	src_orig_color = src_area->orig_color;
 
 	/* Share the cacheable flag from the original mapping */
@@ -665,5 +673,5 @@
 		return ENOMEM;
 	}
-	
+
 	/*
 	 * Now the destination address space area has been
@@ -671,9 +679,31 @@
 	 * attribute and set the sh_info.
 	 */	
+	mutex_lock(&dst_as->lock);	
 	mutex_lock(&dst_area->lock);
 	dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
 	dst_area->sh_info = sh_info;
+	dst_area->orig_color = src_orig_color;
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	if (src_orig_color != PAGE_COLOR(dst_base)) {
+		/*
+ 		 * We have just detected an attempt to create an invalid address
+ 		 * alias. We allow this and set a special flag that tells the
+ 		 * architecture specific code to flush the D-cache when the
+ 		 * offending address space is installed and deinstalled
+ 		 * (cleanup).
+ 		 *
+ 		 * In order for the flags to take effect immediately, we also
+ 		 * perform a global D-cache shootdown.
+ 		 */
+		dcache_shootdown_start();
+		dst_as->dcache_flush_on_install = true;
+		dst_as->dcache_flush_on_deinstall = true;
+		dcache_flush();
+		dcache_shootdown_finalize();
+	}
+#endif /* CONFIG_VIRT_IDX_DCACHE */
 	mutex_unlock(&dst_area->lock);
-	
+	mutex_unlock(&dst_as->lock);	
+
 	interrupts_restore(ipl);
 	
Index: kernel/kernel.config
===================================================================
--- kernel/kernel.config	(revision 3d769966455541f6a4296056f6156d2ad7eb2ef0)
+++ kernel/kernel.config	(revision 92778f2136ec900a873b76c69db8efbdb1998fea)
@@ -98,6 +98,6 @@
 ! [ARCH=sparc64] CONFIG_NS16550 (y/n)
 
-# Virtually indexed cache support
-! [ARCH=sparc64] CONFIG_VIRT_IDX_CACHE (n/y)
+# Virtually indexed D-cache support
+! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
 
 
