From ad984aeba298388c4311fdb649b940bd8d3f5062 Mon Sep 17 00:00:00 2001 From: hawk Date: Fri, 3 Mar 2006 17:15:39 +0000 Subject: [PATCH] - patch for bug in kernel >= 2.6.11 implementation of the global_flush_tlb() kernel interface that can lead to severe stability problems in combination with the NVIDIA Linux/x86-64 graphics driver and/or other drivers relying on the change_page_attr()/global_flush_tlb() kernel interfaces Changed files: NVIDIA_kernel-1.0-7174-1386866.diff -> 1.1 --- NVIDIA_kernel-1.0-7174-1386866.diff | 72 +++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 NVIDIA_kernel-1.0-7174-1386866.diff diff --git a/NVIDIA_kernel-1.0-7174-1386866.diff b/NVIDIA_kernel-1.0-7174-1386866.diff new file mode 100644 index 0000000..0a6263f --- /dev/null +++ b/NVIDIA_kernel-1.0-7174-1386866.diff @@ -0,0 +1,72 @@ +diff -ru usr/src/nv/nv-vm.c usr/src/nv.1386866/nv-vm.c +--- usr/src/nv/nv-vm.c 2005-03-22 16:19:09.000000000 +0100 ++++ usr/src/nv.1386866/nv-vm.c 2005-10-11 19:33:24.821108608 +0200 +@@ -58,26 +58,57 @@ + * conflicts. we try to rely on the kernel's provided interfaces when possible, + * but need additional flushing on earlier kernels. + */ +-#if defined(KERNEL_2_4) +-/* wrap CACHE_FLUSH so we can pass it to smp_call_function */ +-static void cache_flush(void *p) +-{ +- CACHE_FLUSH(); +-} +-#endif +- + /* + * 2.4 kernels handle flushing in the change_page_attr() call, but kernels + * earlier than 2.4.27 don't flush on cpus that support Self Snoop, so we + * manually flush on these kernels (actually, we go ahead and flush on all + * 2.4 kernels, as it's possible some others may be missing this fix and + * we'd prefer to be a little slower flushing caches than hanging the +- * system. 2.6 kernels split the flushing out to a seperate call, +- * global_flush_tlb(), so we rely on that. ++ * system. ++ * 2.6 kernels split the flushing out to a seperate call, ++ * global_flush_tlb(), so we rely on that. however, there are some 2.6 ++ * x86_64 kernels that do not properly flush. for now, we'll flush on all ++ * potential kernels, as it's slightly slower, but safer. + */ ++#if defined(KERNEL_2_4) || (defined(KERNEL_2_6) && defined(NVCPU_X86_64)) ++#define NV_CPA_NEEDS_FLUSHING 1 ++#endif ++ ++#if defined(NV_CPA_NEEDS_FLUSHING) ++static void cache_flush(void *p) ++{ ++ unsigned long reg0, reg1; ++ ++ CACHE_FLUSH(); ++ ++ // flush global TLBs ++#if defined (NVCPU_X86) ++ asm volatile("movl %%cr4, %0; \n" ++ "andl $~0x80, %0; \n" ++ "movl %0, %%cr4; \n" ++ "movl %%cr3, %1; \n" ++ "movl %1, %%cr3; \n" ++ "orl $0x80, %0; \n" ++ "movl %0, %%cr4; \n" ++ : "=&r" (reg0), "=&r" (reg1) ++ : : "memory"); ++#else ++ asm volatile("movq %%cr4, %0; \n" ++ "andq $~0x80, %0; \n" ++ "movq %0, %%cr4; \n" ++ "movq %%cr3, %1; \n" ++ "movq %1, %%cr3; \n" ++ "orq $0x80, %0; \n" ++ "movq %0, %%cr4; \n" ++ : "=&r" (reg0), "=&r" (reg1) ++ : : "memory"); ++#endif ++} ++#endif ++ + static void nv_flush_caches(void) + { +-#if defined(KERNEL_2_4) ++#if defined(NV_CPA_NEEDS_FLUSHING) + #ifdef CONFIG_SMP + smp_call_function(cache_flush, NULL, 1, 1); + #endif -- 2.43.0