Index: linux-2.6.9/include/asm-sparc64/pgtable.h
===================================================================
--- linux-2.6.9.orig/include/asm-sparc64/pgtable.h	2004-10-18 14:53:06.000000000 -0700
+++ linux-2.6.9/include/asm-sparc64/pgtable.h	2004-10-25 16:56:34.000000000 -0700
@@ -347,6 +347,7 @@
 
 struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+#define huge_update_mmu_cache update_mmu_cache
 
 /* Make a non-present pseudo-TTE. */
 static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
Index: linux-2.6.9/arch/sparc64/mm/init.c
===================================================================
--- linux-2.6.9.orig/arch/sparc64/mm/init.c	2004-10-18 14:53:50.000000000 -0700
+++ linux-2.6.9/arch/sparc64/mm/init.c	2004-10-25 17:32:43.000000000 -0700
@@ -192,6 +192,30 @@
 			     : "g5", "g7");
 }
 
+static int flush_dcache_pages(struct page *page) {
+	int nr;
+
+	if (!PageCompound(page))
+		return flush_dcache_page_impl(page);
+
+	page = page->private;
+	nr = 1 << page[1].index;
+	while (nr-- >0)
+		flush_dcache_impl(page++)
+}
+
+static int smp_flush_dcache_pages(struct page *page, int cpu) {
+	int nr;
+
+	if (!PageCompound(page))
+		return smp_flush_dcache_page_impl(page, cpu);
+
+	page = page->private;
+	nr = 1 << page[1].index;
+	while (nr-- >0)
+		smp_flush_dcache_impl(page++, cpu)
+}
+
 extern void __update_mmu_cache(unsigned long mmu_context_hw, unsigned long address, pte_t pte, int code);
 
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
@@ -211,17 +235,32 @@
 		 * in the SMP case.
 		 */
 		if (cpu == this_cpu)
-			flush_dcache_page_impl(page);
+			flush_dcache_pages(page);
 		else
-			smp_flush_dcache_page_impl(page, cpu);
+			smp_flush_dcache_pages(page, cpu);
 
 		clear_dcache_dirty_cpu(page, cpu);
 
 		put_cpu();
 	}
-	if (get_thread_fault_code())
-		__update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS,
+	if (get_thread_fault_code()) {
+
+		if (PageCompound(page)) {
+			int nr;
+
+			page = page->private;
+			nr = 1 << page[1].index;
+			address = page_address(page);
+			while (nr-- > 0) {
+				__update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS,
+				   address, pte, get_thread_fault_code());
+				address += PAGE_SIZE;
+			}
+		} else
+			__update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS,
 				   address, pte, get_thread_fault_code());
+
+	}
 }
 
 void flush_dcache_page(struct page *page)
@@ -235,9 +274,18 @@
 		if (dirty) {
 			if (dirty_cpu == this_cpu)
 				goto out;
-			smp_flush_dcache_page_impl(page, dirty_cpu);
+			smp_flush_dcache_pages(page, dirty_cpu);
 		}
-		set_dcache_dirty(page, this_cpu);
+
+		if (PageCompound(page)) {
+			int nr=1;
+
+			page = page->private;
+			nr = 1 << page[1].index;
+			while (nr-- >0)
+				set_dcache_dirty(page++, this_cpu);
+		} else
+			set_dcache_dirty(page++, this_cpu);
 	} else {
 		/* We could delay the flush for the !page_mapping
 		 * case too.  But that case is for exec env/arg