| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|---|
| 1 | 2 | #ifndef _ASM_POWERPC_BOOK3S_64_MMU_HASH_H_ |
|---|
| 2 | 3 | #define _ASM_POWERPC_BOOK3S_64_MMU_HASH_H_ |
|---|
| 3 | 4 | /* |
|---|
| .. | .. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Dave Engebretsen & Mike Corrigan <{engebret|mikejc}@us.ibm.com> |
|---|
| 7 | 8 | * PPC64 rework. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or |
|---|
| 10 | | - * modify it under the terms of the GNU General Public License |
|---|
| 11 | | - * as published by the Free Software Foundation; either version |
|---|
| 12 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <asm/page.h> |
|---|
| .. | .. |
|---|
| 23 | 19 | */ |
|---|
| 24 | 20 | #include <asm/book3s/64/pgtable.h> |
|---|
| 25 | 21 | #include <asm/bug.h> |
|---|
| 26 | | -#include <asm/processor.h> |
|---|
| 22 | +#include <asm/task_size_64.h> |
|---|
| 27 | 23 | #include <asm/cpu_has_feature.h> |
|---|
| 28 | 24 | |
|---|
| 29 | 25 | /* |
|---|
| 30 | 26 | * SLB |
|---|
| 31 | 27 | */ |
|---|
| 32 | 28 | |
|---|
| 33 | | -#define SLB_NUM_BOLTED 3 |
|---|
| 29 | +#define SLB_NUM_BOLTED 2 |
|---|
| 34 | 30 | #define SLB_CACHE_ENTRIES 8 |
|---|
| 35 | 31 | #define SLB_MIN_SIZE 32 |
|---|
| 36 | 32 | |
|---|
| .. | .. |
|---|
| 90 | 86 | #define HPTE_R_PP0 ASM_CONST(0x8000000000000000) |
|---|
| 91 | 87 | #define HPTE_R_TS ASM_CONST(0x4000000000000000) |
|---|
| 92 | 88 | #define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000) |
|---|
| 93 | | -#define HPTE_R_KEY_BIT0 ASM_CONST(0x2000000000000000) |
|---|
| 94 | | -#define HPTE_R_KEY_BIT1 ASM_CONST(0x1000000000000000) |
|---|
| 89 | +#define HPTE_R_KEY_BIT4 ASM_CONST(0x2000000000000000) |
|---|
| 90 | +#define HPTE_R_KEY_BIT3 ASM_CONST(0x1000000000000000) |
|---|
| 95 | 91 | #define HPTE_R_RPN_SHIFT 12 |
|---|
| 96 | 92 | #define HPTE_R_RPN ASM_CONST(0x0ffffffffffff000) |
|---|
| 97 | 93 | #define HPTE_R_RPN_3_0 ASM_CONST(0x01fffffffffff000) |
|---|
| .. | .. |
|---|
| 107 | 103 | #define HPTE_R_R ASM_CONST(0x0000000000000100) |
|---|
| 108 | 104 | #define HPTE_R_KEY_LO ASM_CONST(0x0000000000000e00) |
|---|
| 109 | 105 | #define HPTE_R_KEY_BIT2 ASM_CONST(0x0000000000000800) |
|---|
| 110 | | -#define HPTE_R_KEY_BIT3 ASM_CONST(0x0000000000000400) |
|---|
| 111 | | -#define HPTE_R_KEY_BIT4 ASM_CONST(0x0000000000000200) |
|---|
| 106 | +#define HPTE_R_KEY_BIT1 ASM_CONST(0x0000000000000400) |
|---|
| 107 | +#define HPTE_R_KEY_BIT0 ASM_CONST(0x0000000000000200) |
|---|
| 112 | 108 | #define HPTE_R_KEY (HPTE_R_KEY_LO | HPTE_R_KEY_HI) |
|---|
| 113 | 109 | |
|---|
| 114 | 110 | #define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000) |
|---|
| .. | .. |
|---|
| 201 | 197 | if (mmu_psize_defs[mmu_psize].shift) |
|---|
| 202 | 198 | return mmu_psize_defs[mmu_psize].shift; |
|---|
| 203 | 199 | BUG(); |
|---|
| 200 | +} |
|---|
| 201 | + |
|---|
| 202 | +static inline unsigned int ap_to_shift(unsigned long ap) |
|---|
| 203 | +{ |
|---|
| 204 | + int psize; |
|---|
| 205 | + |
|---|
| 206 | + for (psize = 0; psize < MMU_PAGE_COUNT; psize++) { |
|---|
| 207 | + if (mmu_psize_defs[psize].ap == ap) |
|---|
| 208 | + return mmu_psize_defs[psize].shift; |
|---|
| 209 | + } |
|---|
| 210 | + |
|---|
| 211 | + return -1; |
|---|
| 204 | 212 | } |
|---|
| 205 | 213 | |
|---|
| 206 | 214 | static inline unsigned long get_sllp_encoding(int psize) |
|---|
| .. | .. |
|---|
| 487 | 495 | extern void pseries_add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages); |
|---|
| 488 | 496 | extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); |
|---|
| 489 | 497 | |
|---|
| 498 | +extern void hash__setup_new_exec(void); |
|---|
| 499 | + |
|---|
| 490 | 500 | #ifdef CONFIG_PPC_PSERIES |
|---|
| 491 | 501 | void hpte_init_pseries(void); |
|---|
| 492 | 502 | #else |
|---|
| .. | .. |
|---|
| 495 | 505 | |
|---|
| 496 | 506 | extern void hpte_init_native(void); |
|---|
| 497 | 507 | |
|---|
| 508 | +struct slb_entry { |
|---|
| 509 | + u64 esid; |
|---|
| 510 | + u64 vsid; |
|---|
| 511 | +}; |
|---|
| 512 | + |
|---|
| 498 | 513 | extern void slb_initialize(void); |
|---|
| 499 | | -extern void slb_flush_and_rebolt(void); |
|---|
| 514 | +void slb_flush_and_restore_bolted(void); |
|---|
| 500 | 515 | void slb_flush_all_realmode(void); |
|---|
| 501 | 516 | void __slb_restore_bolted_realmode(void); |
|---|
| 502 | 517 | void slb_restore_bolted_realmode(void); |
|---|
| 518 | +void slb_save_contents(struct slb_entry *slb_ptr); |
|---|
| 519 | +void slb_dump_contents(struct slb_entry *slb_ptr); |
|---|
| 503 | 520 | |
|---|
| 504 | 521 | extern void slb_vmalloc_update(void); |
|---|
| 505 | 522 | extern void slb_set_size(u16 size); |
|---|
| .. | .. |
|---|
| 512 | 529 | * from mmu context id and effective segment id of the address. |
|---|
| 513 | 530 | * |
|---|
| 514 | 531 | * For user processes max context id is limited to MAX_USER_CONTEXT. |
|---|
| 515 | | - |
|---|
| 516 | | - * For kernel space, we use context ids 1-4 to map addresses as below: |
|---|
| 517 | | - * NOTE: each context only support 64TB now. |
|---|
| 518 | | - * 0x00001 - [ 0xc000000000000000 - 0xc0003fffffffffff ] |
|---|
| 519 | | - * 0x00002 - [ 0xd000000000000000 - 0xd0003fffffffffff ] |
|---|
| 520 | | - * 0x00003 - [ 0xe000000000000000 - 0xe0003fffffffffff ] |
|---|
| 521 | | - * 0x00004 - [ 0xf000000000000000 - 0xf0003fffffffffff ] |
|---|
| 532 | + * more details in get_user_context |
|---|
| 533 | + * |
|---|
| 534 | + * For kernel space get_kernel_context |
|---|
| 522 | 535 | * |
|---|
| 523 | 536 | * The proto-VSIDs are then scrambled into real VSIDs with the |
|---|
| 524 | 537 | * multiplicative hash: |
|---|
| .. | .. |
|---|
| 559 | 572 | #define ESID_BITS_1T_MASK ((1 << ESID_BITS_1T) - 1) |
|---|
| 560 | 573 | |
|---|
| 561 | 574 | /* |
|---|
| 575 | + * Now certain config support MAX_PHYSMEM more than 512TB. Hence we will need |
|---|
| 576 | + * to use more than one context for linear mapping the kernel. |
|---|
| 577 | + * For vmalloc and memmap, we use just one context with 512TB. With 64 byte |
|---|
| 578 | + * struct page size, we need ony 32 TB in memmap for 2PB (51 bits (MAX_PHYSMEM_BITS)). |
|---|
| 579 | + */ |
|---|
| 580 | +#if (H_MAX_PHYSMEM_BITS > MAX_EA_BITS_PER_CONTEXT) |
|---|
| 581 | +#define MAX_KERNEL_CTX_CNT (1UL << (H_MAX_PHYSMEM_BITS - MAX_EA_BITS_PER_CONTEXT)) |
|---|
| 582 | +#else |
|---|
| 583 | +#define MAX_KERNEL_CTX_CNT 1 |
|---|
| 584 | +#endif |
|---|
| 585 | + |
|---|
| 586 | +#define MAX_VMALLOC_CTX_CNT 1 |
|---|
| 587 | +#define MAX_IO_CTX_CNT 1 |
|---|
| 588 | +#define MAX_VMEMMAP_CTX_CNT 1 |
|---|
| 589 | + |
|---|
| 590 | +/* |
|---|
| 562 | 591 | * 256MB segment |
|---|
| 563 | 592 | * The proto-VSID space has 2^(CONTEX_BITS + ESID_BITS) - 1 segments |
|---|
| 564 | 593 | * available for user + kernel mapping. VSID 0 is reserved as invalid, contexts |
|---|
| .. | .. |
|---|
| 568 | 597 | * We also need to avoid the last segment of the last context, because that |
|---|
| 569 | 598 | * would give a protovsid of 0x1fffffffff. That will result in a VSID 0 |
|---|
| 570 | 599 | * because of the modulo operation in vsid scramble. |
|---|
| 600 | + * |
|---|
| 571 | 601 | */ |
|---|
| 572 | 602 | #define MAX_USER_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 2) |
|---|
| 573 | | -#define MIN_USER_CONTEXT (5) |
|---|
| 574 | 603 | |
|---|
| 575 | | -/* Would be nice to use KERNEL_REGION_ID here */ |
|---|
| 576 | | -#define KERNEL_REGION_CONTEXT_OFFSET (0xc - 1) |
|---|
| 604 | +// The + 2 accounts for INVALID_REGION and 1 more to avoid overlap with kernel |
|---|
| 605 | +#define MIN_USER_CONTEXT (MAX_KERNEL_CTX_CNT + MAX_VMALLOC_CTX_CNT + \ |
|---|
| 606 | + MAX_IO_CTX_CNT + MAX_VMEMMAP_CTX_CNT + 2) |
|---|
| 577 | 607 | |
|---|
| 578 | 608 | /* |
|---|
| 579 | 609 | * For platforms that support on 65bit VA we limit the context bits |
|---|
| .. | .. |
|---|
| 624 | 654 | |
|---|
| 625 | 655 | /* 4 bits per slice and we have one slice per 1TB */ |
|---|
| 626 | 656 | #define SLICE_ARRAY_SIZE (H_PGTABLE_RANGE >> 41) |
|---|
| 627 | | -#define TASK_SLICE_ARRAY_SZ(x) ((x)->context.slb_addr_limit >> 41) |
|---|
| 628 | | - |
|---|
| 657 | +#define LOW_SLICE_ARRAY_SZ (BITS_PER_LONG / BITS_PER_BYTE) |
|---|
| 658 | +#define TASK_SLICE_ARRAY_SZ(x) ((x)->hash_context->slb_addr_limit >> 41) |
|---|
| 629 | 659 | #ifndef __ASSEMBLY__ |
|---|
| 630 | 660 | |
|---|
| 631 | 661 | #ifdef CONFIG_PPC_SUBPAGE_PROT |
|---|
| .. | .. |
|---|
| 654 | 684 | #define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS) |
|---|
| 655 | 685 | |
|---|
| 656 | 686 | extern void subpage_prot_free(struct mm_struct *mm); |
|---|
| 657 | | -extern void subpage_prot_init_new_context(struct mm_struct *mm); |
|---|
| 658 | 687 | #else |
|---|
| 659 | 688 | static inline void subpage_prot_free(struct mm_struct *mm) {} |
|---|
| 660 | | -static inline void subpage_prot_init_new_context(struct mm_struct *mm) { } |
|---|
| 661 | 689 | #endif /* CONFIG_PPC_SUBPAGE_PROT */ |
|---|
| 690 | + |
|---|
| 691 | +/* |
|---|
| 692 | + * One bit per slice. We have lower slices which cover 256MB segments |
|---|
| 693 | + * upto 4G range. That gets us 16 low slices. For the rest we track slices |
|---|
| 694 | + * in 1TB size. |
|---|
| 695 | + */ |
|---|
| 696 | +struct slice_mask { |
|---|
| 697 | + u64 low_slices; |
|---|
| 698 | + DECLARE_BITMAP(high_slices, SLICE_NUM_HIGH); |
|---|
| 699 | +}; |
|---|
| 700 | + |
|---|
| 701 | +struct hash_mm_context { |
|---|
| 702 | + u16 user_psize; /* page size index */ |
|---|
| 703 | + |
|---|
| 704 | + /* SLB page size encodings*/ |
|---|
| 705 | + unsigned char low_slices_psize[LOW_SLICE_ARRAY_SZ]; |
|---|
| 706 | + unsigned char high_slices_psize[SLICE_ARRAY_SIZE]; |
|---|
| 707 | + unsigned long slb_addr_limit; |
|---|
| 708 | +#ifdef CONFIG_PPC_64K_PAGES |
|---|
| 709 | + struct slice_mask mask_64k; |
|---|
| 710 | +#endif |
|---|
| 711 | + struct slice_mask mask_4k; |
|---|
| 712 | +#ifdef CONFIG_HUGETLB_PAGE |
|---|
| 713 | + struct slice_mask mask_16m; |
|---|
| 714 | + struct slice_mask mask_16g; |
|---|
| 715 | +#endif |
|---|
| 716 | + |
|---|
| 717 | +#ifdef CONFIG_PPC_SUBPAGE_PROT |
|---|
| 718 | + struct subpage_prot_table *spt; |
|---|
| 719 | +#endif /* CONFIG_PPC_SUBPAGE_PROT */ |
|---|
| 720 | +}; |
|---|
| 662 | 721 | |
|---|
| 663 | 722 | #if 0 |
|---|
| 664 | 723 | /* |
|---|
| .. | .. |
|---|
| 714 | 773 | /* |
|---|
| 715 | 774 | * Bad address. We return VSID 0 for that |
|---|
| 716 | 775 | */ |
|---|
| 717 | | - if ((ea & ~REGION_MASK) >= H_PGTABLE_RANGE) |
|---|
| 776 | + if ((ea & EA_MASK) >= H_PGTABLE_RANGE) |
|---|
| 718 | 777 | return 0; |
|---|
| 719 | 778 | |
|---|
| 720 | 779 | if (!mmu_has_feature(MMU_FTR_68_BIT_VA)) |
|---|
| .. | .. |
|---|
| 734 | 793 | } |
|---|
| 735 | 794 | |
|---|
| 736 | 795 | /* |
|---|
| 796 | + * For kernel space, we use context ids as |
|---|
| 797 | + * below. Range is 512TB per context. |
|---|
| 798 | + * |
|---|
| 799 | + * 0x00001 - [ 0xc000000000000000 - 0xc001ffffffffffff] |
|---|
| 800 | + * 0x00002 - [ 0xc002000000000000 - 0xc003ffffffffffff] |
|---|
| 801 | + * 0x00003 - [ 0xc004000000000000 - 0xc005ffffffffffff] |
|---|
| 802 | + * 0x00004 - [ 0xc006000000000000 - 0xc007ffffffffffff] |
|---|
| 803 | + * |
|---|
| 804 | + * vmap, IO, vmemap |
|---|
| 805 | + * |
|---|
| 806 | + * 0x00005 - [ 0xc008000000000000 - 0xc009ffffffffffff] |
|---|
| 807 | + * 0x00006 - [ 0xc00a000000000000 - 0xc00bffffffffffff] |
|---|
| 808 | + * 0x00007 - [ 0xc00c000000000000 - 0xc00dffffffffffff] |
|---|
| 809 | + * |
|---|
| 810 | + */ |
|---|
| 811 | +static inline unsigned long get_kernel_context(unsigned long ea) |
|---|
| 812 | +{ |
|---|
| 813 | + unsigned long region_id = get_region_id(ea); |
|---|
| 814 | + unsigned long ctx; |
|---|
| 815 | + /* |
|---|
| 816 | + * Depending on Kernel config, kernel region can have one context |
|---|
| 817 | + * or more. |
|---|
| 818 | + */ |
|---|
| 819 | + if (region_id == LINEAR_MAP_REGION_ID) { |
|---|
| 820 | + /* |
|---|
| 821 | + * We already verified ea to be not beyond the addr limit. |
|---|
| 822 | + */ |
|---|
| 823 | + ctx = 1 + ((ea & EA_MASK) >> MAX_EA_BITS_PER_CONTEXT); |
|---|
| 824 | + } else |
|---|
| 825 | + ctx = region_id + MAX_KERNEL_CTX_CNT - 1; |
|---|
| 826 | + return ctx; |
|---|
| 827 | +} |
|---|
| 828 | + |
|---|
| 829 | +/* |
|---|
| 737 | 830 | * This is only valid for addresses >= PAGE_OFFSET |
|---|
| 738 | 831 | */ |
|---|
| 739 | 832 | static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) |
|---|
| .. | .. |
|---|
| 743 | 836 | if (!is_kernel_addr(ea)) |
|---|
| 744 | 837 | return 0; |
|---|
| 745 | 838 | |
|---|
| 746 | | - /* |
|---|
| 747 | | - * For kernel space, we use context ids 1-4 to map the address space as |
|---|
| 748 | | - * below: |
|---|
| 749 | | - * |
|---|
| 750 | | - * 0x00001 - [ 0xc000000000000000 - 0xc0003fffffffffff ] |
|---|
| 751 | | - * 0x00002 - [ 0xd000000000000000 - 0xd0003fffffffffff ] |
|---|
| 752 | | - * 0x00003 - [ 0xe000000000000000 - 0xe0003fffffffffff ] |
|---|
| 753 | | - * 0x00004 - [ 0xf000000000000000 - 0xf0003fffffffffff ] |
|---|
| 754 | | - * |
|---|
| 755 | | - * So we can compute the context from the region (top nibble) by |
|---|
| 756 | | - * subtracting 11, or 0xc - 1. |
|---|
| 757 | | - */ |
|---|
| 758 | | - context = (ea >> 60) - KERNEL_REGION_CONTEXT_OFFSET; |
|---|
| 759 | | - |
|---|
| 839 | + context = get_kernel_context(ea); |
|---|
| 760 | 840 | return get_vsid(context, ea, ssize); |
|---|
| 761 | 841 | } |
|---|
| 762 | 842 | |
|---|