e511cfbb0851cca7ba447fe7a9170ff4ca3cffdc
[packages/xorg-driver-video-nvidia.git] / NVIDIA_kernel-169.12-2286310.diff
1 diff -ru usr/src/nv/Makefile.kbuild usr/src/nv.2286310/Makefile.kbuild
2 --- usr/src/nv/Makefile.kbuild  2008-03-16 14:13:10.000000000 -0700
3 +++ usr/src/nv.2286310/Makefile.kbuild  2008-03-16 14:37:47.204131496 -0700
4 @@ -177,6 +177,7 @@
5         vmap \
6         signal_struct \
7         agp_backend_acquire \
8 +       set_pages_uc \
9         change_page_attr \
10         pci_get_class \
11         sysctl_max_map_count \
12 diff -ru usr/src/nv/conftest.sh usr/src/nv.2286310/conftest.sh
13 --- usr/src/nv/conftest.sh      2008-03-16 14:13:10.000000000 -0700
14 +++ usr/src/nv.2286310/conftest.sh      2008-03-16 14:37:47.204131496 -0700
15 @@ -100,6 +100,32 @@
16              fi
17          ;;
18  
19 +        set_pages_uc)
20 +            #
21 +            # Determine if the set_pages_uc() function is present.
22 +            #
23 +            echo "#include <linux/autoconf.h>
24 +            #include <asm/cacheflush.h>
25 +            void conftest_set_pages_uc(void) {
26 +                set_pages_uc();
27 +            }" > conftest$$.c
28 +
29 +            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
30 +            rm -f conftest$$.c
31 +
32 +            if [ -f conftest$$.o ]; then
33 +                rm -f conftest$$.o
34 +                echo "#undef NV_SET_PAGES_UC_PRESENT" >> conftest.h
35 +                return
36 +            else
37 +                echo "#ifdef NV_CHANGE_PAGE_ATTR_PRESENT" >> conftest.h
38 +                echo "#undef NV_CHANGE_PAGE_ATTR_PRESENT" >> conftest.h
39 +                echo "#endif"                             >> conftest.h
40 +                echo "#define NV_SET_PAGES_UC_PRESENT"    >> conftest.h
41 +                return
42 +            fi
43 +        ;;
44 +
45          change_page_attr)
46              #
47              # Determine if the change_page_attr() function is
48 @@ -124,7 +150,9 @@
49                  rm -f conftest$$.o
50                  return
51              else
52 +                echo "#ifndef NV_SET_PAGES_UC_PRESENT"     >> conftest.h
53                  echo "#define NV_CHANGE_PAGE_ATTR_PRESENT" >> conftest.h
54 +                echo "#endif"                              >> conftest.h
55                  return
56              fi
57          ;;
58 @@ -524,6 +552,8 @@
59                  return
60              fi
61  
62 +            rm -f conftest$$.o
63 +
64              echo "#include <linux/autoconf.h>
65              #include <linux/interrupt.h>
66              irq_handler_t conftest_isr;
67 diff -ru usr/src/nv/nv-linux.h usr/src/nv.2286310/nv-linux.h
68 --- usr/src/nv/nv-linux.h       2008-03-16 14:13:10.000000000 -0700
69 +++ usr/src/nv.2286310/nv-linux.h       2008-03-16 14:37:47.204131496 -0700
70 @@ -871,9 +871,10 @@
71  
72  #define NV_PGD_OFFSET(address, kernel, mm)              \
73     ({                                                   \
74 +        struct mm_struct *__mm = (mm);                  \
75          pgd_t *__pgd;                                   \
76          if (!kernel)                                    \
77 -            __pgd = pgd_offset(mm, address);            \
78 +            __pgd = pgd_offset(__mm, address);          \
79          else                                            \
80              __pgd = pgd_offset_k(address);              \
81          __pgd;                                          \
82 @@ -1208,21 +1209,24 @@
83              nv_check_pci_config_space(nv, cb);                      \
84      }
85  
86 +extern int nv_update_memory_types;
87 +
88  /*
89 - * a BUG() is triggered on early 2.6 x86_64 kernels. the underlying
90 - * problem actually exists on many architectures and kernels, but
91 - * these are the only kernels that check the condition and trigger
92 - * a BUG(). note that this is a problem of the core kernel, not an
93 - * nvidia bug (and can still be triggered by agpgart). let's avoid
94 - * change_page_attr on those kernels.
95 + * Using change_page_attr() on early Linux/x86-64 2.6 kernels may
96 + * result in a BUG() being triggered. The underlying problem
97 + * actually exists on multiple architectures and kernels, but only
98 + * the above check for the condition and trigger a BUG().
99 + *
100 + * Note that this is a due to a bug in the Linux kernel, not an
101 + * NVIDIA driver bug (it can also be triggered by AGPGART).
102 + *
103 + * We therefore need to determine at runtime if change_page_attr()
104 + * can be used safely on these kernels.
105   */
106 -#if defined(NV_CHANGE_PAGE_ATTR_PRESENT)
107 -extern int nv_use_cpa;
108 -
109 -#if defined(NVCPU_X86_64) && !defined(KERNEL_2_4) && \
110 -         (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11))
111 -#define NV_CHANGE_PAGE_ATTR_BUG_PRESENT 1
112 -#endif
113 +#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) && defined(NVCPU_X86_64) && \
114 +  !defined(KERNEL_2_4) && \
115 +  (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11))
116 +#define NV_CHANGE_PAGE_ATTR_BUG_PRESENT
117  #endif
118  
119  #if defined(NVCPU_X86) || defined(NVCPU_X86_64)
120 @@ -1234,7 +1238,7 @@
121   *
122   * We need to be careful to mask out _PAGE_NX when the host system
123   * doesn't support this feature or when it's disabled: the kernel
124 - * may not do this in its implementation of the  change_page_attr()
125 + * may not do this in its implementation of the change_page_attr()
126   * interface.
127   */
128  #ifndef X86_FEATURE_NX
129 diff -ru usr/src/nv/nv-reg.h usr/src/nv.2286310/nv-reg.h
130 --- usr/src/nv/nv-reg.h 2008-03-16 14:13:10.000000000 -0700
131 +++ usr/src/nv.2286310/nv-reg.h 2008-03-16 14:37:47.204131496 -0700
132 @@ -391,34 +391,36 @@
133  #define NV_REG_REMAP_LIMIT NV_REG_STRING(__NV_REMAP_LIMIT)
134  
135  /*
136 - * Option: UseCPA
137 + * Option: UpdateMemoryTypes
138   *
139   * Description:
140   *
141 - * Many kernels have a broken implementation of change_page_attr that leads
142 - * to cache aliasing problems. x86_64 kernels between 2.6.0 and 2.6.10 will
143 - * force a kernel BUG_ON() when this condition is encountered. For this
144 - * reason, the NVIDIA driver is very careful about not using the CPA kernel
145 - * interface on these kernels.
146 - *
147 - * Some distributions have backported this fix to kernel versions that fall
148 - * within this version range. The NVIDIA driver attempts to automatically
149 - * detect these fixes and reenable usage of the change_page_attr interface.
150 - *
151 - * Due to the serious nature of the problems that can arise from this, the
152 - * NVIDIA driver implements a manual registry key to force usage of this API
153 - * to be enabled or disabled. This registry key can be used to force usage
154 - * of the API on a known fixed kernel if the NVIDIA driver fails to detect
155 - * the kernel as fixed. This registry key can also be used to disable usage
156 - * of the API on a bad kernel that is misdetected as a fixed kernel.
157 - *
158 - * The default value is '-1' (use NVIDIA driver default logic)
159 - * A value of '0' will forcibly disable change_page_attr calls.
160 - * A value of '1' will forcibly enable change_page_attr calls.
161 + * Many kernels have broken implementations of the change_page_attr()
162 + * kernel interface that may cause cache aliasing problems. Linux/x86-64
163 + * kernels between 2.6.0 and 2.6.10 may prompt kernel BUG()s due to
164 + * improper accounting in the interface's large page management code, for
165 + * example. For this reason, the NVIDIA Linux driver is very careful about
166 + * not using the change_page_attr() kernel interface on these kernels.
167 + *
168 + * Due to the serious nature of the problems that can arise from bugs in
169 + * the change_page_attr(), set_pages_{uc,wb}() and other kernel interfaces
170 + * used to modify memory types, the NVIDIA driver implements a manual
171 + * registry key override to allow forcibly enabling or disabling use of
172 + * these APIs.
173 + *
174 + * Possible values:
175 + *
176 + * ~0 = use the NVIDIA driver's default logic (default)
177 + *  0 = enable use of change_page_attr(), etc.
178 + *  1 = disable use of change_page_attr(), etc.
179 + *
180 + * By default, the NVIDIA driver will attempt to auto-detect if it can
181 + * safely use the change_page_attr() and other kernel interfaces to modify
182 + * the memory types of kernel mappings.
183   */
184  
185 -#define __NV_USE_CPA UseCPA
186 -#define NV_REG_USE_CPA NV_REG_STRING(__NV_USE_CPA)
187 +#define __NV_UPDATE_MEMORY_TYPES UpdateMemoryTypes
188 +#define NV_REG_UPDATE_MEMORY_TYPES NV_REG_STRING(__NV_UPDATE_MEMORY_TYPES)
189  
190  /*
191   * Option: RegistryDwords
192 @@ -490,7 +492,7 @@
193  NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_GID, 0);
194  NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_MODE, 0666);
195  NV_DEFINE_REG_ENTRY(__NV_REMAP_LIMIT, 0);
196 -NV_DEFINE_REG_ENTRY(__NV_USE_CPA, -1);
197 +NV_DEFINE_REG_ENTRY(__NV_UPDATE_MEMORY_TYPES, ~0);
198  NV_DEFINE_REG_ENTRY(__NV_USE_VBIOS, 1);
199  NV_DEFINE_REG_ENTRY(__NV_RM_EDGE_INTR_CHECK, 1);
200  
201 @@ -535,7 +537,7 @@
202      NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_DEVICE_FILE_GID),
203      NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_DEVICE_FILE_MODE),
204      NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_REMAP_LIMIT),
205 -    NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_USE_CPA),
206 +    NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_UPDATE_MEMORY_TYPES),
207      NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_USE_VBIOS),
208      NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_RM_EDGE_INTR_CHECK),
209      {NULL, NULL, NULL}
210 diff -ru usr/src/nv/nv-vm.c usr/src/nv.2286310/nv-vm.c
211 --- usr/src/nv/nv-vm.c  2008-03-16 14:13:09.000000000 -0700
212 +++ usr/src/nv.2286310/nv-vm.c  2008-03-16 14:37:47.204131496 -0700
213 @@ -43,42 +43,40 @@
214  }
215  #endif
216  
217 -/*
218 - * AMD Athlon processors expose a subtle bug in the Linux
219 - * kernel, that may lead to AGP memory corruption. Recent
220 - * kernel versions had a workaround for this problem, but
221 - * 2.4.20 is the first kernel to address it properly. The
222 - * page_attr API provides the means to solve the problem. 
223 - */
224 -
225  static inline void nv_set_page_attrib_uncached(nv_pte_t *page_ptr)
226  {
227 -#if defined(NV_CHANGE_PAGE_ATTR_PRESENT)
228 -    if (nv_use_cpa)
229 +    if (nv_update_memory_types)
230      {
231 -        struct page *page = virt_to_page(__va(page_ptr->phys_addr));
232 +#if defined(NV_SET_PAGES_UC_PRESENT)
233 +        struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr);
234 +        set_pages_uc(page, 1);
235 +#elif defined(NV_CHANGE_PAGE_ATTR_PRESENT)
236 +        struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr);
237          pgprot_t prot = PAGE_KERNEL_NOCACHE;
238  #if defined(NVCPU_X86) || defined(NVCPU_X86_64)
239          pgprot_val(prot) &= __nv_supported_pte_mask;
240  #endif
241          change_page_attr(page, 1, prot);
242 -    }
243  #endif
244 +    }
245  }
246  
247  static inline void nv_set_page_attrib_cached(nv_pte_t *page_ptr)
248  {
249 -#if defined(NV_CHANGE_PAGE_ATTR_PRESENT)
250 -    if (nv_use_cpa)
251 +    if (nv_update_memory_types)
252      {
253 -        struct page *page = virt_to_page(__va(page_ptr->phys_addr));
254 +#if defined(NV_SET_PAGES_UC_PRESENT)
255 +        struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr);
256 +        set_pages_wb(page, 1);
257 +#elif defined(NV_CHANGE_PAGE_ATTR_PRESENT)
258 +        struct page *page = NV_GET_PAGE_STRUCT(page_ptr->phys_addr);
259          pgprot_t prot = PAGE_KERNEL;
260  #if defined(NVCPU_X86) || defined(NVCPU_X86_64)
261          pgprot_val(prot) &= __nv_supported_pte_mask;
262  #endif
263          change_page_attr(page, 1, prot);
264 +#endif
265      }
266 -#endif /* NV_CHANGE_PAGE_ATTR_PRESENT */
267  }
268  
269  static inline void nv_lock_page(nv_pte_t *page_ptr)
270 @@ -360,7 +358,8 @@
271  #if defined(NV_CPA_NEEDS_FLUSHING)
272      nv_execute_on_all_cpus(cache_flush, NULL);
273  #endif
274 -#if defined (NVCPU_X86) || defined (NVCPU_X86_64)
275 +#if (defined(NVCPU_X86) || defined(NVCPU_X86_64)) && \
276 +  defined(NV_CHANGE_PAGE_ATTR_PRESENT)
277      global_flush_tlb();
278  #endif
279      nv_ext_flush_caches(); // handle other platform flushes if present
280 @@ -662,7 +661,7 @@
281  
282          address = (unsigned long)virt_addr + i * PAGE_SIZE; 
283  
284 -        pgd = NV_PGD_OFFSET(address, 1, &init_mm);
285 +        pgd = NV_PGD_OFFSET(address, 1, NULL);
286          if (!NV_PGD_PRESENT(pgd))
287              goto failed;
288  
289 diff -ru usr/src/nv/nv.c usr/src/nv.2286310/nv.c
290 --- usr/src/nv/nv.c     2008-03-16 14:13:09.000000000 -0700
291 +++ usr/src/nv.2286310/nv.c     2008-03-16 14:37:47.208131723 -0700
292 @@ -15,6 +15,7 @@
293  #include "nv_compiler.h"
294  #include "os-agp.h"
295  #include "nv-vm.h"
296 +#include "nv-reg.h"
297  
298  #ifdef MODULE_ALIAS_CHARDEV_MAJOR
299  MODULE_ALIAS_CHARDEV_MAJOR(NV_MAJOR_DEVICE_NUMBER);
300 @@ -116,10 +117,7 @@
301  unsigned int nv_remap_limit;
302  #endif
303  
304 -#if defined(NV_CHANGE_PAGE_ATTR_PRESENT)
305 -int nv_use_cpa = 1;
306 -#endif
307 -
308 +int nv_update_memory_types = 1;
309  static int nv_mmconfig_failure_detected = 0;
310  
311  static void *nv_pte_t_cache = NULL;
312 @@ -1030,30 +1028,26 @@
313  #endif /* defined(NV_BUILD_NV_PAT_SUPPORT) */
314  }
315  
316 -
317  #if defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT)
318 -
319 -/* nv_verify_cpa_interface - determine if the change_page_attr bug is fixed
320 - * in this kernel.
321 +/*
322 + * nv_verify_cpa_interface() - determine if the change_page_attr() large page
323 + * management accounting bug known to exist in early Linux/x86-64 kernels
324 + * is present in this kernel.
325   *
326 - * there's really not a good way to determine if change_page_attr is fixed.
327 - * we can't really use cpa on 2.6 x86_64 kernels < 2.6.11, as if we run into
328 - * the accounting bug, the kernel will throw a BUG. this isn't 100% accurate,
329 - * as it doesn't throw a bug until we try to restore the caching attributes
330 - * of the page. so if we can track down a 4M allocation, we can mark it
331 - * uncached and see if the accounting was done correctly.
332 - * 
333 - * this is a little ugly, but the most accurate approach to determining if
334 - * this kernel is good.
335 + * There's really no good way to determine if change_page_attr() is working
336 + * correctly. We can't reliably use change_page_attr() on Linux/x86-64 2.6
337 + * kernels < 2.6.11: if we run into the accounting bug, the Linux kernel will
338 + * trigger a BUG() if we attempt to restore the WB memory type of a page
339 + * originally part of a large page.
340   *
341 - * why do we even bother? some distributions have back-ported the cpa fix to
342 - * kernels < 2.6.11. we want to use change_page_attr to avoid random corruption
343 - * and hangs, but need to make sure it's safe to do so.
344 + * So if we can successfully allocate such a page, change its memory type to
345 + * UC and check if the accounting was done correctly, we can determine if
346 + * the change_page_attr() interface can be used safely.
347   *
348 - * return values:
349 - *    0 - test passed, interface works
350 - *    1 - test failed, status unclear
351 - *   -1 - test failed, interface broken
352 + * Return values:
353 + *    0 - test passed, the change_page_attr() interface works
354 + *    1 - test failed, the status is unclear
355 + *   -1 - test failed, the change_page_attr() interface is broken
356   */
357  
358  static inline pte_t *check_large_page(unsigned long vaddr)
359 @@ -1061,7 +1055,7 @@
360      pgd_t *pgd = NULL;
361      pmd_t *pmd = NULL;
362  
363 -    pgd = NV_PGD_OFFSET(vaddr, 1, &init_mm);
364 +    pgd = NV_PGD_OFFSET(vaddr, 1, NULL);
365      if (!NV_PGD_PRESENT(pgd))
366          return NULL;
367  
368 @@ -1171,20 +1165,29 @@
369  
370      return 1;
371  }
372 -
373  #endif /* defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT) */
374  
375 -
376 -// verify that the kernel's mapping matches the requested type 
377 -// this is to protect against accidental cache aliasing problems
378 +/*
379 + * nv_verify_page_mappings() - verify that the kernel mapping of the specified
380 + * page matches the specified type. This is to help detect bugs in the Linux
381 + * kernel's change_page_attr() interface, early.
382 + *
383 + * This function relies on the ability to perform kernel virtul address to PFN
384 + * translations and therefore on 'init_mm'. Unfortunately, the latter is no
385 + * longer exported in recent Linux/x86 2.6 kernels. The export was removed at
386 + * roughtly the same time as the set_pages_{uc,wb}() change_page_attr()
387 + * replacement interfaces were introduced; hopefully, it will be sufficient to
388 + * check for their presence.
389 + */
390  int nv_verify_page_mappings(
391      nv_pte_t *page_ptr,
392      unsigned int cachetype
393  )
394  {
395 +#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) || \
396 +    (defined(NV_SET_PAGES_UC_PRESENT) && !defined(NVCPU_X86))
397      unsigned long retval = -1;
398  #if defined(NVCPU_X86) || defined(NVCPU_X86_64)
399 -    struct mm_struct *mm;
400      pgd_t *pgd = NULL;
401      pmd_t *pmd = NULL;
402      pte_t *pte = NULL;
403 @@ -1192,15 +1195,12 @@
404      unsigned long address;
405      static int count = 0;
406  
407 -#if defined(NV_CHANGE_PAGE_ATTR_PRESENT)
408 -    if (!nv_use_cpa)
409 +    if (!nv_update_memory_types)
410          return 0;
411 -#endif
412  
413      address = (unsigned long)__va(page_ptr->phys_addr);
414 -    mm = &init_mm; // always a kernel page
415  
416 -    pgd = NV_PGD_OFFSET(address, 1, mm);
417 +    pgd = NV_PGD_OFFSET(address, 1, NULL);
418      if (!NV_PGD_PRESENT(pgd))
419      {
420          nv_printf(NV_DBG_ERRORS, "NVRM: pgd not present for addr 0x%lx\n", address);
421 @@ -1266,8 +1266,11 @@
422      }
423  
424  failed:
425 -#endif
426 +#endif /* defined(NVCPU_X86) || defined(NVCPU_X86_64) */
427      return retval;
428 +#else
429 +    return 0;
430 +#endif
431  }
432  
433  #if defined(NV_BUILD_NV_PAT_SUPPORT) && defined(CONFIG_HOTPLUG_CPU)
434 @@ -1313,7 +1316,7 @@
435  static int __init nvidia_init_module(void)
436  {
437      int rc;
438 -    U032 i, count;
439 +    U032 i, count, data;
440      nv_state_t *nv = NV_STATE_PTR(&nv_ctl_device);
441      nv_stack_t *sp = NULL;
442  
443 @@ -1485,43 +1488,42 @@
444      /* create /proc/driver/nvidia */
445      nvos_proc_create();
446  
447 -#if defined(NV_CHANGE_PAGE_ATTR_PRESENT)
448 +    /*
449 +     * Give users an opportunity to disable the driver's use of
450 +     * the change_page_attr() and set_pages_{uc,wb}() kernel
451 +     * interfaces.
452 +     */
453 +    rc = rm_read_registry_dword(sp, nv,
454 +            "NVreg", NV_REG_UPDATE_MEMORY_TYPES, &data);
455 +    if ((rc == 0) && ((int)data != ~0))
456      {
457 -        int data;
458 -
459 -        // allow the user to override us with a registry key
460 -        rc = rm_read_registry_dword(sp, nv, "NVreg", "UseCPA", &data);
461 -        if ((rc == 0) && (data != -1))
462 -        {
463 -            nv_use_cpa = data;
464 -        }
465 +        nv_update_memory_types = data;
466 +    }
467  #if defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT)
468 -        else
469 +    /*
470 +     * Unless we explicitely detect that the change_page_attr()
471 +     * inteface is fixed, disable usage of the interface on
472 +     * this kernel. Notify the user of this problem using the
473 +     * driver's /proc warnings interface (read by the installer
474 +     * and the bug report script).
475 +     */
476 +    else
477 +    {
478 +        rc = nv_verify_cpa_interface();
479 +        if (rc < 0)
480          {
481 -            /*
482 -             * Unless we explicitely detect that the change_page_attr()
483 -             * inteface is fixed, disable usage of the interface on
484 -             * this kernel. Notify the user of this problem using the
485 -             * driver's /proc warnings interface (read by the installer
486 -             * and the bug report script).
487 -             */
488 -            rc = nv_verify_cpa_interface();
489 -            if (rc < 0)
490 -            {
491 -                nv_prints(NV_DBG_ERRORS, __cpgattr_warning);
492 -                nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning);
493 -                nv_use_cpa = 0;
494 -            }
495 -            else if (rc != 0)
496 -            {
497 -                nv_prints(NV_DBG_ERRORS, __cpgattr_warning_2);
498 -                nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning_2);
499 -                nv_use_cpa = 0;
500 -            }
501 +            nv_prints(NV_DBG_ERRORS, __cpgattr_warning);
502 +            nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning);
503 +            nv_update_memory_types = 0;
504 +        }
505 +        else if (rc != 0)
506 +        {
507 +            nv_prints(NV_DBG_ERRORS, __cpgattr_warning_2);
508 +            nvos_proc_add_warning_file("change_page_attr", __cpgattr_warning_2);
509 +            nv_update_memory_types = 0;
510          }
511 -#endif
512      }
513 -#endif
514 +#endif /* defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT) */
515  
516  #if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION) && !defined(HAVE_COMPAT_IOCTL)
517      /* Register ioctl()'s for 32-bit clients */
518 @@ -3482,8 +3484,21 @@
519      pte_t *pte = NULL;
520      NvU64 retval;
521  
522 -    mm = (kern) ? &init_mm : current->mm;
523 -    if (!kern) down_read(&current->mm->mmap_sem);
524 +    if (!kern)
525 +    {
526 +        mm = current->mm;
527 +        down_read(&mm->mmap_sem);
528 +    }
529 +    else
530 +    {
531 +#if defined(NV_SET_PAGES_UC_PRESENT) && defined(NVCPU_X86)
532 +        /* nv_printf(NV_DBG_ERRORS,
533 +            "NVRM: can't translate KVA in nv_get_phys_address()!\n"); */
534 +        return 0;
535 +#else
536 +        mm = NULL;
537 +#endif
538 +    }
539  
540      pgd = NV_PGD_OFFSET(address, kern, mm);
541      if (!NV_PGD_PRESENT(pgd))
542 @@ -3504,22 +3519,24 @@
543      retval &= ~_PAGE_NX;
544  #endif
545  
546 -    if (!kern) up_read(&current->mm->mmap_sem);
547 +    if (!kern)
548 +        up_read(&mm->mmap_sem);
549      return retval;
550  
551  failed:
552 -    if (!kern) up_read(&current->mm->mmap_sem);
553 +    if (!kern)
554 +        up_read(&mm->mmap_sem);
555      return 0;
556  }
557  
558  NvU64 NV_API_CALL nv_get_kern_phys_address(NvU64 address)
559  {
560 -    // make sure this address is a kernel pointer
561 +    /* make sure this address is a kernel virtual address */
562  #if defined(DEBUG) && !defined(CONFIG_X86_4G)
563      if (address < PAGE_OFFSET)
564      {
565          nv_printf(NV_DBG_WARNINGS,
566 -            "NVRM: user address passed to get_kern_phys_address: 0x%lx\n",
567 +            "NVRM: user address passed to get_kern_phys_address: 0x%llx!\n",
568              address);
569          return 0;
570      }
571 @@ -3534,12 +3551,12 @@
572  
573  NvU64 NV_API_CALL nv_get_kern_user_address(NvU64 address)
574  {
575 -    // make sure this address is not a kernel pointer
576 +    /* make sure this address is not a kernel virtual address */
577  #if defined(DEBUG) && !defined(CONFIG_X86_4G)
578      if (address >= PAGE_OFFSET)
579      {
580          nv_printf(NV_DBG_WARNINGS,
581 -            "NVRM: kernel address passed to get_user_phys_address: 0x%lx\n",
582 +            "NVRM: kernel address passed to get_user_phys_address: 0x%llx!\n",
583              address);
584          return 0;
585      }
586 @@ -4316,16 +4333,12 @@
587      return -1;
588  }
589  
590 -int NV_API_CALL nv_no_incoherent_mappings
591 -(
592 -    void
593 -)
594 +int NV_API_CALL nv_no_incoherent_mappings(void)
595  {
596      if(nv_ext_no_incoherent_mappings() == 1)
597          return 1;
598 -
599 -#if defined(NV_CHANGE_PAGE_ATTR_PRESENT)
600 -    return 1;
601 +#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) || defined(NV_SET_PAGES_UC_PRESENT)
602 +    return (nv_update_memory_types);
603  #else
604      return 0;
605  #endif
606 diff -ru usr/src/nv/os-interface.c usr/src/nv.2286310/os-interface.c
607 --- usr/src/nv/os-interface.c   2008-03-16 14:13:09.000000000 -0700
608 +++ usr/src/nv.2286310/os-interface.c   2008-03-16 14:37:47.208131723 -0700
609 @@ -1198,6 +1198,18 @@
610  {
611      void *vaddr;
612  
613 +    if (start == 0)
614 +    {
615 +        if (mode != NV_MEMORY_CACHED)
616 +        {
617 +            nv_printf(NV_DBG_ERRORS,
618 +                "NVRM: os_map_kernel_space: won't map address 0x%0llx UC!\n", start);
619 +            return NULL;
620 +        }
621 +        else
622 +            return (void *)PAGE_OFFSET;
623 +    }
624 +
625      if (!NV_MAY_SLEEP())
626      {
627          nv_printf(NV_DBG_ERRORS,
628 @@ -1230,6 +1242,9 @@
629      NvU64 size_bytes
630  )
631  {
632 +    if (addr == (void *)PAGE_OFFSET)
633 +        return;
634 +
635      NV_IOUNMAP(addr, size_bytes);
636  }
637  
This page took 0.16335 seconds and 2 git commands to generate.