Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision 4638401d72971e059187a767fda13c9cf1a57ac1)
+++ kernel/generic/src/mm/backend_anon.c	(revision 454f1da77de2349b52f4bfe6ec9378202f3cdbda)
@@ -79,4 +79,5 @@
 {
 	uintptr_t frame;
+	bool dirty = false;
 
 	if (!as_area_check_access(area, access))
@@ -95,5 +96,5 @@
 		mutex_lock(&area->sh_info->lock);
 		frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
-			ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf);
+		    ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf);
 		if (!frame) {
 			bool allocate = true;
@@ -114,4 +115,5 @@
 				frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
 				memsetb(PA2KA(frame), FRAME_SIZE, 0);
+				dirty = true;
 				
 				/*
@@ -144,4 +146,5 @@
 		frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
 		memsetb(PA2KA(frame), FRAME_SIZE, 0);
+		dirty = true;
 	}
 	
@@ -155,4 +158,19 @@
 		panic("Could not insert used space.\n");
 		
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	if (dirty && PAGE_COLOR(PA2KA(frame)) != PAGE_COLOR(addr)) {
+		/*
+		 * By writing to the frame using kernel virtual address,
+		 * we have created an illegal virtual alias. We now have to
+		 * invalidate cachelines belonging to addr on all processors
+		 * so that they will be reloaded with the new content on next
+		 * read.
+		 */
+		dcache_flush_frame(addr, frame);
+		dcache_shootdown_start(DCACHE_INVL_FRAME, PAGE_COLOR(addr), frame);
+		dcache_shootdown_finalize();
+	}
+#endif
+
 	return AS_PF_OK;
 }
@@ -169,7 +187,4 @@
 {
 	frame_free(frame);
-#ifdef CONFIG_VIRT_IDX_DCACHE
-	dcache_flush_frame(page, frame);
-#endif
 }
 
@@ -218,5 +233,5 @@
 				frame_reference_add(pfn);
 			}
-				
+
 		}
 	}
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision 4638401d72971e059187a767fda13c9cf1a57ac1)
+++ kernel/generic/src/mm/backend_elf.c	(revision 454f1da77de2349b52f4bfe6ec9378202f3cdbda)
@@ -82,4 +82,5 @@
 	uintptr_t base, frame;
 	index_t i;
+	bool dirty = false;
 
 	if (!as_area_check_access(area, access))
@@ -148,5 +149,6 @@
 			memcpy((void *) PA2KA(frame),
 			    (void *) (base + i * FRAME_SIZE), FRAME_SIZE);
-			
+			dirty = true;
+
 			if (area->sh_info) {
 				frame_reference_add(ADDR2PFN(frame));
@@ -169,4 +171,5 @@
 		frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
 		memsetb(PA2KA(frame), FRAME_SIZE, 0);
+		dirty = true;
 
 		if (area->sh_info) {
@@ -189,4 +192,5 @@
 		memcpy((void *) PA2KA(frame), (void *) (base + i * FRAME_SIZE),
 		    size);
+		dirty = true;
 
 		if (area->sh_info) {
@@ -205,4 +209,19 @@
 	if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
 		panic("Could not insert used space.\n");
+
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	if (dirty && PAGE_COLOR(PA2KA(frame)) != PAGE_COLOR(addr)) {
+		/*
+		 * By writing to the frame using kernel virtual address,
+		 * we have created an illegal virtual alias. We now have to
+		 * invalidate cachelines belonging to addr on all processors
+		 * so that they will be reloaded with the new content on next
+		 * read.
+		 */
+		dcache_flush_frame(addr, frame);
+		dcache_shootdown_start(DCACHE_INVL_FRAME, PAGE_COLOR(addr), frame);
+		dcache_shootdown_finalize();
+	}
+#endif
 
 	return AS_PF_OK;
@@ -239,7 +258,4 @@
 			 */
 			frame_free(frame);
-#ifdef CONFIG_VIRT_IDX_DCACHE
-		        dcache_flush_frame(page, frame);
-#endif
 		}
 	} else {
@@ -248,9 +264,6 @@
 		 * lower part is backed by the ELF image and the upper is
 		 * anonymous). In any case, a frame needs to be freed.
-		 */
-		frame_free(frame); 
-#ifdef CONFIG_VIRT_IDX_DCACHE
-	        dcache_flush_frame(page, frame);
-#endif
+		 */ 
+		frame_free(frame);
 	}
 }
