Index: linux-2.6.18-mm3/arch/ia64/kernel/ivt.S =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/kernel/ivt.S 2006-10-09 17:00:39.948917253 -0700 +++ linux-2.6.18-mm3/arch/ia64/kernel/ivt.S 2006-10-09 17:04:27.614562242 -0700 @@ -430,13 +430,17 @@ ENTRY(nested_dtlb_miss) shl r21=r16,3 // shift bit 60 into sign bit mov r18=cr.itir shr.u r17=r16,61 // get the region number into r17 + movl r22=(1 << (PGDIR_SHIFT+PAGE_SHIFT))// End of mappable space ;; cmp.eq p6,p7=5,r17 // is faulting address in region 5? + cmp.gt p9,p0=r21,r22 // Above mappable space +(p9) br.cond.spnt vary_pagesize // If the higher bits were set check ;; extr.u r18=r18,2,6 // get the faulting page size srlz.d LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir ;; +nested_dtlb: add r22=-PAGE_SHIFT,r18 // adjustment for hugetlb address add r18=PGDIR_SHIFT-PAGE_SHIFT+3,r18 ;; @@ -480,6 +484,50 @@ ENTRY(nested_dtlb_miss) br.sptk.many b0 // return to continuation point END(nested_dtlb_miss) + // We vary the page size depending on the 3 bits above those + // used for the mapping. + // + // The following page sizes are possible. Each supports a 128TB of + // address spaces + // + // PS-Bits Pagesize + // 0 + // 1 256k + // 2 1M + // 3 4M + // 4 16M + // 5 64M + // 6 256M + // 7 1GB + // + // Input + // r18 = ITIR + // Output + // r18 = page size + // +ENTRY(vary_pagesize) + cmp.eq p6,p7=4,r17 // Huge region? +(p7) br.cond.spnt page_fault // Hmm... illegal address... + ;; + mov r21=16 // +2 is first large page size + extr r22=r16,(PGDIR_SHIFT-PAGE_SHIFT-3),3 // Get page size bits + srlz.d + LOAD_PHYSICAL(p0, r19, memmap_pg_dir) + ;; + dep r16=0,r16,(PGDIR_SHIFT-PAGE_SHIFT-3),3 // Clear page size bits in r16 + dep r19=r22,r19,PAGE_SHIFT,3 // Use our subsection of pgd + ;; + shladd r22=r22,1,r21 // Calculate page size + ;; + dep r18=r22,r18,2,6 // Fix up itir + ;; + mov cr.itir=r18 // Set new page size + ;; + mov r18=r22; // r18 must have page size on return + shl r21=r16,3 // realign r21. + br.cond.spnt.many nested_dtlb // Continue +END(vary_pagesize) + .org ia64_ivt+0x1800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) Index: linux-2.6.18-mm3/arch/ia64/kernel/vmlinux.lds.S =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/kernel/vmlinux.lds.S 2006-10-07 16:07:33.962941756 -0700 +++ linux-2.6.18-mm3/arch/ia64/kernel/vmlinux.lds.S 2006-10-09 17:23:04.242962706 -0700 @@ -152,9 +152,9 @@ SECTIONS __end___mckinley_e9_bundles = .; } + . = ALIGN(16); #if defined(CONFIG_IA64_GENERIC) /* Machine Vector */ - . = ALIGN(16); .machvec : AT(ADDR(.machvec) - LOAD_OFFSET) { machvec_start = .; Index: linux-2.6.18-mm3/arch/ia64/kernel/vmlinux.lds =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/kernel/vmlinux.lds 2006-10-09 13:32:53.248903397 -0700 +++ linux-2.6.18-mm3/arch/ia64/kernel/vmlinux.lds 2006-10-09 17:23:11.856751041 -0700 @@ -547,6 +547,8 @@ SECTIONS *(.data.patch.mckinley_e9) __end___mckinley_e9_bundles = .; } + + . = ALIGN(16); __con_initcall_start = .; .con_initcall.init : AT(ADDR(.con_initcall.init) - (((5<<(61))+0x100000000) - (1 << 26))) { *(.con_initcall.init) }