diff -ru usr/src/nv/nv.c usr/src/nv.7152258/nv.c
--- usr/src/nv/nv.c	2008-01-23 05:12:23.000000000 +0100
+++ usr/src/nv.7152258/nv.c	2008-07-15 23:56:46.000000000 +0200
@@ -21,10 +21,9 @@
 #endif
 
 #if defined(KERNEL_2_4) && (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE))
-// weak linking?
 extern int i2c_add_adapter (struct i2c_adapter *) __attribute__ ((weak));
 extern int i2c_del_adapter (struct i2c_adapter *) __attribute__ ((weak));
-#endif // defined(KERNEL_2_4) && (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE))
+#endif
 
 /*
  * our global state; one per device
@@ -40,10 +39,7 @@
 static struct pm_dev *apm_nv_dev[NV_MAX_DEVICES] = { 0 };
 #endif
 
-int nv_pat_enabled = 0;
-
-static int nv_disable_pat = 0;
-NV_MODULE_PARAMETER(nv_disable_pat);
+int nv_pat_mode = NV_PAT_MODE_DISABLED;
 
 #if defined(NVCPU_X86) || defined(NVCPU_X86_64)
 NvU64 __nv_supported_pte_mask = ~_PAGE_NX;
@@ -502,7 +498,7 @@
     nv_state_t *nv;
     nv_linux_state_t *nvl;
 
-    proc_nvidia = create_proc_entry("nvidia", d_flags, proc_root_driver);
+    proc_nvidia = create_proc_entry("driver/nvidia", d_flags, NULL);
     if (!proc_nvidia)
         goto failed;
 
@@ -754,17 +750,18 @@
 static int   __nv_enable_pat_support   (void);
 static void  __nv_disable_pat_support  (void);
 
-#if defined(NV_BUILD_NV_PAT_SUPPORT)
+#if defined(NV_ENABLE_PAT_SUPPORT)
 /*
- * Private PAT support for use by the NVIDIA driver. This is an
- * interim solution until the kernel offers PAT support.
+ * Private PAT support for use by the NVIDIA driver. This is used
+ * on kernels that do not modify the PAT to include a write-combining
+ * entry.
  */
 static int   __check_pat_support       (void);
 static void  __nv_setup_pat_entries    (void *);
 static void  __nv_restore_pat_entries  (void *);
 
-#define NV_READ_PAT_ENTRIES(pat1, pat2)   rdmsr(IA32_CR_PAT, (pat1), (pat2))
-#define NV_WRITE_PAT_ENTRIES(pat1, pat2)  wrmsr(IA32_CR_PAT, (pat1), (pat2))
+#define NV_READ_PAT_ENTRIES(pat1, pat2)   rdmsr(0x277, (pat1), (pat2))
+#define NV_WRITE_PAT_ENTRIES(pat1, pat2)  wrmsr(0x277, (pat1), (pat2))
 #define NV_PAT_ENTRY(pat, index)          (((pat) & (0xff<<((index)*8)))>>((index)*8))
 
 static inline void __nv_disable_caches(unsigned long *cr4)
@@ -789,7 +786,7 @@
 static int __check_pat_support()
 {
     unsigned int pat1, pat2, i;
-
+    U008 PAT_WC_index;
     if (!test_bit(X86_FEATURE_PAT, (volatile unsigned long *)&boot_cpu_data.x86_capability))
     {
         nv_printf(NV_DBG_ERRORS,
@@ -798,24 +795,29 @@
     }
 
     NV_READ_PAT_ENTRIES(pat1, pat2);
+    PAT_WC_index = 0xf;
 
     for (i = 0; i < 4; i++)
     {
-         // we plan to mark PAT entry 1 as WC. if it's already marked such,
-         // that's fine, since it would be no different than us setting it.
-         if ((i != 1) && NV_PAT_ENTRY(pat1, i) == 1)
-         {
-             nv_printf(NV_DBG_ERRORS, "NVRM: PAT index %d already configured for Write-Combining!\n", i);
-             nv_printf(NV_DBG_ERRORS, "NVRM: Aborting, due to PAT already being configured\n");
-             return 0;
-         }
-
-         if (NV_PAT_ENTRY(pat2, i) == 1)
-         {
-             nv_printf(NV_DBG_ERRORS, "NVRM: PAT index %d already configured for Write-Combining!\n", i + 4);
-             nv_printf(NV_DBG_ERRORS, "NVRM: Aborting, due to PAT already being configured\n");
-             return 0;
-         }
+        if (NV_PAT_ENTRY(pat1, i) == 0x01)
+        {
+               PAT_WC_index = i;
+               break;
+        }
+        if (NV_PAT_ENTRY(pat2, i) == 0x01)
+        {
+               PAT_WC_index = i + 4;
+               break;
+        }
+    }
+
+    if (PAT_WC_index == 1)
+       nv_pat_mode = NV_PAT_MODE_KERNEL;
+    else if (PAT_WC_index != 0xf)
+    {
+       nv_printf(NV_DBG_ERRORS,
+               "NVRM: PAT configuration unsupported, falling back to MTRRs.\n");
+       return 0;
     }
 
     return 1;
@@ -870,19 +872,22 @@
     NV_RESTORE_FLAGS(eflags);
 }
 
-#endif /* defined(NV_BUILD_NV_PAT_SUPPORT) */
+#endif
 
 static int __nv_enable_pat_support()
 {
-#if defined(NV_BUILD_NV_PAT_SUPPORT)
+#if defined(NV_ENABLE_PAT_SUPPORT)
     unsigned long pat1, pat2;
 
-    if (nv_pat_enabled)
+    if (nv_pat_mode != NV_PAT_MODE_DISABLED)
         return 1;
 
     if (!__check_pat_support())
         return 0;
 
+    if (nv_pat_mode != NV_PAT_MODE_DISABLED)
+        return 1;
+
     NV_READ_PAT_ENTRIES(orig_pat1, orig_pat2);
     nv_printf(NV_DBG_SETUP, "saved orig pats as 0x%lx 0x%lx\n", orig_pat1, orig_pat2);
 
@@ -892,31 +897,31 @@
         return 0;
     }
 
-    nv_pat_enabled = 1;
+    nv_pat_mode = NV_PAT_MODE_BUILTIN;
 
     NV_READ_PAT_ENTRIES(pat1, pat2);
     nv_printf(NV_DBG_SETUP, "changed pats to 0x%lx 0x%lx\n", pat1, pat2);
-#endif /* defined(NV_BUILD_NV_PAT_SUPPORT) */
+#endif
 
     return 1;
 }
 
 static void __nv_disable_pat_support()
 {
-#if defined(NV_BUILD_NV_PAT_SUPPORT)
+#if defined(NV_ENABLE_PAT_SUPPORT)
     unsigned long pat1, pat2;
 
-    if (!nv_pat_enabled)
+    if (!nv_pat_mode != NV_PAT_MODE_BUILTIN)
         return;
 
     if (nv_execute_on_all_cpus(__nv_restore_pat_entries, NULL) != 0)
         return;
 
-    nv_pat_enabled = 0;
+    nv_pat_mode = NV_PAT_MODE_DISABLED;
 
     NV_READ_PAT_ENTRIES(pat1, pat2);
     nv_printf(NV_DBG_SETUP, "restored orig pats as 0x%lx 0x%lx\n", pat1, pat2);
-#endif /* defined(NV_BUILD_NV_PAT_SUPPORT) */
+#endif
 }
 
 
@@ -1130,7 +1135,7 @@
             break;
         default:
             expected = pgprot_val(PAGE_KERNEL_NOCACHE);
-            if ((flags & ~_PAGE_NX) == (expected & ~_PAGE_NX))
+            if ((flags & ~(_PAGE_NX | _PAGE_PWT)) == (expected & ~(_PAGE_NX | _PAGE_PWT)))
                 retval = 0;
             break;
     }
@@ -1157,7 +1162,7 @@
     return retval;
 }
 
-#if defined(NV_BUILD_NV_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU)
+#if defined(NV_ENABLE_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU)
 static int
 nv_kern_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
@@ -1190,7 +1195,7 @@
     .priority = 0
 };
 
-#endif /* defined(NV_BUILD_NV_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU) */
+#endif
 
 
 /***
@@ -1199,8 +1204,9 @@
 
 static int __init nvidia_init_module(void)
 {
-    int rc;
-    U032 i, count;
+    int rc, disable_pat = 0;
+    U032 i, count, data;
+    nv_state_t *nv = NV_STATE_PTR(&nv_ctl_device);
 
 #if defined(VM_CHECKER)
     nv_init_lock(vm_lock);
@@ -1314,18 +1320,6 @@
         nv_printf(NV_DBG_ERRORS, "NVRM: pte cache allocation failed\n");
         goto failed;
     }
- 
-#if defined(NV_BUILD_NV_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU)
-    if (!nv_disable_pat)
-    {
-        if (register_hotcpu_notifier(&nv_hotcpu_nfb) != 0)
-        {
-            rc = -EIO;
-            nv_printf(NV_DBG_ERRORS, "NVRM: CPU hotplug notifier registration failed!\n");
-            goto failed;
-        }
-    }
-#endif
 
 #if defined(NV_SG_MAP_BUFFERS)
     rm_read_registry_dword(NV_STATE_PTR(&nv_ctl_device), "NVreg", "RemapLimit",  &nv_remap_limit);
@@ -1404,15 +1398,33 @@
 
     nvos_proc_add_warning_file("README", __README_warning);
 
-#if defined(NV_BUILD_NV_PAT_SUPPORT)
-    if (!nv_disable_pat)
+    rc = rm_read_registry_dword(nv, "NVreg", "UsePageAttributeTable", &data);
+    if ((rc == 0) && ((int)data != ~0))
+    {
+       disable_pat = (data == 0);
+    }
+    if (!disable_pat)
+    {
         __nv_enable_pat_support();
+#if defined(NV_ENABLE_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU)
+        if (nv_pat_mode == NV_PAT_MODE_BUILTIN)
+        {
+            if (register_hotcpu_notifier(&nv_hotcpu_nfb) != 0)
+            {
+                __nv_disable_pat_support();
+                rc = -EIO;
+                nv_printf(NV_DBG_ERRORS,
+                    "NVRM: CPU hotplug notifier registration failed!\n");
+                goto failed;
+            }
+        }
+#endif
+    }
     else
     {
         nv_printf(NV_DBG_ERRORS,
             "NVRM: builtin PAT support disabled, falling back to MTRRs.\n");
     }
-#endif
 
 #if (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)) && defined(KERNEL_2_4)
     // attempt to load the i2c modules for linux kernel
@@ -1552,15 +1564,13 @@
     rm_unregister_ioctl_conversions();
 #endif
 
-#if defined(NV_BUILD_NV_PAT_SUPPORT)
-    if (nv_pat_enabled)
+    if (nv_pat_mode == NV_PAT_MODE_BUILTIN)
     {
         __nv_disable_pat_support();
-#if defined(CONFIG_HOTPLUG_CPU)
+#if defined(NV_ENABLE_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU)
         unregister_hotcpu_notifier(&nv_hotcpu_nfb);
 #endif
     }
-#endif
 
 #if defined(NV_ENABLE_MEM_TRACKING)
 #if defined(VM_CHECKER)
@@ -1677,7 +1687,8 @@
         }
     }
 }
-
+#if !defined(NV_VM_INSERT_PAGE_PRESENT)
+static
 struct page *nv_kern_vma_nopage(
     struct vm_area_struct *vma,
     unsigned long address,
@@ -1688,22 +1699,21 @@
 #endif
 )
 {
-#if !defined(NV_VM_INSERT_PAGE_PRESENT)
     struct page *page;
 
     page = pfn_to_page(vma->vm_pgoff);
     get_page(page);
 
     return page;
-#else
-    return NOPAGE_SIGBUS;
-#endif
 }
+#endif
 
 struct vm_operations_struct nv_vm_ops = {
     .open   = nv_kern_vma_open,
     .close  = nv_kern_vma_release,  /* "close" */
+#if !defined(NV_VM_INSERT_PAGE_PRESENT)
     .nopage = nv_kern_vma_nopage,
+#endif
 };
 
 static nv_file_private_t *
@@ -1982,12 +1992,15 @@
             *prot = pgprot_noncached(*prot);
             break;
         case NV_MEMORY_WRITECOMBINED:
-            if (nv_pat_enabled &&
+#if defined(NV_ENABLE_PAT_SUPPORT)
+            if ((nv_pat_mode != NV_PAT_MODE_DISABLED) &&
                 (memory_type != NV_MEMORY_TYPE_REGISTERS))
             {
-                *prot = pgprot_writecombined(*prot);
+                pgprot_val(*prot) &= ~(_PAGE_PSE | _PAGE_PCD | _PAGE_PWT);
+                *prot = __pgprot(pgprot_val(*prot) | _PAGE_PWT);
                 break;
             }
+#endif
             /*
              * If PAT support is unavailable and the memory space isn't
              * NV_MEMORY_TYPE_AGP, we need to return an error code to
@@ -2007,7 +2020,6 @@
                 break;
             return 1;
         case NV_MEMORY_CACHED:
-        //case NV_MEMORY_WRITEBACK:
             /*
              * RAM is cached on Linux by default, we can assume there's
              * nothing to be done here. This is not the case for the
@@ -2024,8 +2036,6 @@
              */
             if (memory_type == NV_MEMORY_TYPE_SYSTEM)
                 break;
-        //case NV_MEMORY_WRITETHRU:
-        //case NV_MEMORY_WRITEPROTECT:
         default:
             nv_printf(NV_DBG_ERRORS,
                 "NVRM: VM: memory type %d not supported for memory space %d!\n",
@@ -3465,8 +3475,9 @@
 
     nv_init_lock(nvl->rm_lock);
 
-    sema_init(&nvl->ldata_lock, 1);
-    sema_init(&nvl->at_lock, 1);
+    NV_INIT_MUTEX(&nvl->ldata_lock);
+    NV_INIT_MUTEX(&nvl->at_lock);
+
     NV_ATOMIC_SET(nvl->usage_count, 0);
 
     nvl->rm_lock_cpu = -1;
diff -ru usr/src/nv/nv-linux.h usr/src/nv.7152258/nv-linux.h
--- usr/src/nv/nv-linux.h	2008-01-23 05:12:23.000000000 +0100
+++ usr/src/nv.7152258/nv-linux.h	2008-07-15 23:56:46.000000000 +0200
@@ -139,16 +139,18 @@
 #endif
 
 #if defined(NVCPU_X86) || defined(NVCPU_X86_64)
-#define NV_BUILD_NV_PAT_SUPPORT 1
+#define NV_ENABLE_PAT_SUPPORT 1
 #endif
+#define NV_PAT_MODE_DISABLED 0
+#define NV_PAT_MODE_KERNEL 1
+#define NV_PAT_MODE_BUILTIN 2
+
+extern int nv_pat_mode;
 
-#if defined(NV_BUILD_NV_PAT_SUPPORT)
-#include "pat.h"
 #if defined(CONFIG_HOTPLUG_CPU)
 #include <linux/cpu.h>              /* CPU hotplug support              */
 #include <linux/notifier.h>         /* struct notifier_block, etc       */
 #endif
-#endif
 
 #if (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE))
 #include <linux/i2c.h>
@@ -630,6 +632,13 @@
 #define nv_down(lock)                   down(&lock)
 #define nv_up(lock)                     up(&lock)
 
+#define NV_INIT_MUTEX(mutex)                   \
+       {                                       \
+               struct semaphore __mutex =      \
+                       __SEMAPHORE_INITIALIZER(*(mutex), 1); \
+               *(mutex) = __mutex;             \
+       }
+
 #if defined (KERNEL_2_4)
 #  define NV_IS_SUSER()                 suser()
 #  define NV_PCI_DEVICE_NAME(dev)       ((dev)->name)
@@ -954,19 +963,6 @@
     }
 #endif
 
-#if defined(NV_BUILD_NV_PAT_SUPPORT) && !defined (pgprot_writecombined)
-static inline pgprot_t pgprot_writecombined(pgprot_t old_prot)
-    {
-        pgprot_t new_prot = old_prot;
-        if (boot_cpu_data.x86 > 3)
-        {
-            pgprot_val(old_prot) &= ~(_PAGE_PCD | _PAGE_PWT);
-            new_prot = __pgprot(pgprot_val(old_prot) | _PAGE_WRTCOMB);
-        }
-        return new_prot;
-    }
-#endif
-
 #if defined(KERNEL_2_4) && defined(NVCPU_X86) && !defined(pfn_to_page)
 #define pfn_to_page(pfn) (mem_map + (pfn))
 #endif
@@ -1057,8 +1053,6 @@
     struct semaphore at_lock;
 } nv_linux_state_t;
 
-extern int nv_pat_enabled;
-
 /*
  * file-private data
  * hide a pointer to our data structures in a file-private ptr
diff -ru usr/src/nv/nv-vm.c usr/src/nv.7152258/nv-vm.c
--- usr/src/nv/nv-vm.c	2008-01-23 05:12:23.000000000 +0100
+++ usr/src/nv.7152258/nv-vm.c	2008-07-15 23:56:46.000000000 +0200
@@ -360,7 +360,6 @@
 #if defined(NV_CPA_NEEDS_FLUSHING)
     nv_execute_on_all_cpus(cache_flush, NULL);
 #endif
-    global_flush_tlb();
 #endif
 }
 
diff -ru usr/src/nv/os-agp.c usr/src/nv.7152258/os-agp.c
--- usr/src/nv/os-agp.c	2008-01-23 05:12:23.000000000 +0100
+++ usr/src/nv.7152258/os-agp.c	2008-07-15 23:56:46.000000000 +0200
@@ -112,7 +112,7 @@
         goto release;
     }
 
-    if (!nv_pat_enabled)
+    if (nv_pat_mode == NV_PAT_MODE_DISABLED)
     {
 #ifdef CONFIG_MTRR
         /*
@@ -171,7 +171,7 @@
 
 failed:
 #ifdef CONFIG_MTRR
-    if (!nv_pat_enabled)
+    if (nv_pat_mode == NV_PAT_MODE_DISABLED)
         mtrr_del(-1, agp_info.aper_base, agp_info.aper_size << 20);
 #endif
 release:
@@ -199,7 +199,7 @@
     nvl = NV_GET_NVL_FROM_NV_STATE(nv);
 
 #ifdef CONFIG_MTRR
-    if (!nv_pat_enabled)
+    if (nv_pat_mode == NV_PAT_MODE_DISABLED)
         mtrr_del(-1, nv->agp.address, nv->agp.size);
 #endif
 
diff -ru usr/src/nv/os-interface.c usr/src/nv.7152258/os-interface.c
--- usr/src/nv/os-interface.c	2008-01-23 05:12:23.000000000 +0100
+++ usr/src/nv.7152258/os-interface.c	2008-07-15 23:56:46.000000000 +0200
@@ -1260,7 +1260,7 @@
 
 BOOL NV_API_CALL os_pat_supported(void)
 {
-    return nv_pat_enabled;
+    return nv_pat_mode != NV_PAT_MODE_DISABLED;
 }
 
 void NV_API_CALL os_dump_stack()
diff -ru usr/src/nv/os-registry.c usr/src/nv.7152258/os-registry.c
--- usr/src/nv/os-registry.c	2008-01-23 05:12:23.000000000 +0100
+++ usr/src/nv.7152258/os-registry.c	2008-07-15 23:56:46.000000000 +0200
@@ -483,6 +483,15 @@
 static int NVreg_RMEdgeIntrCheck = 1;
 NV_MODULE_PARAMETER(NVreg_RMEdgeIntrCheck);
 
+
+// Option: UsePageAttributeTable
+// Possible values:
+//     ~0 = use the NVIDIA driver's default logic (default)
+//      1 = enable use of PAT for WC mappings.
+//      2 = disable use of the PAT for WC mappings.
+static int NVreg_UsePageAttributeTable = 0;
+NV_MODULE_PARAMETER(NVreg_UsePageAttributeTable);
+
 /*
  * You can enable any of the registry options disabled by default by
  * editing their respective entries in the table below. The last field
@@ -517,6 +526,7 @@
     { "NVreg",  "PanelPWMFrequency",        &NVreg_PanelPWMFrequency,        1 },
     { "NVreg",  "PanelBrightnessLimits",    &NVreg_PanelBrightnessLimits,    1 },
     { "NVreg",  "RMEdgeIntrCheck",          &NVreg_RMEdgeIntrCheck,          1 },
+    { "NVreg",  "UsePageAttributeTable",    &NVreg_UsePageAttributeTable,    1 },
     {  NULL,     NULL,                      NULL,                            0 }
 };