Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'parisc-4.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc update from Helge Deller:
"This patchset adds Huge Page and HUGETLBFS support for parisc"

Honestly, the hugepage support should have gone through in the merge
window, and is not really an rc-time fix. But it only touches
arch/parisc, and I cannot find it in myself to care. If one of the
three parisc users notices a breakage, I will point at Helge and make
rude farting noises.

* 'parisc-4.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: Map kernel text and data on huge pages
parisc: Add Huge Page and HUGETLBFS support
parisc: Use long branch to do_syscall_trace_exit
parisc: Increase initial kernel mapping to 32MB on 64bit kernel
parisc: Initialize the fault vector earlier in the boot process.
parisc: Add defines for Huge page support
parisc: Drop unused MADV_xxxK_PAGES flags from asm/mman.h
parisc: Drop definition of start_thread_som for HP-UX SOM binaries
parisc: Fix wrong comment regarding first pmd entry flags

+382 -116
+3
arch/parisc/Kconfig
··· 108 108 default 3 if 64BIT && PARISC_PAGE_SIZE_4KB 109 109 default 2 110 110 111 + config SYS_SUPPORTS_HUGETLBFS 112 + def_bool y if PA20 113 + 111 114 source "init/Kconfig" 112 115 113 116 source "kernel/Kconfig.freezer"
+85
arch/parisc/include/asm/hugetlb.h
··· 1 + #ifndef _ASM_PARISC64_HUGETLB_H 2 + #define _ASM_PARISC64_HUGETLB_H 3 + 4 + #include <asm/page.h> 5 + #include <asm-generic/hugetlb.h> 6 + 7 + 8 + void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, 9 + pte_t *ptep, pte_t pte); 10 + 11 + pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, 12 + pte_t *ptep); 13 + 14 + static inline int is_hugepage_only_range(struct mm_struct *mm, 15 + unsigned long addr, 16 + unsigned long len) { 17 + return 0; 18 + } 19 + 20 + /* 21 + * If the arch doesn't supply something else, assume that hugepage 22 + * size aligned regions are ok without further preparation. 23 + */ 24 + static inline int prepare_hugepage_range(struct file *file, 25 + unsigned long addr, unsigned long len) 26 + { 27 + if (len & ~HPAGE_MASK) 28 + return -EINVAL; 29 + if (addr & ~HPAGE_MASK) 30 + return -EINVAL; 31 + return 0; 32 + } 33 + 34 + static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb, 35 + unsigned long addr, unsigned long end, 36 + unsigned long floor, 37 + unsigned long ceiling) 38 + { 39 + free_pgd_range(tlb, addr, end, floor, ceiling); 40 + } 41 + 42 + static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, 43 + unsigned long addr, pte_t *ptep) 44 + { 45 + } 46 + 47 + static inline int huge_pte_none(pte_t pte) 48 + { 49 + return pte_none(pte); 50 + } 51 + 52 + static inline pte_t huge_pte_wrprotect(pte_t pte) 53 + { 54 + return pte_wrprotect(pte); 55 + } 56 + 57 + static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, 58 + unsigned long addr, pte_t *ptep) 59 + { 60 + pte_t old_pte = *ptep; 61 + set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); 62 + } 63 + 64 + static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, 65 + unsigned long addr, pte_t *ptep, 66 + pte_t pte, int dirty) 67 + { 68 + int changed = !pte_same(*ptep, pte); 69 + if (changed) { 70 + set_huge_pte_at(vma->vm_mm, addr, ptep, pte); 71 + flush_tlb_page(vma, addr); 72 + } 73 + return changed; 74 + } 75 + 76 + static inline pte_t huge_ptep_get(pte_t *ptep) 77 + { 78 + return *ptep; 79 + } 80 + 81 + static inline void arch_clear_hugepage_flags(struct page *page) 82 + { 83 + } 84 + 85 + #endif /* _ASM_PARISC64_HUGETLB_H */
+12 -1
arch/parisc/include/asm/page.h
··· 145 145 #endif /* CONFIG_DISCONTIGMEM */ 146 146 147 147 #ifdef CONFIG_HUGETLB_PAGE 148 - #define HPAGE_SHIFT 22 /* 4MB (is this fixed?) */ 148 + #define HPAGE_SHIFT PMD_SHIFT /* fixed for transparent huge pages */ 149 149 #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) 150 150 #define HPAGE_MASK (~(HPAGE_SIZE - 1)) 151 151 #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 152 + 153 + #if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB) 154 + # define REAL_HPAGE_SHIFT 20 /* 20 = 1MB */ 155 + # define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_1M 156 + #elif !defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB) 157 + # define REAL_HPAGE_SHIFT 22 /* 22 = 4MB */ 158 + # define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4M 159 + #else 160 + # define REAL_HPAGE_SHIFT 24 /* 24 = 16MB */ 161 + # define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_16M 152 162 #endif 163 + #endif /* CONFIG_HUGETLB_PAGE */ 153 164 154 165 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 155 166
+1 -1
arch/parisc/include/asm/pgalloc.h
··· 35 35 PxD_FLAG_VALID | 36 36 PxD_FLAG_ATTACHED) 37 37 + (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT)); 38 - /* The first pmd entry also is marked with _PAGE_GATEWAY as 38 + /* The first pmd entry also is marked with PxD_FLAG_ATTACHED as 39 39 * a signal that this pmd may not be freed */ 40 40 __pgd_val_set(*pgd, PxD_FLAG_ATTACHED); 41 41 #endif
+22 -4
arch/parisc/include/asm/pgtable.h
··· 83 83 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e)) 84 84 85 85 /* This is the size of the initially mapped kernel memory */ 86 - #define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */ 86 + #ifdef CONFIG_64BIT 87 + #define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */ 88 + #else 89 + #define KERNEL_INITIAL_ORDER 24 /* 1<<24 = 16MB */ 90 + #endif 87 91 #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) 88 92 89 93 #if CONFIG_PGTABLE_LEVELS == 3 ··· 171 167 #define _PAGE_NO_CACHE_BIT 24 /* (0x080) Uncached Page (U bit) */ 172 168 #define _PAGE_ACCESSED_BIT 23 /* (0x100) Software: Page Accessed */ 173 169 #define _PAGE_PRESENT_BIT 22 /* (0x200) Software: translation valid */ 174 - /* bit 21 was formerly the FLUSH bit but is now unused */ 170 + #define _PAGE_HPAGE_BIT 21 /* (0x400) Software: Huge Page */ 175 171 #define _PAGE_USER_BIT 20 /* (0x800) Software: User accessible page */ 176 172 177 173 /* N.B. The bits are defined in terms of a 32 bit word above, so the */ ··· 198 194 #define _PAGE_NO_CACHE (1 << xlate_pabit(_PAGE_NO_CACHE_BIT)) 199 195 #define _PAGE_ACCESSED (1 << xlate_pabit(_PAGE_ACCESSED_BIT)) 200 196 #define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT)) 197 + #define _PAGE_HUGE (1 << xlate_pabit(_PAGE_HPAGE_BIT)) 201 198 #define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT)) 202 199 203 200 #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED) ··· 222 217 #define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT)) 223 218 #define PxD_FLAG_MASK (0xf) 224 219 #define PxD_FLAG_SHIFT (4) 225 - #define PxD_VALUE_SHIFT (8) /* (PAGE_SHIFT-PxD_FLAG_SHIFT) */ 220 + #define PxD_VALUE_SHIFT (PFN_PTE_SHIFT-PxD_FLAG_SHIFT) 226 221 227 222 #ifndef __ASSEMBLY__ 228 223 ··· 368 363 static inline pte_t pte_mkspecial(pte_t pte) { return pte; } 369 364 370 365 /* 366 + * Huge pte definitions. 367 + */ 368 + #ifdef CONFIG_HUGETLB_PAGE 369 + #define pte_huge(pte) (pte_val(pte) & _PAGE_HUGE) 370 + #define pte_mkhuge(pte) (__pte(pte_val(pte) | _PAGE_HUGE)) 371 + #else 372 + #define pte_huge(pte) (0) 373 + #define pte_mkhuge(pte) (pte) 374 + #endif 375 + 376 + 377 + /* 371 378 * Conversion functions: convert a page and protection to a page entry, 372 379 * and a page entry and page directory to the page they refer to. 373 380 */ ··· 427 410 /* Find an entry in the second-level page table.. */ 428 411 429 412 #if CONFIG_PGTABLE_LEVELS == 3 413 + #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) 430 414 #define pmd_offset(dir,address) \ 431 - ((pmd_t *) pgd_page_vaddr(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1))) 415 + ((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(address)) 432 416 #else 433 417 #define pmd_offset(dir,addr) ((pmd_t *) dir) 434 418 #endif
-27
arch/parisc/include/asm/processor.h
··· 192 192 */ 193 193 typedef unsigned int elf_caddr_t; 194 194 195 - #define start_thread_som(regs, new_pc, new_sp) do { \ 196 - unsigned long *sp = (unsigned long *)new_sp; \ 197 - __u32 spaceid = (__u32)current->mm->context; \ 198 - unsigned long pc = (unsigned long)new_pc; \ 199 - /* offset pc for priv. level */ \ 200 - pc |= 3; \ 201 - \ 202 - regs->iasq[0] = spaceid; \ 203 - regs->iasq[1] = spaceid; \ 204 - regs->iaoq[0] = pc; \ 205 - regs->iaoq[1] = pc + 4; \ 206 - regs->sr[2] = LINUX_GATEWAY_SPACE; \ 207 - regs->sr[3] = 0xffff; \ 208 - regs->sr[4] = spaceid; \ 209 - regs->sr[5] = spaceid; \ 210 - regs->sr[6] = spaceid; \ 211 - regs->sr[7] = spaceid; \ 212 - regs->gr[ 0] = USER_PSW; \ 213 - regs->gr[30] = ((new_sp)+63)&~63; \ 214 - regs->gr[31] = pc; \ 215 - \ 216 - get_user(regs->gr[26],&sp[0]); \ 217 - get_user(regs->gr[25],&sp[-1]); \ 218 - get_user(regs->gr[24],&sp[-2]); \ 219 - get_user(regs->gr[23],&sp[-3]); \ 220 - } while(0) 221 - 222 195 /* The ELF abi wants things done a "wee bit" differently than 223 196 * som does. Supporting this behavior here avoids 224 197 * having our own version of create_elf_tables.
-10
arch/parisc/include/uapi/asm/mman.h
··· 49 49 #define MADV_DONTFORK 10 /* don't inherit across fork */ 50 50 #define MADV_DOFORK 11 /* do inherit across fork */ 51 51 52 - /* The range 12-64 is reserved for page size specification. */ 53 - #define MADV_4K_PAGES 12 /* Use 4K pages */ 54 - #define MADV_16K_PAGES 14 /* Use 16K pages */ 55 - #define MADV_64K_PAGES 16 /* Use 64K pages */ 56 - #define MADV_256K_PAGES 18 /* Use 256K pages */ 57 - #define MADV_1M_PAGES 20 /* Use 1 Megabyte pages */ 58 - #define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */ 59 - #define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */ 60 - #define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */ 61 - 62 52 #define MADV_MERGEABLE 65 /* KSM may merge identical pages */ 63 53 #define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */ 64 54
+8
arch/parisc/kernel/asm-offsets.c
··· 290 290 DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT); 291 291 DEFINE(ASM_PT_INITIAL, PT_INITIAL); 292 292 BLANK(); 293 + /* HUGEPAGE_SIZE is only used in vmlinux.lds.S to align kernel text 294 + * and kernel data on physical huge pages */ 295 + #ifdef CONFIG_HUGETLB_PAGE 296 + DEFINE(HUGEPAGE_SIZE, 1UL << REAL_HPAGE_SHIFT); 297 + #else 298 + DEFINE(HUGEPAGE_SIZE, PAGE_SIZE); 299 + #endif 300 + BLANK(); 293 301 DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip)); 294 302 DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space)); 295 303 DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
+34 -22
arch/parisc/kernel/entry.S
··· 502 502 STREG \pte,0(\ptp) 503 503 .endm 504 504 505 + /* We have (depending on the page size): 506 + * - 38 to 52-bit Physical Page Number 507 + * - 12 to 26-bit page offset 508 + */ 505 509 /* bitshift difference between a PFN (based on kernel's PAGE_SIZE) 506 510 * to a CPU TLB 4k PFN (4k => 12 bits to shift) */ 507 - #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) 511 + #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) 512 + #define PAGE_ADD_HUGE_SHIFT (REAL_HPAGE_SHIFT-12) 508 513 509 514 /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ 510 - .macro convert_for_tlb_insert20 pte 515 + .macro convert_for_tlb_insert20 pte,tmp 516 + #ifdef CONFIG_HUGETLB_PAGE 517 + copy \pte,\tmp 518 + extrd,u \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ 519 + 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte 520 + 521 + depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ 522 + (63-58)+PAGE_ADD_SHIFT,\pte 523 + extrd,u,*= \tmp,_PAGE_HPAGE_BIT+32,1,%r0 524 + depdi _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\ 525 + (63-58)+PAGE_ADD_HUGE_SHIFT,\pte 526 + #else /* Huge pages disabled */ 511 527 extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ 512 528 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte 513 529 depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ 514 530 (63-58)+PAGE_ADD_SHIFT,\pte 531 + #endif 515 532 .endm 516 533 517 534 /* Convert the pte and prot to tlb insertion values. How 518 535 * this happens is quite subtle, read below */ 519 - .macro make_insert_tlb spc,pte,prot 536 + .macro make_insert_tlb spc,pte,prot,tmp 520 537 space_to_prot \spc \prot /* create prot id from space */ 521 538 /* The following is the real subtlety. This is depositing 522 539 * T <-> _PAGE_REFTRAP ··· 570 553 depdi 1,12,1,\prot 571 554 572 555 /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ 573 - convert_for_tlb_insert20 \pte 556 + convert_for_tlb_insert20 \pte \tmp 574 557 .endm 575 558 576 559 /* Identical macro to make_insert_tlb above, except it ··· 663 646 664 647 665 648 /* 666 - * Align fault_vector_20 on 4K boundary so that both 667 - * fault_vector_11 and fault_vector_20 are on the 668 - * same page. This is only necessary as long as we 669 - * write protect the kernel text, which we may stop 670 - * doing once we use large page translations to cover 671 - * the static part of the kernel address space. 649 + * Fault_vectors are architecturally required to be aligned on a 2K 650 + * boundary 672 651 */ 673 652 674 653 .text 675 - 676 - .align 4096 654 + .align 2048 677 655 678 656 ENTRY(fault_vector_20) 679 657 /* First vector is invalid (0) */ ··· 1159 1147 tlb_lock spc,ptp,pte,t0,t1,dtlb_check_alias_20w 1160 1148 update_accessed ptp,pte,t0,t1 1161 1149 1162 - make_insert_tlb spc,pte,prot 1150 + make_insert_tlb spc,pte,prot,t1 1163 1151 1164 1152 idtlbt pte,prot 1165 1153 ··· 1185 1173 tlb_lock spc,ptp,pte,t0,t1,nadtlb_check_alias_20w 1186 1174 update_accessed ptp,pte,t0,t1 1187 1175 1188 - make_insert_tlb spc,pte,prot 1176 + make_insert_tlb spc,pte,prot,t1 1189 1177 1190 1178 idtlbt pte,prot 1191 1179 ··· 1279 1267 tlb_lock spc,ptp,pte,t0,t1,dtlb_check_alias_20 1280 1268 update_accessed ptp,pte,t0,t1 1281 1269 1282 - make_insert_tlb spc,pte,prot 1270 + make_insert_tlb spc,pte,prot,t1 1283 1271 1284 1272 f_extend pte,t1 1285 1273 ··· 1307 1295 tlb_lock spc,ptp,pte,t0,t1,nadtlb_check_alias_20 1308 1296 update_accessed ptp,pte,t0,t1 1309 1297 1310 - make_insert_tlb spc,pte,prot 1298 + make_insert_tlb spc,pte,prot,t1 1311 1299 1312 1300 f_extend pte,t1 1313 1301 ··· 1416 1404 tlb_lock spc,ptp,pte,t0,t1,itlb_fault 1417 1405 update_accessed ptp,pte,t0,t1 1418 1406 1419 - make_insert_tlb spc,pte,prot 1407 + make_insert_tlb spc,pte,prot,t1 1420 1408 1421 1409 iitlbt pte,prot 1422 1410 ··· 1440 1428 tlb_lock spc,ptp,pte,t0,t1,naitlb_check_alias_20w 1441 1429 update_accessed ptp,pte,t0,t1 1442 1430 1443 - make_insert_tlb spc,pte,prot 1431 + make_insert_tlb spc,pte,prot,t1 1444 1432 1445 1433 iitlbt pte,prot 1446 1434 ··· 1526 1514 tlb_lock spc,ptp,pte,t0,t1,itlb_fault 1527 1515 update_accessed ptp,pte,t0,t1 1528 1516 1529 - make_insert_tlb spc,pte,prot 1517 + make_insert_tlb spc,pte,prot,t1 1530 1518 1531 1519 f_extend pte,t1 1532 1520 ··· 1546 1534 tlb_lock spc,ptp,pte,t0,t1,naitlb_check_alias_20 1547 1535 update_accessed ptp,pte,t0,t1 1548 1536 1549 - make_insert_tlb spc,pte,prot 1537 + make_insert_tlb spc,pte,prot,t1 1550 1538 1551 1539 f_extend pte,t1 1552 1540 ··· 1578 1566 tlb_lock spc,ptp,pte,t0,t1,dbit_fault 1579 1567 update_dirty ptp,pte,t1 1580 1568 1581 - make_insert_tlb spc,pte,prot 1569 + make_insert_tlb spc,pte,prot,t1 1582 1570 1583 1571 idtlbt pte,prot 1584 1572 ··· 1622 1610 tlb_lock spc,ptp,pte,t0,t1,dbit_fault 1623 1611 update_dirty ptp,pte,t1 1624 1612 1625 - make_insert_tlb spc,pte,prot 1613 + make_insert_tlb spc,pte,prot,t1 1626 1614 1627 1615 f_extend pte,t1 1628 1616
+2 -2
arch/parisc/kernel/head.S
··· 69 69 stw,ma %arg2,4(%r1) 70 70 stw,ma %arg3,4(%r1) 71 71 72 - /* Initialize startup VM. Just map first 8/16 MB of memory */ 72 + /* Initialize startup VM. Just map first 16/32 MB of memory */ 73 73 load32 PA(swapper_pg_dir),%r4 74 74 mtctl %r4,%cr24 /* Initialize kernel root pointer */ 75 75 mtctl %r4,%cr25 /* Initialize user root pointer */ ··· 107 107 /* Now initialize the PTEs themselves. We use RWX for 108 108 * everything ... it will get remapped correctly later */ 109 109 ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */ 110 - ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ 110 + load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ 111 111 load32 PA(pg0),%r1 112 112 113 113 $pgt_fill_loop:
+13 -1
arch/parisc/kernel/setup.c
··· 130 130 printk(KERN_INFO "The 32-bit Kernel has started...\n"); 131 131 #endif 132 132 133 - printk(KERN_INFO "Default page size is %dKB.\n", (int)(PAGE_SIZE / 1024)); 133 + printk(KERN_INFO "Kernel default page size is %d KB. Huge pages ", 134 + (int)(PAGE_SIZE / 1024)); 135 + #ifdef CONFIG_HUGETLB_PAGE 136 + printk(KERN_CONT "enabled with %d MB physical and %d MB virtual size", 137 + 1 << (REAL_HPAGE_SHIFT - 20), 1 << (HPAGE_SHIFT - 20)); 138 + #else 139 + printk(KERN_CONT "disabled"); 140 + #endif 141 + printk(KERN_CONT ".\n"); 142 + 134 143 135 144 pdc_console_init(); 136 145 ··· 386 377 void start_parisc(void) 387 378 { 388 379 extern void start_kernel(void); 380 + extern void early_trap_init(void); 389 381 390 382 int ret, cpunum; 391 383 struct pdc_coproc_cfg coproc_cfg; ··· 406 396 } else { 407 397 panic("must have an fpu to boot linux"); 408 398 } 399 + 400 + early_trap_init(); /* initialize checksum of fault_vector */ 409 401 410 402 start_kernel(); 411 403 // not reached
+2 -2
arch/parisc/kernel/syscall.S
··· 369 369 ldo -16(%r30),%r29 /* Reference param save area */ 370 370 #endif 371 371 ldo TASK_REGS(%r1),%r26 372 - bl do_syscall_trace_exit,%r2 372 + BL do_syscall_trace_exit,%r2 373 373 STREG %r28,TASK_PT_GR28(%r1) /* save return value now */ 374 374 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 375 375 LDREG TI_TASK(%r1), %r1 ··· 390 390 #ifdef CONFIG_64BIT 391 391 ldo -16(%r30),%r29 /* Reference param save area */ 392 392 #endif 393 - bl do_syscall_trace_exit,%r2 393 + BL do_syscall_trace_exit,%r2 394 394 ldo TASK_REGS(%r1),%r26 395 395 396 396 ldil L%syscall_exit_rfi,%r1
+15 -20
arch/parisc/kernel/traps.c
··· 807 807 } 808 808 809 809 810 - int __init check_ivt(void *iva) 810 + void __init initialize_ivt(const void *iva) 811 811 { 812 812 extern u32 os_hpmc_size; 813 813 extern const u32 os_hpmc[]; ··· 818 818 u32 *hpmcp; 819 819 u32 length; 820 820 821 - if (strcmp((char *)iva, "cows can fly")) 822 - return -1; 821 + if (strcmp((const char *)iva, "cows can fly")) 822 + panic("IVT invalid"); 823 823 824 824 ivap = (u32 *)iva; 825 825 ··· 839 839 check += ivap[i]; 840 840 841 841 ivap[5] = -check; 842 - 843 - return 0; 844 842 } 845 843 844 + 845 + /* early_trap_init() is called before we set up kernel mappings and 846 + * write-protect the kernel */ 847 + void __init early_trap_init(void) 848 + { 849 + extern const void fault_vector_20; 850 + 846 851 #ifndef CONFIG_64BIT 847 - extern const void fault_vector_11; 852 + extern const void fault_vector_11; 853 + initialize_ivt(&fault_vector_11); 848 854 #endif 849 - extern const void fault_vector_20; 855 + 856 + initialize_ivt(&fault_vector_20); 857 + } 850 858 851 859 void __init trap_init(void) 852 860 { 853 - void *iva; 854 - 855 - if (boot_cpu_data.cpu_type >= pcxu) 856 - iva = (void *) &fault_vector_20; 857 - else 858 - #ifdef CONFIG_64BIT 859 - panic("Can't boot 64-bit OS on PA1.1 processor!"); 860 - #else 861 - iva = (void *) &fault_vector_11; 862 - #endif 863 - 864 - if (check_ivt(iva)) 865 - panic("IVT invalid"); 866 861 }
+6 -3
arch/parisc/kernel/vmlinux.lds.S
··· 60 60 EXIT_DATA 61 61 } 62 62 PERCPU_SECTION(8) 63 - . = ALIGN(PAGE_SIZE); 63 + . = ALIGN(HUGEPAGE_SIZE); 64 64 __init_end = .; 65 65 /* freed after init ends here */ 66 66 ··· 116 116 * that we can properly leave these 117 117 * as writable 118 118 */ 119 - . = ALIGN(PAGE_SIZE); 119 + . = ALIGN(HUGEPAGE_SIZE); 120 120 data_start = .; 121 121 122 122 EXCEPTION_TABLE(8) ··· 135 135 _edata = .; 136 136 137 137 /* BSS */ 138 - BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 8) 138 + BSS_SECTION(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE) 139 139 140 + /* bootmap is allocated in setup_bootmem() directly behind bss. */ 141 + 142 + . = ALIGN(HUGEPAGE_SIZE); 140 143 _end = . ; 141 144 142 145 STABS_DEBUG
+1
arch/parisc/mm/Makefile
··· 3 3 # 4 4 5 5 obj-y := init.o fault.o ioremap.o 6 + obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+161
arch/parisc/mm/hugetlbpage.c
··· 1 + /* 2 + * PARISC64 Huge TLB page support. 3 + * 4 + * This parisc implementation is heavily based on the SPARC and x86 code. 5 + * 6 + * Copyright (C) 2015 Helge Deller <deller@gmx.de> 7 + */ 8 + 9 + #include <linux/fs.h> 10 + #include <linux/mm.h> 11 + #include <linux/hugetlb.h> 12 + #include <linux/pagemap.h> 13 + #include <linux/sysctl.h> 14 + 15 + #include <asm/mman.h> 16 + #include <asm/pgalloc.h> 17 + #include <asm/tlb.h> 18 + #include <asm/tlbflush.h> 19 + #include <asm/cacheflush.h> 20 + #include <asm/mmu_context.h> 21 + 22 + 23 + unsigned long 24 + hugetlb_get_unmapped_area(struct file *file, unsigned long addr, 25 + unsigned long len, unsigned long pgoff, unsigned long flags) 26 + { 27 + struct hstate *h = hstate_file(file); 28 + 29 + if (len & ~huge_page_mask(h)) 30 + return -EINVAL; 31 + if (len > TASK_SIZE) 32 + return -ENOMEM; 33 + 34 + if (flags & MAP_FIXED) 35 + if (prepare_hugepage_range(file, addr, len)) 36 + return -EINVAL; 37 + 38 + if (addr) 39 + addr = ALIGN(addr, huge_page_size(h)); 40 + 41 + /* we need to make sure the colouring is OK */ 42 + return arch_get_unmapped_area(file, addr, len, pgoff, flags); 43 + } 44 + 45 + 46 + pte_t *huge_pte_alloc(struct mm_struct *mm, 47 + unsigned long addr, unsigned long sz) 48 + { 49 + pgd_t *pgd; 50 + pud_t *pud; 51 + pmd_t *pmd; 52 + pte_t *pte = NULL; 53 + 54 + /* We must align the address, because our caller will run 55 + * set_huge_pte_at() on whatever we return, which writes out 56 + * all of the sub-ptes for the hugepage range. So we have 57 + * to give it the first such sub-pte. 58 + */ 59 + addr &= HPAGE_MASK; 60 + 61 + pgd = pgd_offset(mm, addr); 62 + pud = pud_alloc(mm, pgd, addr); 63 + if (pud) { 64 + pmd = pmd_alloc(mm, pud, addr); 65 + if (pmd) 66 + pte = pte_alloc_map(mm, NULL, pmd, addr); 67 + } 68 + return pte; 69 + } 70 + 71 + pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) 72 + { 73 + pgd_t *pgd; 74 + pud_t *pud; 75 + pmd_t *pmd; 76 + pte_t *pte = NULL; 77 + 78 + addr &= HPAGE_MASK; 79 + 80 + pgd = pgd_offset(mm, addr); 81 + if (!pgd_none(*pgd)) { 82 + pud = pud_offset(pgd, addr); 83 + if (!pud_none(*pud)) { 84 + pmd = pmd_offset(pud, addr); 85 + if (!pmd_none(*pmd)) 86 + pte = pte_offset_map(pmd, addr); 87 + } 88 + } 89 + return pte; 90 + } 91 + 92 + /* Purge data and instruction TLB entries. Must be called holding 93 + * the pa_tlb_lock. The TLB purge instructions are slow on SMP 94 + * machines since the purge must be broadcast to all CPUs. 95 + */ 96 + static inline void purge_tlb_entries_huge(struct mm_struct *mm, unsigned long addr) 97 + { 98 + int i; 99 + 100 + /* We may use multiple physical huge pages (e.g. 2x1 MB) to emulate 101 + * Linux standard huge pages (e.g. 2 MB) */ 102 + BUILD_BUG_ON(REAL_HPAGE_SHIFT > HPAGE_SHIFT); 103 + 104 + addr &= HPAGE_MASK; 105 + addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT; 106 + 107 + for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) { 108 + mtsp(mm->context, 1); 109 + pdtlb(addr); 110 + if (unlikely(split_tlb)) 111 + pitlb(addr); 112 + addr += (1UL << REAL_HPAGE_SHIFT); 113 + } 114 + } 115 + 116 + void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, 117 + pte_t *ptep, pte_t entry) 118 + { 119 + unsigned long addr_start; 120 + int i; 121 + 122 + addr &= HPAGE_MASK; 123 + addr_start = addr; 124 + 125 + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { 126 + /* Directly write pte entry. We could call set_pte_at(mm, addr, ptep, entry) 127 + * instead, but then we get double locking on pa_tlb_lock. */ 128 + *ptep = entry; 129 + ptep++; 130 + 131 + /* Drop the PAGE_SIZE/non-huge tlb entry */ 132 + purge_tlb_entries(mm, addr); 133 + 134 + addr += PAGE_SIZE; 135 + pte_val(entry) += PAGE_SIZE; 136 + } 137 + 138 + purge_tlb_entries_huge(mm, addr_start); 139 + } 140 + 141 + 142 + pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, 143 + pte_t *ptep) 144 + { 145 + pte_t entry; 146 + 147 + entry = *ptep; 148 + set_huge_pte_at(mm, addr, ptep, __pte(0)); 149 + 150 + return entry; 151 + } 152 + 153 + int pmd_huge(pmd_t pmd) 154 + { 155 + return 0; 156 + } 157 + 158 + int pud_huge(pud_t pud) 159 + { 160 + return 0; 161 + }
+17 -23
arch/parisc/mm/init.c
··· 409 409 unsigned long vaddr; 410 410 unsigned long ro_start; 411 411 unsigned long ro_end; 412 - unsigned long fv_addr; 413 - unsigned long gw_addr; 414 - extern const unsigned long fault_vector_20; 415 - extern void * const linux_gateway_page; 412 + unsigned long kernel_end; 416 413 417 414 ro_start = __pa((unsigned long)_text); 418 415 ro_end = __pa((unsigned long)&data_start); 419 - fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK; 420 - gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK; 416 + kernel_end = __pa((unsigned long)&_end); 421 417 422 418 end_paddr = start_paddr + size; 423 419 ··· 471 475 for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) { 472 476 pte_t pte; 473 477 474 - /* 475 - * Map the fault vector writable so we can 476 - * write the HPMC checksum. 477 - */ 478 478 if (force) 479 479 pte = __mk_pte(address, pgprot); 480 - else if (parisc_text_address(vaddr) && 481 - address != fv_addr) 480 + else if (parisc_text_address(vaddr)) { 482 481 pte = __mk_pte(address, PAGE_KERNEL_EXEC); 482 + if (address >= ro_start && address < kernel_end) 483 + pte = pte_mkhuge(pte); 484 + } 483 485 else 484 486 #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) 485 - if (address >= ro_start && address < ro_end 486 - && address != fv_addr 487 - && address != gw_addr) 488 - pte = __mk_pte(address, PAGE_KERNEL_RO); 489 - else 487 + if (address >= ro_start && address < ro_end) { 488 + pte = __mk_pte(address, PAGE_KERNEL_EXEC); 489 + pte = pte_mkhuge(pte); 490 + } else 490 491 #endif 492 + { 491 493 pte = __mk_pte(address, pgprot); 494 + if (address >= ro_start && address < kernel_end) 495 + pte = pte_mkhuge(pte); 496 + } 492 497 493 498 if (address >= end_paddr) { 494 499 if (force) ··· 533 536 534 537 /* force the kernel to see the new TLB entries */ 535 538 __flush_tlb_range(0, init_begin, init_end); 536 - /* Attempt to catch anyone trying to execute code here 537 - * by filling the page with BRK insns. 538 - */ 539 - memset((void *)init_begin, 0x00, init_end - init_begin); 539 + 540 540 /* finally dump all the instructions which were cached, since the 541 541 * pages are no-longer executable */ 542 542 flush_icache_range(init_begin, init_end); 543 543 544 - free_initmem_default(-1); 544 + free_initmem_default(POISON_FREE_INITMEM); 545 545 546 546 /* set up a new led state on systems shipped LED State panel */ 547 547 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); ··· 722 728 unsigned long size; 723 729 724 730 start_paddr = pmem_ranges[range].start_pfn << PAGE_SHIFT; 725 - end_paddr = start_paddr + (pmem_ranges[range].pages << PAGE_SHIFT); 726 731 size = pmem_ranges[range].pages << PAGE_SHIFT; 732 + end_paddr = start_paddr + size; 727 733 728 734 map_pages((unsigned long)__va(start_paddr), start_paddr, 729 735 size, PAGE_KERNEL, 0);