diff -urN 2.3.41/arch/alpha/kernel/alpha_ksyms.c smp-imb/arch/alpha/kernel/alpha_ksyms.c --- 2.3.41/arch/alpha/kernel/alpha_ksyms.c Fri Dec 17 18:17:06 1999 +++ smp-imb/arch/alpha/kernel/alpha_ksyms.c Wed Feb 2 13:43:09 2000 @@ -160,6 +160,7 @@ EXPORT_SYMBOL(flush_tlb_mm); EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(flush_tlb_range); +EXPORT_SYMBOL(smp_imb); EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(cpu_number_map); EXPORT_SYMBOL(global_bh_lock); diff -urN 2.3.41/arch/alpha/kernel/smp.c smp-imb/arch/alpha/kernel/smp.c --- 2.3.41/arch/alpha/kernel/smp.c Wed Dec 8 00:05:25 1999 +++ smp-imb/arch/alpha/kernel/smp.c Wed Feb 2 13:42:27 2000 @@ -868,6 +868,22 @@ } static void +ipi_imb(void) +{ + imb(); +} + +void +smp_imb(void) +{ + /* Must wait other processors to flush their icache before continue. */ + if (smp_call_function(ipi_imb, NULL, 1, 1)) + printk(KERN_CRIT "smp_imb: timed out\n"); + + imb(); +} + +static void ipi_flush_tlb_all(void *ignored) { tbia(); diff -urN 2.3.41/include/asm-alpha/pgalloc.h smp-imb/include/asm-alpha/pgalloc.h --- 2.3.41/include/asm-alpha/pgalloc.h Tue Jan 18 01:11:25 2000 +++ smp-imb/include/asm-alpha/pgalloc.h Wed Feb 2 13:42:27 2000 @@ -3,13 +3,27 @@ #include -/* Caches aren't brain-dead on the Alpha. */ -#define flush_cache_all() do { } while (0) +/* The icache is not coherent with the dcache on alpha, thus before + running self modified code we must always run an imb(). + Actually flush_cache_all() is real overkill as it's recalled from + vmalloc() before accessing pagetables and on the Alpha we are not required + to flush the icache before doing that, but the semantic of flush_cache_all() + requires us to flush _all_ the caches and so we must be correct here. It's + instead vmalloc that should be changed to use a more finegrined cache + flush operation (I suspect that also other archs doesn't need an icache + flush while handling pagetables). OTOH vmalloc is not a performance critical + path so after all we can live with it for now. */ +#define flush_cache_all() flush_icache_range(0, 0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(mm, start, end) do { } while (0) #define flush_cache_page(vma, vmaddr) do { } while (0) #define flush_page_to_ram(page) do { } while (0) -#define flush_icache_range(start, end) do { } while (0) +#ifndef __SMP__ +#define flush_icache_range(start, end) imb() +#else +#define flush_icache_range(start, end) smp_imb() +extern void smp_imb(void); +#endif /* * Use a few helper functions to hide the ugly broken ASN