Index: linux-2.6.18-mm3/include/asm-ia64/page.h =================================================================== --- linux-2.6.18-mm3.orig/include/asm-ia64/page.h 2006-10-07 08:33:58.029715297 -0700 +++ linux-2.6.18-mm3/include/asm-ia64/page.h 2006-10-07 12:36:46.522174073 -0700 @@ -54,9 +54,11 @@ # define HPAGE_REGION_BASE RGN_BASE(RGN_HPAGE) # define HPAGE_SHIFT hpage_shift #ifdef CONFIG_VIRTUAL_MEM_MAP_HUGE -# define HPAGE_SHIFT_DEFAULT 24 /* Reduce memory overhead for virtual mem_map */ +# define HPAGE_SHIFT_DEFAULT 20 /* Reduce memory overhead for virtual mem_map */ +# define VIRTUAL_MEM_MAP_REGION RGN_HPAGE #else # define HPAGE_SHIFT_DEFAULT 28 /* check ia64 SDM for architecture supported size */ +# define VIRTUAL_MEM_MAP_REGION RGN_GATE #endif # define HPAGE_SIZE (__IA64_UL_CONST(1) << HPAGE_SHIFT) # define HPAGE_MASK (~(HPAGE_SIZE - 1)) @@ -113,27 +115,17 @@ do { \ #define VIRTUAL_MEM_MAP_SIZE (1UL << (IA64_MAX_PHYS_BITS - PAGE_SHIFT +\ STRUCT_PAGE_ORDER)) -#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. - */ -#define VIRTUAL_MEM_MAP_REGION RGN_HPAGE -#define VIRTUAL_MEM_MAP RGN_BASE(VIRTUAL_MEM_MAP_REGION) #define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL) - -#else /* * Place the virtual memory map in the VMALLOC area reducing the * available address space of 128 TB by 8 TB. */ -#define VIRTUAL_MEM_MAP_REGION RGN_GATE -#define VIRTUAL_MEM_MAP (RGN_BASE(VIRTUAL_MEM_MAP_REGION) + 0x200000000UL) -#define VMALLOC_START (VIRTUAL_MEM_MAP + VIRTUAL_MEM_MAP_SIZE) -#endif +#define VMALLOC_END_OFFSET ((1UL << (4*PAGE_SHIFT - 9)) - VIRTUAL_MEM_MAP_SIZE) + +#define VMALLOC_END (RGN_BASE(RGN_GATE) + VMALLOC_END_OFFSET) -#define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9))) +#define VIRTUAL_MEM_MAP (RGN_BASE(VIRTUAL_MEM_MAP_REGION) + \ + VMALLOC_END_OFFSET) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) Index: linux-2.6.18-mm3/arch/ia64/mm/fault.c =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/mm/fault.c 2006-10-06 22:18:22.880147125 -0700 +++ linux-2.6.18-mm3/arch/ia64/mm/fault.c 2006-10-07 13:37:30.331948714 -0700 @@ -53,6 +53,11 @@ static inline int notify_page_fault(enum } #endif +static int is_virtual_mem_map(unsigned long address) +{ + return REGION_NUMBER(address) == VIRTUAL_MEM_MAP_REGION && + address >= VIRTUAL_MEM_MAP; +} /* * Return TRUE if ADDRESS points at a page in the kernel's mapped segment * (inside region 5, on ia64) and that page is present. @@ -65,6 +70,14 @@ mapped_kernel_page_is_present (unsigned pmd_t *pmd; pte_t *ptep, pte; + printk("mapped_kernel_page_is_present(%lx)\n", address); + if (is_virtual_mem_map(address) && + REGION_NUMBER(address) == RGN_HPAGE) { + /* Need to make sure that we look up the right pte */ + address &= HPAGE_MASK; + printk("fixed up huge page address=%lx\n",address); + } + pgd = pgd_offset_k(address); if (pgd_none(*pgd) || pgd_bad(*pgd)) return 0; @@ -94,6 +107,9 @@ ia64_do_page_fault (unsigned long addres struct siginfo si; unsigned long mask; + printk("ia64_do_page_fault(%lx, %lx,) atomic=%d mm=%lx user_mode=%d\n", address, isr, + in_atomic(), mm, user_mode(regs)); + /* mmap_sem is performance critical.... */ prefetchw(&mm->mmap_sem); @@ -112,7 +128,7 @@ ia64_do_page_fault (unsigned long addres * code. */ - if ((REGION_NUMBER(address) == VIRTUAL_MEM_MAP_REGION) && !user_mode(regs)) + if (is_virtual_mem_map(address) && !user_mode(regs)) goto bad_area_no_up; #endif @@ -257,8 +273,9 @@ ia64_do_page_fault (unsigned long addres * translation, which fixed the problem. So, we check to see if the translation is * valid, and return if it is. */ - if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address)) - return; + if ((REGION_NUMBER(address) == RGN_GATE || is_virtual_mem_map(address)) + && mapped_kernel_page_is_present(address)) + return; if (ia64_done_with_exception(regs)) return; Index: linux-2.6.18-mm3/arch/ia64/kernel/ivt.S =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/kernel/ivt.S 2006-10-07 11:36:55.058719426 -0700 +++ linux-2.6.18-mm3/arch/ia64/kernel/ivt.S 2006-10-07 15:40:56.303509876 -0700 @@ -103,31 +103,29 @@ ENTRY(vhpt_miss) * - the faulting virtual address has no valid page table mapping */ mov r16=cr.ifa // get address that caused the TLB miss -#ifdef CONFIG_HUGETLB_PAGE movl r18=PAGE_SHIFT mov r25=cr.itir -#endif + movl r28=IA64_VIRTUAL_MEM_MAP ;; rsm psr.dt // use physical addressing for data mov r31=pr // save the predicate registers - mov r19=IA64_KR(PT_BASE) // get page table base address shl r21=r16,3 // shift bit 60 into sign bit + mov r19=IA64_KR(PT_BASE) // get page table base address shr.u r17=r16,61 // get the region number into r17 ;; shr.u r22=r21,3 -#ifdef CONFIG_HUGETLB_PAGE + cmp.eq p6,p7=RGN_GATE,r17 // is IFA pointing into to kernel region? extr.u r26=r25,2,6 ;; +(p7) cmp.eq.unc p9,p0=VIRTUAL_MEM_MAP_REGION,r17 // Is IFA pointing to vmm region? cmp.ne p8,p0=r18,r26 sub r27=r26,r18 ;; (p8) dep r25=r18,r25,2,6 (p8) shr r22=r22,r27 -#endif +(p9) cmp.ltu p6,p7=r28,r16 // Address > VIRTUAL_MEM_MAP ? ;; - cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? shr.u r18=r22,PGDIR_SHIFT // get bottom portion of pgd index bit - ;; (p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place srlz.d @@ -375,7 +373,6 @@ ENTRY(alt_dtlb_miss) mov r21=cr.ipsr mov r31=pr ;; -#ifdef CONFIG_DISABLE_VHPT shr.u r22=r16,61 // get the region number into r21 ;; cmp.gt p8,p0=6,r22 // access to region 0-5 @@ -385,7 +382,6 @@ ENTRY(alt_dtlb_miss) (p8) mov cr.iha=r17 (p8) mov r29=b0 // save b0 (p8) br.cond.dptk dtlb_fault -#endif extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? 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-07 12:55:50.712473456 -0700 @@ -13,6 +13,7 @@ #include #include #include +#include #include "../kernel/sigframe.h" @@ -268,4 +269,10 @@ 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(); +#ifdef CONFIG_VIRTUAL_MEM_MAP_HUGE + DEFINE(IA64_VIRTUAL_MEM_MAP, VIRTUAL_MEM_MAP); +#else + DEFINE(IA64_VIRTUAL_MEM_MAP, -1ULL); +#endif }