+++ /dev/null
-diff -ru usr/src/nv/nv-linux.h usr/src/nv.1258475/nv-linux.h
---- usr/src/nv/nv-linux.h 2005-03-22 16:19:09.000000000 +0100
-+++ usr/src/nv.1258475/nv-linux.h 2005-05-05 19:06:45.237118320 +0200
-@@ -200,7 +200,6 @@
- */
- #if defined(CONFIG_SWIOTLB)
- #define NV_SWIOTLB 1
--#define NV_SWIOTLB_MAX_RETRIES 16
- extern int nv_swiotlb;
- #endif
-
-@@ -1053,6 +1052,31 @@
- }
-
- #if defined(NV_SG_MAP_BUFFERS)
-+
-+static inline int nv_map_sg(struct pci_dev *dev, struct scatterlist *sg)
-+ {
-+ int ret;
-+#if defined(KERNEL_2_6) && defined(CONFIG_SWIOTLB)
-+ if (swiotlb)
-+ ret = swiotlb_map_sg(&dev->dev, sg, 1, PCI_DMA_BIDIRECTIONAL);
-+ else
-+#endif
-+ ret = pci_map_sg(dev, sg, 1, PCI_DMA_BIDIRECTIONAL);
-+ return ret;
-+ }
-+
-+static inline void nv_unmap_sg(struct pci_dev *dev, struct scatterlist *sg)
-+ {
-+#if defined(KERNEL_2_6) && defined(CONFIG_SWIOTLB)
-+ if (swiotlb)
-+ swiotlb_unmap_sg(&dev->dev, sg, 1, PCI_DMA_BIDIRECTIONAL);
-+ else
-+#endif
-+ pci_unmap_sg(dev, sg, 1, PCI_DMA_BIDIRECTIONAL);
-+ }
-+
-+#define NV_MAP_SG_MAX_RETRIES 16
-+
- static inline int nv_sg_map_buffer(
- struct pci_dev *dev,
- nv_pte_t **page_list,
-@@ -1067,50 +1091,42 @@
- sg_ptr->offset = (unsigned long)base & ~PAGE_MASK;
- sg_ptr->length = num_pages * PAGE_SIZE;
-
--#if defined(NV_SWIOTLB)
-- i = NV_SWIOTLB_MAX_RETRIES;
-+ i = NV_MAP_SG_MAX_RETRIES;
- do {
-- if (pci_map_sg(dev, sg_ptr, 1, PCI_DMA_BIDIRECTIONAL) == 0)
-+ if (nv_map_sg(dev, sg_ptr) == 0)
- return 1;
-
- if (sg_ptr->dma_address & ~PAGE_MASK)
- {
- struct scatterlist sg_tmp;
-- pci_unmap_sg(dev, sg_ptr, num_pages, PCI_DMA_BIDIRECTIONAL);
-+ nv_unmap_sg(dev, sg_ptr);
-
- memset(&sg_tmp, 0, sizeof(struct scatterlist));
- sg_tmp.page = sg_ptr->page;
- sg_tmp.offset = sg_ptr->offset;
- sg_tmp.length = 2048;
-
-- if (pci_map_sg(dev, &sg_tmp, 1, PCI_DMA_BIDIRECTIONAL) == 0)
-+ if (nv_map_sg(dev, &sg_tmp) == 0)
- return 1;
-
-- if (pci_map_sg(dev, sg_ptr, 1, PCI_DMA_BIDIRECTIONAL) == 0)
-+ if (nv_map_sg(dev, sg_ptr) == 0)
- {
-- pci_unmap_sg(dev, &sg_tmp, num_pages, PCI_DMA_BIDIRECTIONAL);
-+ nv_unmap_sg(dev, &sg_tmp);
- return 1;
- }
-
-- pci_unmap_sg(dev, &sg_tmp, num_pages, PCI_DMA_BIDIRECTIONAL);
-+ nv_unmap_sg(dev, &sg_tmp);
- }
- } while (i-- && sg_ptr->dma_address & ~PAGE_MASK);
--#else
-- if (pci_map_sg(dev, sg_ptr, 1, PCI_DMA_BIDIRECTIONAL) == 0)
-- {
-- return 1;
-- }
--#endif
-
- if (sg_ptr->dma_address & ~PAGE_MASK)
- {
- nv_printf(NV_DBG_ERRORS,
- "NVRM: VM: nv_sg_map_buffer: failed to obtain aligned mapping\n");
-- pci_unmap_sg(dev, sg_ptr, num_pages, PCI_DMA_BIDIRECTIONAL);
-+ nv_unmap_sg(dev, sg_ptr);
- return 1;
- }
-
-- NV_FIXUP_SWIOTLB_VIRT_ADDR_BUG(sg_ptr->dma_address);
-
- // this is a bit of a hack to make contiguous allocations easier to handle
- // nv_sg_load below relies on the page_ptr addresses being filed in, as
-@@ -1139,6 +1155,9 @@
- // wire in the new page's addresses, but save the original off to free later
- if (nv_swiotlb)
- {
-+ // note that we modify our local version, not the sg_ptr version that
-+ // will be returned to the swiotlb pool
-+ NV_FIXUP_SWIOTLB_VIRT_ADDR_BUG(page_ptr->dma_addr);
- page_ptr->orig_phys_addr = page_ptr->phys_addr;
- page_ptr->phys_addr = page_ptr->dma_addr;
- page_ptr->orig_virt_addr = page_ptr->virt_addr;
-@@ -1171,7 +1190,7 @@
-
- if (page_ptr->dma_addr != page_ptr->phys_addr)
- {
-- pci_unmap_sg(dev, sg_ptr, 1, PCI_DMA_BIDIRECTIONAL);
-+ nv_unmap_sg(dev, sg_ptr);
- page_ptr->dma_addr = 0;
- }
- }
+++ /dev/null
-diff -ru usr/src/nv/nv-linux.h usr/src/nv.1296092/nv-linux.h
---- usr/src/nv/nv-linux.h 2005-03-22 16:19:09.000000000 +0100
-+++ usr/src/nv.1296092/nv-linux.h 2005-06-14 16:55:30.416687848 +0200
-@@ -76,7 +76,7 @@
- #include <asm/page.h> /* PAGE_OFFSET */
- #include <asm/pgtable.h> /* pte bit definitions */
-
--#if defined(NVCPU_X86_64) && defined(KERNEL_2_6)
-+#if defined(NVCPU_X86_64) && defined(KERNEL_2_6) && !defined(HAVE_COMPAT_IOCTL)
- #include <linux/syscalls.h> /* sys_ioctl() */
- #include <linux/ioctl32.h> /* register_ioctl32_conversion() */
- #endif
-diff -ru usr/src/nv/nv.c usr/src/nv.1296092/nv.c
---- usr/src/nv/nv.c 2005-03-22 16:19:09.000000000 +0100
-+++ usr/src/nv.1296092/nv.c 2005-06-14 16:55:16.745766144 +0200
-@@ -153,6 +153,7 @@
- int nv_kern_mmap(struct file *, struct vm_area_struct *);
- unsigned int nv_kern_poll(struct file *, poll_table *);
- int nv_kern_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-+long nv_kern_compat_ioctl(struct file *, unsigned int, unsigned long);
- void nv_kern_isr_bh(unsigned long);
- irqreturn_t nv_kern_isr(int, void *, struct pt_regs *);
- void nv_kern_rc_timer(unsigned long);
-@@ -209,6 +210,9 @@
- .owner = THIS_MODULE,
- .poll = nv_kern_poll,
- .ioctl = nv_kern_ioctl,
-+#if defined(NVCPU_X86_64) && defined(HAVE_COMPAT_IOCTL)
-+ .compat_ioctl = nv_kern_compat_ioctl,
-+#endif
- .mmap = nv_kern_mmap,
- .open = nv_kern_open,
- .release = nv_kern_close,
-@@ -993,8 +997,10 @@
- inter_module_register("nv_linux_devices", THIS_MODULE, nv_linux_devices);
- #endif
-
-+#if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION) && !defined(HAVE_COMPAT_IOCTL)
- /* Register ioctl conversions for 32 bit clients */
- rm_register_ioctl_conversions();
-+#endif
-
- #ifdef NV_SWIOTLB
- // may need a better test than this eventually
-@@ -1154,8 +1160,10 @@
- #endif
- }
-
-+#if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION) && !defined(HAVE_COMPAT_IOCTL)
- /* Unregister ioctl conversions for 32 bit clients */
- rm_unregister_ioctl_conversions();
-+#endif
-
- #if defined(NV_BUILD_NV_PAT_SUPPORT)
- if (nv_pat_enabled)
-@@ -1930,6 +1938,15 @@
- return status;
- }
-
-+long nv_kern_compat_ioctl(
-+ struct file *file,
-+ unsigned int cmd,
-+ unsigned long i_arg
-+)
-+{
-+ return nv_kern_ioctl(file->f_dentry->d_inode, file, cmd, i_arg);
-+}
-+
- /*
- * driver receives an interrupt
- * if someone waiting, then hand it off.
-diff -ru usr/src/nv/os-interface.c usr/src/nv.1296092/os-interface.c
---- usr/src/nv/os-interface.c 2005-03-22 16:19:09.000000000 +0100
-+++ usr/src/nv.1296092/os-interface.c 2005-06-14 16:55:21.366063752 +0200
-@@ -1227,18 +1227,18 @@
-
- void NV_API_CALL os_register_ioctl32_conversion(U032 cmd, U032 size)
- {
--#if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION)
-+#if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION) && !defined(HAVE_COMPAT_IOCTL)
- unsigned int request = _IOWR(NV_IOCTL_MAGIC, cmd, char[size]);
- register_ioctl32_conversion(request, (void *)sys_ioctl);
--#endif /* NVCPU_X86_64 */
-+#endif
- }
-
- void NV_API_CALL os_unregister_ioctl32_conversion(U032 cmd, U032 size)
- {
--#if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION)
-+#if defined(NVCPU_X86_64) && defined(CONFIG_IA32_EMULATION) && !defined(HAVE_COMPAT_IOCTL)
- unsigned int request = _IOWR(NV_IOCTL_MAGIC, cmd, char[size]);
- unregister_ioctl32_conversion(request);
--#endif /* NVCPU_X86_64 */
-+#endif
- }
-
- BOOL NV_API_CALL os_pat_supported(void)
+++ /dev/null
-diff -ru usr/src/nv/nv-vm.c usr/src/nv.1321905/nv-vm.c
---- usr/src/nv/nv-vm.c 2005-03-22 16:19:09.000000000 +0100
-+++ usr/src/nv.1321905/nv-vm.c 2005-10-23 15:43:12.860170440 +0200
-@@ -248,6 +248,20 @@
- /* lock the page for dma purposes */
- SetPageReserved(NV_GET_PAGE_STRUCT(phys_addr));
-
-+#if defined(_PAGE_NX)
-+ if ((_PAGE_NX & pgprot_val(PAGE_KERNEL)) != 0 && phys_addr < 0x400000) {
-+ // Until a bug in change_page_attr() is fixed
-+ // we avoid pages with physaddr < 0x400000,
-+ // since splitting "jumbo" mappings results
-+ // in kernel pages being mapped as PAGE_KERNEL, which
-+ // may include _PAGE_NX, effectively making much of the
-+ // kernel code non-executable.
-+ nv_printf(NV_DBG_MEMINFO, "NVRM: nv_vm_malloc discarding page @%08x\n", phys_addr);
-+ --i;
-+ continue;
-+ }
-+#endif
-+
- page_ptr = at->page_table[i];
- page_ptr->phys_addr = phys_addr;
- page_ptr->virt_addr = virt_addr;
+++ /dev/null
-diff -ru usr/src/nv/nv-linux.h usr/src/nv.1361053/nv-linux.h
---- usr/src/nv/nv-linux.h 2005-03-22 16:19:09.000000000 +0100
-+++ usr/src/nv.1361053/nv-linux.h 2005-10-11 19:01:57.647002680 +0200
-@@ -1018,15 +1018,50 @@
- #define NV_CHANGE_PAGE_ATTR_BUG_PRESENT 1
- #endif
-
-+#if defined(NVCPU_X86) || defined(NVCPU_X86_64)
-+/*
-+ * On Linux/x86-64 (and recent Linux/x86) kernels, the PAGE_KERNEL
-+ * and PAGE_KERNEL_NOCACHE protection bit masks include _PAGE_NX
-+ * to indicate that the no-execute protection page feature is used
-+ * for the page in question.
-+ *
-+ * We need to be careful to mask out _PAGE_NX when the host system
-+ * doesn't support this feature or when it's disabled: the kernel
-+ * may not do this in its implementation of the change_page_attr()
-+ * interface.
-+ */
-+#ifndef X86_FEATURE_NX
-+#define X86_FEATURE_NX (1*32+20)
-+#endif
-+#ifndef boot_cpu_has
-+#define boot_cpu_has(x) test_bit(x, boot_cpu_data.x86_capability)
-+#endif
-+#ifndef MSR_EFER
-+#define MSR_EFER 0xc0000080
-+#endif
-+#ifndef EFER_NX
-+#define EFER_NX (1 << 11)
-+#endif
-+#ifndef _PAGE_NX
-+#define _PAGE_NX ((NvU64)1 << 63)
-+#endif
-+extern NvU64 __nv_supported_pte_mask;
-+#endif
-+
- #if defined(NV_CHANGE_PAGE_ATTR_PRESENT) && !defined(NV_CHANGE_PAGE_ATTR_BUG_PRESENT)
- static inline void NV_SET_PAGE_ATTRIB_UNCACHED(nv_pte_t *page_ptr)
- {
- struct page *page = virt_to_page(__va(page_ptr->phys_addr));
-- change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
-+ pgprot_t prot = PAGE_KERNEL_NOCACHE;
-+#if defined(NVCPU_X86) || defined(NVCPU_X86_64)
-+ pgprot_val(prot) &= __nv_supported_pte_mask;
-+#endif
-+ change_page_attr(page, 1, prot);
- }
- static inline void NV_SET_PAGE_ATTRIB_CACHED(nv_pte_t *page_ptr)
- {
- struct page *page = virt_to_page(__va(page_ptr->phys_addr));
-+ pgprot_t prot = PAGE_KERNEL;
- #ifdef CONFIG_SWIOTLB
- if (page_ptr->orig_phys_addr)
- {
-@@ -1034,7 +1069,10 @@
- os_dbg_breakpoint();
- }
- #endif
-- change_page_attr(page, 1, PAGE_KERNEL);
-+#if defined(NVCPU_X86) || defined(NVCPU_X86_64)
-+ pgprot_val(prot) &= __nv_supported_pte_mask;
-+#endif
-+ change_page_attr(page, 1, prot);
- }
- #else
- #define NV_SET_PAGE_ATTRIB_UNCACHED(page_list)
-diff -ru usr/src/nv/nv.c usr/src/nv.1361053/nv.c
---- usr/src/nv/nv.c 2005-03-22 16:19:09.000000000 +0100
-+++ usr/src/nv.1361053/nv.c 2005-10-11 18:59:20.347915776 +0200
-@@ -38,6 +38,10 @@
- static int nv_disable_pat = 0;
- NV_MODULE_PARAMETER(nv_disable_pat);
-
-+#if defined(NVCPU_X86) || defined(NVCPU_X86_64)
-+NvU64 __nv_supported_pte_mask = ~_PAGE_NX;
-+#endif
-+
- /*
- * And one for the control device
- */
-@@ -1024,6 +1028,16 @@
- __nv_enable_pat_support();
- }
- #endif
-+
-+#if defined(NVCPU_X86_64) || (defined(NVCPU_X86) && defined(CONFIG_X86_PAE))
-+ if (boot_cpu_has(X86_FEATURE_NX))
-+ {
-+ U032 __eax, __edx;
-+ rdmsr(MSR_EFER, __eax, __edx);
-+ if ((__eax & EFER_NX) != 0)
-+ __nv_supported_pte_mask |= _PAGE_NX;
-+ }
-+#endif
-
- return 0;
-
+++ /dev/null
-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