Index: linux-2.6.18-mm3/include/asm-ia64/page.h =================================================================== --- linux-2.6.18-mm3.orig/include/asm-ia64/page.h 2006-10-08 18:30:12.454578641 -0700 +++ linux-2.6.18-mm3/include/asm-ia64/page.h 2006-10-08 21:39:27.233245035 -0700 @@ -53,11 +53,7 @@ #ifdef CONFIG_HUGETLB_PAGE # define HPAGE_REGION_BASE RGN_BASE(RGN_HPAGE) # define HPAGE_SHIFT hpage_shift -#ifdef CONFIG_VIRTUAL_MEM_MAP_HUGE -# define HPAGE_SHIFT_DEFAULT 20 /* Reduce memory overhead for virtual mem_map */ -#else # define HPAGE_SHIFT_DEFAULT 28 /* check ia64 SDM for architecture supported size */ -#endif # define HPAGE_SIZE (__IA64_UL_CONST(1) << HPAGE_SHIFT) # define HPAGE_MASK (~(HPAGE_SIZE - 1)) @@ -115,14 +111,15 @@ do { \ #ifdef CONFIG_VIRTUAL_MEM_MAP_HUGE /* - * Use huge pages for the virtual memory map. Since we have separate - * huge page region we can use the whole range and leave VMALLOC - * untouched. + * Use huge pages for the virtual memory map. We place the virtual + * addresses beyond RGN_MAP_LIMIT in order to be able to distinguish + * between user space and kernel access to the huge area. */ #define VIRTUAL_MEM_MAP_REGION RGN_HPAGE -#define VIRTUAL_MEM_MAP RGN_BASE(VIRTUAL_MEM_MAP_REGION) +#define VIRTUAL_MEM_MAP RGN_BASE(VIRTUAL_MEM_MAP_REGION) + RGN_MAP_LIMIT #define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL) - +#define VIRTUAL_MEM_MAP_PAGE_SHIFT 20 +#define VIRTUAL_MEM_MAP_PAGE_SIZE (1UL << 20) #else /* * Place the virtual memory map in the VMALLOC area reducing the @@ -130,7 +127,11 @@ do { \ */ #define VIRTUAL_MEM_MAP_REGION RGN_GATE #define VIRTUAL_MEM_MAP (RGN_BASE(VIRTUAL_MEM_MAP_REGION) + 0x200000000UL) +#define VIRTUAL_MEM_MAP_PAGE_SHIFT PAGE_SHIFT +#define VIRTUAL_MEM_MAP_PAGE_SIZE PAGE_SIZE +#define #define VMALLOC_START (VIRTUAL_MEM_MAP + VIRTUAL_MEM_MAP_SIZE) + #endif #define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9))) Index: linux-2.6.18-mm3/arch/ia64/kernel/ivt.S =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/kernel/ivt.S 2006-10-08 21:20:40.515623500 -0700 +++ linux-2.6.18-mm3/arch/ia64/kernel/ivt.S 2006-10-08 21:39:27.238127546 -0700 @@ -433,13 +433,17 @@ ENTRY(nested_dtlb_miss) mov r19=IA64_KR(PT_BASE) // get the page table base address shl r21=r16,3 // shift bit 60 into sign bit mov r18=cr.itir +(p9) tbit.nz p9,p0=r16,IA64_RGN_MAP_SHIFT // Check for virtual MMAP flag set shr.u r17=r16,61 // get the region number into r17 ;; cmp.eq p6,p7=5,r17 // kernel region? - cmp.eq p9,p0=4,r17 // select other pgd for vmmap huge region? extr.u r18=r18,2,6 // get the faulting page size +(p9) cmp.eq p9,p0=4,r17 // Clear mmap flag if not region 4 ;; -(p7) cmp.eq p6,p7=4,r17 // huge region switches processing +(p9) mov r18=VIRTUAL_MEM_MAP_PAGE_SHIFT // Override page size +(p9) mov cr.itir=r18 // Reset Page size + ;; +(p9) cmp.eq p6,p7=4,r17 // May need to switch to kernel style processing add r22=-PAGE_SHIFT,r18 // page order add r18=PGDIR_SHIFT-PAGE_SHIFT+3,r18 // Calculate shift to get to nr of pgd ;; @@ -457,13 +461,14 @@ ENTRY(nested_dtlb_miss) ;; (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5 (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4] - cmp.eq p7,p6=0,r21 // unused address bits all zeroes? + cmp.eq p7,p6=r0,r21 // unused address bits all zeroes? #ifdef CONFIG_PGTABLE_4 shr.u r18=r22,PUD_SHIFT // shift pud index into position #else shr.u r18=r22,PMD_SHIFT // shift pmd index into position #endif ;; +(p9) cmp.eq p7,p6=1,r21 // For the virtual memmap case it must be 1 ld8 r17=[r17] // get *pgd (may be 0) ;; (p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL? Index: linux-2.6.18-mm3/arch/ia64/kernel/asm-offsets.c =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/kernel/asm-offsets.c 2006-10-06 18:11:41.094742499 -0700 +++ linux-2.6.18-mm3/arch/ia64/kernel/asm-offsets.c 2006-10-08 21:39:27.245939564 -0700 @@ -268,4 +268,7 @@ void foo(void) DEFINE(IA64_TIME_SOURCE_MMIO64, TIME_SOURCE_MMIO64); DEFINE(IA64_TIME_SOURCE_MMIO32, TIME_SOURCE_MMIO32); DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec)); + BLANK(); + + DEFINE(IA64_RGN_MAP_SHIFT, RGN_MAP_SHIFT); }