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;