diff options
author | Paul Mackerras <paulus@samba.org> | 2007-10-11 06:37:10 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-10-12 00:05:17 -0400 |
commit | 1189be6508d45183013ddb82b18f4934193de274 (patch) | |
tree | 58924481b4de56699e4a884dce8dc601e71cf7d1 /arch/powerpc/mm/hash_utils_64.c | |
parent | 287e5d6fcccfa38b953cebe307e1ddfd32363355 (diff) |
[POWERPC] Use 1TB segments
This makes the kernel use 1TB segments for all kernel mappings and for
user addresses of 1TB and above, on machines which support them
(currently POWER5+, POWER6 and PA6T).
We detect that the machine supports 1TB segments by looking at the
ibm,processor-segment-sizes property in the device tree.
We don't currently use 1TB segments for user addresses < 1T, since
that would effectively prevent 32-bit processes from using huge pages
unless we also had a way to revert to using 256MB segments. That
would be possible but would involve extra complications (such as
keeping track of which segment size was used when HPTEs were inserted)
and is not addressed here.
Parts of this patch were originally written by Ben Herrenschmidt.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/mm/hash_utils_64.c')
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 114 |
1 files changed, 83 insertions, 31 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index d525f2eba313..611ad084b7e7 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -93,6 +93,8 @@ int mmu_linear_psize = MMU_PAGE_4K; | |||
93 | int mmu_virtual_psize = MMU_PAGE_4K; | 93 | int mmu_virtual_psize = MMU_PAGE_4K; |
94 | int mmu_vmalloc_psize = MMU_PAGE_4K; | 94 | int mmu_vmalloc_psize = MMU_PAGE_4K; |
95 | int mmu_io_psize = MMU_PAGE_4K; | 95 | int mmu_io_psize = MMU_PAGE_4K; |
96 | int mmu_kernel_ssize = MMU_SEGSIZE_256M; | ||
97 | int mmu_highuser_ssize = MMU_SEGSIZE_256M; | ||
96 | #ifdef CONFIG_HUGETLB_PAGE | 98 | #ifdef CONFIG_HUGETLB_PAGE |
97 | int mmu_huge_psize = MMU_PAGE_16M; | 99 | int mmu_huge_psize = MMU_PAGE_16M; |
98 | unsigned int HPAGE_SHIFT; | 100 | unsigned int HPAGE_SHIFT; |
@@ -145,7 +147,8 @@ struct mmu_psize_def mmu_psize_defaults_gp[] = { | |||
145 | 147 | ||
146 | 148 | ||
147 | int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | 149 | int htab_bolt_mapping(unsigned long vstart, unsigned long vend, |
148 | unsigned long pstart, unsigned long mode, int psize) | 150 | unsigned long pstart, unsigned long mode, |
151 | int psize, int ssize) | ||
149 | { | 152 | { |
150 | unsigned long vaddr, paddr; | 153 | unsigned long vaddr, paddr; |
151 | unsigned int step, shift; | 154 | unsigned int step, shift; |
@@ -158,8 +161,8 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
158 | for (vaddr = vstart, paddr = pstart; vaddr < vend; | 161 | for (vaddr = vstart, paddr = pstart; vaddr < vend; |
159 | vaddr += step, paddr += step) { | 162 | vaddr += step, paddr += step) { |
160 | unsigned long hash, hpteg; | 163 | unsigned long hash, hpteg; |
161 | unsigned long vsid = get_kernel_vsid(vaddr); | 164 | unsigned long vsid = get_kernel_vsid(vaddr, ssize); |
162 | unsigned long va = (vsid << 28) | (vaddr & 0x0fffffff); | 165 | unsigned long va = hpt_va(vaddr, vsid, ssize); |
163 | 166 | ||
164 | tmp_mode = mode; | 167 | tmp_mode = mode; |
165 | 168 | ||
@@ -167,14 +170,14 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
167 | if (!in_kernel_text(vaddr)) | 170 | if (!in_kernel_text(vaddr)) |
168 | tmp_mode = mode | HPTE_R_N; | 171 | tmp_mode = mode | HPTE_R_N; |
169 | 172 | ||
170 | hash = hpt_hash(va, shift); | 173 | hash = hpt_hash(va, shift, ssize); |
171 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | 174 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); |
172 | 175 | ||
173 | DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert); | 176 | DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert); |
174 | 177 | ||
175 | BUG_ON(!ppc_md.hpte_insert); | 178 | BUG_ON(!ppc_md.hpte_insert); |
176 | ret = ppc_md.hpte_insert(hpteg, va, paddr, | 179 | ret = ppc_md.hpte_insert(hpteg, va, paddr, |
177 | tmp_mode, HPTE_V_BOLTED, psize); | 180 | tmp_mode, HPTE_V_BOLTED, psize, ssize); |
178 | 181 | ||
179 | if (ret < 0) | 182 | if (ret < 0) |
180 | break; | 183 | break; |
@@ -186,6 +189,37 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
186 | return ret < 0 ? ret : 0; | 189 | return ret < 0 ? ret : 0; |
187 | } | 190 | } |
188 | 191 | ||
192 | static int __init htab_dt_scan_seg_sizes(unsigned long node, | ||
193 | const char *uname, int depth, | ||
194 | void *data) | ||
195 | { | ||
196 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
197 | u32 *prop; | ||
198 | unsigned long size = 0; | ||
199 | |||
200 | /* We are scanning "cpu" nodes only */ | ||
201 | if (type == NULL || strcmp(type, "cpu") != 0) | ||
202 | return 0; | ||
203 | |||
204 | prop = (u32 *)of_get_flat_dt_prop(node, "ibm,processor-segment-sizes", | ||
205 | &size); | ||
206 | if (prop == NULL) | ||
207 | return 0; | ||
208 | for (; size >= 4; size -= 4, ++prop) { | ||
209 | if (prop[0] == 40) { | ||
210 | DBG("1T segment support detected\n"); | ||
211 | cur_cpu_spec->cpu_features |= CPU_FTR_1T_SEGMENT; | ||
212 | } | ||
213 | return 1; | ||
214 | } | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static void __init htab_init_seg_sizes(void) | ||
219 | { | ||
220 | of_scan_flat_dt(htab_dt_scan_seg_sizes, NULL); | ||
221 | } | ||
222 | |||
189 | static int __init htab_dt_scan_page_sizes(unsigned long node, | 223 | static int __init htab_dt_scan_page_sizes(unsigned long node, |
190 | const char *uname, int depth, | 224 | const char *uname, int depth, |
191 | void *data) | 225 | void *data) |
@@ -265,7 +299,6 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, | |||
265 | return 0; | 299 | return 0; |
266 | } | 300 | } |
267 | 301 | ||
268 | |||
269 | static void __init htab_init_page_sizes(void) | 302 | static void __init htab_init_page_sizes(void) |
270 | { | 303 | { |
271 | int rc; | 304 | int rc; |
@@ -398,7 +431,7 @@ void create_section_mapping(unsigned long start, unsigned long end) | |||
398 | { | 431 | { |
399 | BUG_ON(htab_bolt_mapping(start, end, __pa(start), | 432 | BUG_ON(htab_bolt_mapping(start, end, __pa(start), |
400 | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX, | 433 | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX, |
401 | mmu_linear_psize)); | 434 | mmu_linear_psize, mmu_kernel_ssize)); |
402 | } | 435 | } |
403 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 436 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
404 | 437 | ||
@@ -449,9 +482,18 @@ void __init htab_initialize(void) | |||
449 | 482 | ||
450 | DBG(" -> htab_initialize()\n"); | 483 | DBG(" -> htab_initialize()\n"); |
451 | 484 | ||
485 | /* Initialize segment sizes */ | ||
486 | htab_init_seg_sizes(); | ||
487 | |||
452 | /* Initialize page sizes */ | 488 | /* Initialize page sizes */ |
453 | htab_init_page_sizes(); | 489 | htab_init_page_sizes(); |
454 | 490 | ||
491 | if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) { | ||
492 | mmu_kernel_ssize = MMU_SEGSIZE_1T; | ||
493 | mmu_highuser_ssize = MMU_SEGSIZE_1T; | ||
494 | printk(KERN_INFO "Using 1TB segments\n"); | ||
495 | } | ||
496 | |||
455 | /* | 497 | /* |
456 | * Calculate the required size of the htab. We want the number of | 498 | * Calculate the required size of the htab. We want the number of |
457 | * PTEGs to equal one half the number of real pages. | 499 | * PTEGs to equal one half the number of real pages. |
@@ -523,18 +565,20 @@ void __init htab_initialize(void) | |||
523 | if (base != dart_tablebase) | 565 | if (base != dart_tablebase) |
524 | BUG_ON(htab_bolt_mapping(base, dart_tablebase, | 566 | BUG_ON(htab_bolt_mapping(base, dart_tablebase, |
525 | __pa(base), mode_rw, | 567 | __pa(base), mode_rw, |
526 | mmu_linear_psize)); | 568 | mmu_linear_psize, |
569 | mmu_kernel_ssize)); | ||
527 | if ((base + size) > dart_table_end) | 570 | if ((base + size) > dart_table_end) |
528 | BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB, | 571 | BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB, |
529 | base + size, | 572 | base + size, |
530 | __pa(dart_table_end), | 573 | __pa(dart_table_end), |
531 | mode_rw, | 574 | mode_rw, |
532 | mmu_linear_psize)); | 575 | mmu_linear_psize, |
576 | mmu_kernel_ssize)); | ||
533 | continue; | 577 | continue; |
534 | } | 578 | } |
535 | #endif /* CONFIG_U3_DART */ | 579 | #endif /* CONFIG_U3_DART */ |
536 | BUG_ON(htab_bolt_mapping(base, base + size, __pa(base), | 580 | BUG_ON(htab_bolt_mapping(base, base + size, __pa(base), |
537 | mode_rw, mmu_linear_psize)); | 581 | mode_rw, mmu_linear_psize, mmu_kernel_ssize)); |
538 | } | 582 | } |
539 | 583 | ||
540 | /* | 584 | /* |
@@ -553,7 +597,7 @@ void __init htab_initialize(void) | |||
553 | 597 | ||
554 | BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end, | 598 | BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end, |
555 | __pa(tce_alloc_start), mode_rw, | 599 | __pa(tce_alloc_start), mode_rw, |
556 | mmu_linear_psize)); | 600 | mmu_linear_psize, mmu_kernel_ssize)); |
557 | } | 601 | } |
558 | 602 | ||
559 | htab_finish_init(); | 603 | htab_finish_init(); |
@@ -621,7 +665,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
621 | pte_t *ptep; | 665 | pte_t *ptep; |
622 | cpumask_t tmp; | 666 | cpumask_t tmp; |
623 | int rc, user_region = 0, local = 0; | 667 | int rc, user_region = 0, local = 0; |
624 | int psize; | 668 | int psize, ssize; |
625 | 669 | ||
626 | DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", | 670 | DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", |
627 | ea, access, trap); | 671 | ea, access, trap); |
@@ -640,20 +684,22 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
640 | DBG_LOW(" user region with no mm !\n"); | 684 | DBG_LOW(" user region with no mm !\n"); |
641 | return 1; | 685 | return 1; |
642 | } | 686 | } |
643 | vsid = get_vsid(mm->context.id, ea); | ||
644 | #ifdef CONFIG_PPC_MM_SLICES | 687 | #ifdef CONFIG_PPC_MM_SLICES |
645 | psize = get_slice_psize(mm, ea); | 688 | psize = get_slice_psize(mm, ea); |
646 | #else | 689 | #else |
647 | psize = mm->context.user_psize; | 690 | psize = mm->context.user_psize; |
648 | #endif | 691 | #endif |
692 | ssize = user_segment_size(ea); | ||
693 | vsid = get_vsid(mm->context.id, ea, ssize); | ||
649 | break; | 694 | break; |
650 | case VMALLOC_REGION_ID: | 695 | case VMALLOC_REGION_ID: |
651 | mm = &init_mm; | 696 | mm = &init_mm; |
652 | vsid = get_kernel_vsid(ea); | 697 | vsid = get_kernel_vsid(ea, mmu_kernel_ssize); |
653 | if (ea < VMALLOC_END) | 698 | if (ea < VMALLOC_END) |
654 | psize = mmu_vmalloc_psize; | 699 | psize = mmu_vmalloc_psize; |
655 | else | 700 | else |
656 | psize = mmu_io_psize; | 701 | psize = mmu_io_psize; |
702 | ssize = mmu_kernel_ssize; | ||
657 | break; | 703 | break; |
658 | default: | 704 | default: |
659 | /* Not a valid range | 705 | /* Not a valid range |
@@ -758,10 +804,10 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
758 | 804 | ||
759 | #ifdef CONFIG_PPC_HAS_HASH_64K | 805 | #ifdef CONFIG_PPC_HAS_HASH_64K |
760 | if (psize == MMU_PAGE_64K) | 806 | if (psize == MMU_PAGE_64K) |
761 | rc = __hash_page_64K(ea, access, vsid, ptep, trap, local); | 807 | rc = __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize); |
762 | else | 808 | else |
763 | #endif /* CONFIG_PPC_HAS_HASH_64K */ | 809 | #endif /* CONFIG_PPC_HAS_HASH_64K */ |
764 | rc = __hash_page_4K(ea, access, vsid, ptep, trap, local); | 810 | rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize); |
765 | 811 | ||
766 | #ifndef CONFIG_PPC_64K_PAGES | 812 | #ifndef CONFIG_PPC_64K_PAGES |
767 | DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep)); | 813 | DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep)); |
@@ -783,6 +829,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, | |||
783 | cpumask_t mask; | 829 | cpumask_t mask; |
784 | unsigned long flags; | 830 | unsigned long flags; |
785 | int local = 0; | 831 | int local = 0; |
832 | int ssize; | ||
786 | 833 | ||
787 | BUG_ON(REGION_ID(ea) != USER_REGION_ID); | 834 | BUG_ON(REGION_ID(ea) != USER_REGION_ID); |
788 | 835 | ||
@@ -815,7 +862,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, | |||
815 | #endif /* CONFIG_PPC_64K_PAGES */ | 862 | #endif /* CONFIG_PPC_64K_PAGES */ |
816 | 863 | ||
817 | /* Get VSID */ | 864 | /* Get VSID */ |
818 | vsid = get_vsid(mm->context.id, ea); | 865 | ssize = user_segment_size(ea); |
866 | vsid = get_vsid(mm->context.id, ea, ssize); | ||
819 | 867 | ||
820 | /* Hash doesn't like irqs */ | 868 | /* Hash doesn't like irqs */ |
821 | local_irq_save(flags); | 869 | local_irq_save(flags); |
@@ -828,28 +876,29 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, | |||
828 | /* Hash it in */ | 876 | /* Hash it in */ |
829 | #ifdef CONFIG_PPC_HAS_HASH_64K | 877 | #ifdef CONFIG_PPC_HAS_HASH_64K |
830 | if (mm->context.user_psize == MMU_PAGE_64K) | 878 | if (mm->context.user_psize == MMU_PAGE_64K) |
831 | __hash_page_64K(ea, access, vsid, ptep, trap, local); | 879 | __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize); |
832 | else | 880 | else |
833 | #endif /* CONFIG_PPC_HAS_HASH_64K */ | 881 | #endif /* CONFIG_PPC_HAS_HASH_64K */ |
834 | __hash_page_4K(ea, access, vsid, ptep, trap, local); | 882 | __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize); |
835 | 883 | ||
836 | local_irq_restore(flags); | 884 | local_irq_restore(flags); |
837 | } | 885 | } |
838 | 886 | ||
839 | void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int local) | 887 | void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize, |
888 | int local) | ||
840 | { | 889 | { |
841 | unsigned long hash, index, shift, hidx, slot; | 890 | unsigned long hash, index, shift, hidx, slot; |
842 | 891 | ||
843 | DBG_LOW("flush_hash_page(va=%016x)\n", va); | 892 | DBG_LOW("flush_hash_page(va=%016x)\n", va); |
844 | pte_iterate_hashed_subpages(pte, psize, va, index, shift) { | 893 | pte_iterate_hashed_subpages(pte, psize, va, index, shift) { |
845 | hash = hpt_hash(va, shift); | 894 | hash = hpt_hash(va, shift, ssize); |
846 | hidx = __rpte_to_hidx(pte, index); | 895 | hidx = __rpte_to_hidx(pte, index); |
847 | if (hidx & _PTEIDX_SECONDARY) | 896 | if (hidx & _PTEIDX_SECONDARY) |
848 | hash = ~hash; | 897 | hash = ~hash; |
849 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 898 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
850 | slot += hidx & _PTEIDX_GROUP_IX; | 899 | slot += hidx & _PTEIDX_GROUP_IX; |
851 | DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx); | 900 | DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx); |
852 | ppc_md.hpte_invalidate(slot, va, psize, local); | 901 | ppc_md.hpte_invalidate(slot, va, psize, ssize, local); |
853 | } pte_iterate_hashed_end(); | 902 | } pte_iterate_hashed_end(); |
854 | } | 903 | } |
855 | 904 | ||
@@ -864,7 +913,7 @@ void flush_hash_range(unsigned long number, int local) | |||
864 | 913 | ||
865 | for (i = 0; i < number; i++) | 914 | for (i = 0; i < number; i++) |
866 | flush_hash_page(batch->vaddr[i], batch->pte[i], | 915 | flush_hash_page(batch->vaddr[i], batch->pte[i], |
867 | batch->psize, local); | 916 | batch->psize, batch->ssize, local); |
868 | } | 917 | } |
869 | } | 918 | } |
870 | 919 | ||
@@ -890,17 +939,19 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address) | |||
890 | #ifdef CONFIG_DEBUG_PAGEALLOC | 939 | #ifdef CONFIG_DEBUG_PAGEALLOC |
891 | static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) | 940 | static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) |
892 | { | 941 | { |
893 | unsigned long hash, hpteg, vsid = get_kernel_vsid(vaddr); | 942 | unsigned long hash, hpteg; |
894 | unsigned long va = (vsid << 28) | (vaddr & 0x0fffffff); | 943 | unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); |
944 | unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize); | ||
895 | unsigned long mode = _PAGE_ACCESSED | _PAGE_DIRTY | | 945 | unsigned long mode = _PAGE_ACCESSED | _PAGE_DIRTY | |
896 | _PAGE_COHERENT | PP_RWXX | HPTE_R_N; | 946 | _PAGE_COHERENT | PP_RWXX | HPTE_R_N; |
897 | int ret; | 947 | int ret; |
898 | 948 | ||
899 | hash = hpt_hash(va, PAGE_SHIFT); | 949 | hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize); |
900 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | 950 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); |
901 | 951 | ||
902 | ret = ppc_md.hpte_insert(hpteg, va, __pa(vaddr), | 952 | ret = ppc_md.hpte_insert(hpteg, va, __pa(vaddr), |
903 | mode, HPTE_V_BOLTED, mmu_linear_psize); | 953 | mode, HPTE_V_BOLTED, |
954 | mmu_linear_psize, mmu_kernel_ssize); | ||
904 | BUG_ON (ret < 0); | 955 | BUG_ON (ret < 0); |
905 | spin_lock(&linear_map_hash_lock); | 956 | spin_lock(&linear_map_hash_lock); |
906 | BUG_ON(linear_map_hash_slots[lmi] & 0x80); | 957 | BUG_ON(linear_map_hash_slots[lmi] & 0x80); |
@@ -910,10 +961,11 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) | |||
910 | 961 | ||
911 | static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) | 962 | static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) |
912 | { | 963 | { |
913 | unsigned long hash, hidx, slot, vsid = get_kernel_vsid(vaddr); | 964 | unsigned long hash, hidx, slot; |
914 | unsigned long va = (vsid << 28) | (vaddr & 0x0fffffff); | 965 | unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); |
966 | unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize); | ||
915 | 967 | ||
916 | hash = hpt_hash(va, PAGE_SHIFT); | 968 | hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize); |
917 | spin_lock(&linear_map_hash_lock); | 969 | spin_lock(&linear_map_hash_lock); |
918 | BUG_ON(!(linear_map_hash_slots[lmi] & 0x80)); | 970 | BUG_ON(!(linear_map_hash_slots[lmi] & 0x80)); |
919 | hidx = linear_map_hash_slots[lmi] & 0x7f; | 971 | hidx = linear_map_hash_slots[lmi] & 0x7f; |
@@ -923,7 +975,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) | |||
923 | hash = ~hash; | 975 | hash = ~hash; |
924 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 976 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
925 | slot += hidx & _PTEIDX_GROUP_IX; | 977 | slot += hidx & _PTEIDX_GROUP_IX; |
926 | ppc_md.hpte_invalidate(slot, va, mmu_linear_psize, 0); | 978 | ppc_md.hpte_invalidate(slot, va, mmu_linear_psize, mmu_kernel_ssize, 0); |
927 | } | 979 | } |
928 | 980 | ||
929 | void kernel_map_pages(struct page *page, int numpages, int enable) | 981 | void kernel_map_pages(struct page *page, int numpages, int enable) |