diff options
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/gup.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 75 | ||||
-rw-r--r-- | arch/x86/mm/ioremap.c | 22 | ||||
-rw-r--r-- | arch/x86/mm/pat.c | 4 |
4 files changed, 66 insertions, 37 deletions
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index 4ba373c5b8c8..be54176e9eb2 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c | |||
@@ -233,7 +233,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
233 | len = (unsigned long) nr_pages << PAGE_SHIFT; | 233 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
234 | end = start + len; | 234 | end = start + len; |
235 | if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, | 235 | if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, |
236 | start, len))) | 236 | (void __user *)start, len))) |
237 | goto slow_irqon; | 237 | goto slow_irqon; |
238 | 238 | ||
239 | /* | 239 | /* |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index b8e461d49412..9db01db6e3cd 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -350,8 +350,10 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end, | |||
350 | * pagetable pages as RO. So assume someone who pre-setup | 350 | * pagetable pages as RO. So assume someone who pre-setup |
351 | * these mappings are more intelligent. | 351 | * these mappings are more intelligent. |
352 | */ | 352 | */ |
353 | if (pte_val(*pte)) | 353 | if (pte_val(*pte)) { |
354 | pages++; | ||
354 | continue; | 355 | continue; |
356 | } | ||
355 | 357 | ||
356 | if (0) | 358 | if (0) |
357 | printk(" pte=%p addr=%lx pte=%016lx\n", | 359 | printk(" pte=%p addr=%lx pte=%016lx\n", |
@@ -418,8 +420,10 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, | |||
418 | * not differ with respect to page frame and | 420 | * not differ with respect to page frame and |
419 | * attributes. | 421 | * attributes. |
420 | */ | 422 | */ |
421 | if (page_size_mask & (1 << PG_LEVEL_2M)) | 423 | if (page_size_mask & (1 << PG_LEVEL_2M)) { |
424 | pages++; | ||
422 | continue; | 425 | continue; |
426 | } | ||
423 | new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd)); | 427 | new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd)); |
424 | } | 428 | } |
425 | 429 | ||
@@ -499,8 +503,10 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, | |||
499 | * not differ with respect to page frame and | 503 | * not differ with respect to page frame and |
500 | * attributes. | 504 | * attributes. |
501 | */ | 505 | */ |
502 | if (page_size_mask & (1 << PG_LEVEL_1G)) | 506 | if (page_size_mask & (1 << PG_LEVEL_1G)) { |
507 | pages++; | ||
503 | continue; | 508 | continue; |
509 | } | ||
504 | prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud)); | 510 | prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud)); |
505 | } | 511 | } |
506 | 512 | ||
@@ -665,12 +671,13 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, | |||
665 | unsigned long last_map_addr = 0; | 671 | unsigned long last_map_addr = 0; |
666 | unsigned long page_size_mask = 0; | 672 | unsigned long page_size_mask = 0; |
667 | unsigned long start_pfn, end_pfn; | 673 | unsigned long start_pfn, end_pfn; |
674 | unsigned long pos; | ||
668 | 675 | ||
669 | struct map_range mr[NR_RANGE_MR]; | 676 | struct map_range mr[NR_RANGE_MR]; |
670 | int nr_range, i; | 677 | int nr_range, i; |
671 | int use_pse, use_gbpages; | 678 | int use_pse, use_gbpages; |
672 | 679 | ||
673 | printk(KERN_INFO "init_memory_mapping\n"); | 680 | printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); |
674 | 681 | ||
675 | /* | 682 | /* |
676 | * Find space for the kernel direct mapping tables. | 683 | * Find space for the kernel direct mapping tables. |
@@ -704,35 +711,50 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, | |||
704 | 711 | ||
705 | /* head if not big page alignment ?*/ | 712 | /* head if not big page alignment ?*/ |
706 | start_pfn = start >> PAGE_SHIFT; | 713 | start_pfn = start >> PAGE_SHIFT; |
707 | end_pfn = ((start + (PMD_SIZE - 1)) >> PMD_SHIFT) | 714 | pos = start_pfn << PAGE_SHIFT; |
715 | end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT) | ||
708 | << (PMD_SHIFT - PAGE_SHIFT); | 716 | << (PMD_SHIFT - PAGE_SHIFT); |
709 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); | 717 | if (start_pfn < end_pfn) { |
718 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); | ||
719 | pos = end_pfn << PAGE_SHIFT; | ||
720 | } | ||
710 | 721 | ||
711 | /* big page (2M) range*/ | 722 | /* big page (2M) range*/ |
712 | start_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT) | 723 | start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT) |
713 | << (PMD_SHIFT - PAGE_SHIFT); | 724 | << (PMD_SHIFT - PAGE_SHIFT); |
714 | end_pfn = ((start + (PUD_SIZE - 1))>>PUD_SHIFT) | 725 | end_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT) |
715 | << (PUD_SHIFT - PAGE_SHIFT); | 726 | << (PUD_SHIFT - PAGE_SHIFT); |
716 | if (end_pfn > ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT))) | 727 | if (end_pfn > ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT))) |
717 | end_pfn = ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT)); | 728 | end_pfn = ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT)); |
718 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | 729 | if (start_pfn < end_pfn) { |
719 | page_size_mask & (1<<PG_LEVEL_2M)); | 730 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, |
731 | page_size_mask & (1<<PG_LEVEL_2M)); | ||
732 | pos = end_pfn << PAGE_SHIFT; | ||
733 | } | ||
720 | 734 | ||
721 | /* big page (1G) range */ | 735 | /* big page (1G) range */ |
722 | start_pfn = end_pfn; | 736 | start_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT) |
723 | end_pfn = (end>>PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); | 737 | << (PUD_SHIFT - PAGE_SHIFT); |
724 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | 738 | end_pfn = (end >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); |
739 | if (start_pfn < end_pfn) { | ||
740 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | ||
725 | page_size_mask & | 741 | page_size_mask & |
726 | ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G))); | 742 | ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G))); |
743 | pos = end_pfn << PAGE_SHIFT; | ||
744 | } | ||
727 | 745 | ||
728 | /* tail is not big page (1G) alignment */ | 746 | /* tail is not big page (1G) alignment */ |
729 | start_pfn = end_pfn; | 747 | start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT) |
730 | end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); | 748 | << (PMD_SHIFT - PAGE_SHIFT); |
731 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | 749 | end_pfn = (end >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); |
732 | page_size_mask & (1<<PG_LEVEL_2M)); | 750 | if (start_pfn < end_pfn) { |
751 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, | ||
752 | page_size_mask & (1<<PG_LEVEL_2M)); | ||
753 | pos = end_pfn << PAGE_SHIFT; | ||
754 | } | ||
733 | 755 | ||
734 | /* tail is not big page (2M) alignment */ | 756 | /* tail is not big page (2M) alignment */ |
735 | start_pfn = end_pfn; | 757 | start_pfn = pos>>PAGE_SHIFT; |
736 | end_pfn = end>>PAGE_SHIFT; | 758 | end_pfn = end>>PAGE_SHIFT; |
737 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); | 759 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); |
738 | 760 | ||
@@ -831,12 +853,12 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
831 | unsigned long nr_pages = size >> PAGE_SHIFT; | 853 | unsigned long nr_pages = size >> PAGE_SHIFT; |
832 | int ret; | 854 | int ret; |
833 | 855 | ||
834 | last_mapped_pfn = init_memory_mapping(start, start + size-1); | 856 | last_mapped_pfn = init_memory_mapping(start, start + size); |
835 | if (last_mapped_pfn > max_pfn_mapped) | 857 | if (last_mapped_pfn > max_pfn_mapped) |
836 | max_pfn_mapped = last_mapped_pfn; | 858 | max_pfn_mapped = last_mapped_pfn; |
837 | 859 | ||
838 | ret = __add_pages(zone, start_pfn, nr_pages); | 860 | ret = __add_pages(zone, start_pfn, nr_pages); |
839 | WARN_ON(1); | 861 | WARN_ON_ONCE(ret); |
840 | 862 | ||
841 | return ret; | 863 | return ret; |
842 | } | 864 | } |
@@ -878,6 +900,7 @@ static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, | |||
878 | void __init mem_init(void) | 900 | void __init mem_init(void) |
879 | { | 901 | { |
880 | long codesize, reservedpages, datasize, initsize; | 902 | long codesize, reservedpages, datasize, initsize; |
903 | unsigned long absent_pages; | ||
881 | 904 | ||
882 | start_periodic_check_for_corruption(); | 905 | start_periodic_check_for_corruption(); |
883 | 906 | ||
@@ -893,8 +916,9 @@ void __init mem_init(void) | |||
893 | #else | 916 | #else |
894 | totalram_pages = free_all_bootmem(); | 917 | totalram_pages = free_all_bootmem(); |
895 | #endif | 918 | #endif |
896 | reservedpages = max_pfn - totalram_pages - | 919 | |
897 | absent_pages_in_range(0, max_pfn); | 920 | absent_pages = absent_pages_in_range(0, max_pfn); |
921 | reservedpages = max_pfn - totalram_pages - absent_pages; | ||
898 | after_bootmem = 1; | 922 | after_bootmem = 1; |
899 | 923 | ||
900 | codesize = (unsigned long) &_etext - (unsigned long) &_text; | 924 | codesize = (unsigned long) &_etext - (unsigned long) &_text; |
@@ -911,10 +935,11 @@ void __init mem_init(void) | |||
911 | VSYSCALL_END - VSYSCALL_START); | 935 | VSYSCALL_END - VSYSCALL_START); |
912 | 936 | ||
913 | printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " | 937 | printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " |
914 | "%ldk reserved, %ldk data, %ldk init)\n", | 938 | "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n", |
915 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), | 939 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), |
916 | max_pfn << (PAGE_SHIFT-10), | 940 | max_pfn << (PAGE_SHIFT-10), |
917 | codesize >> 10, | 941 | codesize >> 10, |
942 | absent_pages << (PAGE_SHIFT-10), | ||
918 | reservedpages << (PAGE_SHIFT-10), | 943 | reservedpages << (PAGE_SHIFT-10), |
919 | datasize >> 10, | 944 | datasize >> 10, |
920 | initsize >> 10); | 945 | initsize >> 10); |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index ae71e11eb3e5..d4c4307ff3e0 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -387,7 +387,7 @@ static void __iomem *ioremap_default(resource_size_t phys_addr, | |||
387 | unsigned long size) | 387 | unsigned long size) |
388 | { | 388 | { |
389 | unsigned long flags; | 389 | unsigned long flags; |
390 | void *ret; | 390 | void __iomem *ret; |
391 | int err; | 391 | int err; |
392 | 392 | ||
393 | /* | 393 | /* |
@@ -399,11 +399,11 @@ static void __iomem *ioremap_default(resource_size_t phys_addr, | |||
399 | if (err < 0) | 399 | if (err < 0) |
400 | return NULL; | 400 | return NULL; |
401 | 401 | ||
402 | ret = (void *) __ioremap_caller(phys_addr, size, flags, | 402 | ret = __ioremap_caller(phys_addr, size, flags, |
403 | __builtin_return_address(0)); | 403 | __builtin_return_address(0)); |
404 | 404 | ||
405 | free_memtype(phys_addr, phys_addr + size); | 405 | free_memtype(phys_addr, phys_addr + size); |
406 | return (void __iomem *)ret; | 406 | return ret; |
407 | } | 407 | } |
408 | 408 | ||
409 | void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size, | 409 | void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size, |
@@ -622,7 +622,7 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx) | |||
622 | __early_set_fixmap(idx, 0, __pgprot(0)); | 622 | __early_set_fixmap(idx, 0, __pgprot(0)); |
623 | } | 623 | } |
624 | 624 | ||
625 | static void *prev_map[FIX_BTMAPS_SLOTS] __initdata; | 625 | static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata; |
626 | static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata; | 626 | static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata; |
627 | static int __init check_early_ioremap_leak(void) | 627 | static int __init check_early_ioremap_leak(void) |
628 | { | 628 | { |
@@ -645,7 +645,7 @@ static int __init check_early_ioremap_leak(void) | |||
645 | } | 645 | } |
646 | late_initcall(check_early_ioremap_leak); | 646 | late_initcall(check_early_ioremap_leak); |
647 | 647 | ||
648 | static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) | 648 | static void __init __iomem *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) |
649 | { | 649 | { |
650 | unsigned long offset, last_addr; | 650 | unsigned long offset, last_addr; |
651 | unsigned int nrpages; | 651 | unsigned int nrpages; |
@@ -713,23 +713,23 @@ static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, | |||
713 | if (early_ioremap_debug) | 713 | if (early_ioremap_debug) |
714 | printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0)); | 714 | printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0)); |
715 | 715 | ||
716 | prev_map[slot] = (void *) (offset + fix_to_virt(idx0)); | 716 | prev_map[slot] = (void __iomem *)(offset + fix_to_virt(idx0)); |
717 | return prev_map[slot]; | 717 | return prev_map[slot]; |
718 | } | 718 | } |
719 | 719 | ||
720 | /* Remap an IO device */ | 720 | /* Remap an IO device */ |
721 | void __init *early_ioremap(unsigned long phys_addr, unsigned long size) | 721 | void __init __iomem *early_ioremap(unsigned long phys_addr, unsigned long size) |
722 | { | 722 | { |
723 | return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO); | 723 | return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO); |
724 | } | 724 | } |
725 | 725 | ||
726 | /* Remap memory */ | 726 | /* Remap memory */ |
727 | void __init *early_memremap(unsigned long phys_addr, unsigned long size) | 727 | void __init __iomem *early_memremap(unsigned long phys_addr, unsigned long size) |
728 | { | 728 | { |
729 | return __early_ioremap(phys_addr, size, PAGE_KERNEL); | 729 | return __early_ioremap(phys_addr, size, PAGE_KERNEL); |
730 | } | 730 | } |
731 | 731 | ||
732 | void __init early_iounmap(void *addr, unsigned long size) | 732 | void __init early_iounmap(void __iomem *addr, unsigned long size) |
733 | { | 733 | { |
734 | unsigned long virt_addr; | 734 | unsigned long virt_addr; |
735 | unsigned long offset; | 735 | unsigned long offset; |
@@ -779,7 +779,7 @@ void __init early_iounmap(void *addr, unsigned long size) | |||
779 | --idx; | 779 | --idx; |
780 | --nrpages; | 780 | --nrpages; |
781 | } | 781 | } |
782 | prev_map[slot] = 0; | 782 | prev_map[slot] = NULL; |
783 | } | 783 | } |
784 | 784 | ||
785 | void __this_fixmap_does_not_exist(void) | 785 | void __this_fixmap_does_not_exist(void) |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 738fd0f24958..eb1bf000d12e 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -481,12 +481,16 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) | |||
481 | return 1; | 481 | return 1; |
482 | } | 482 | } |
483 | #else | 483 | #else |
484 | /* This check is needed to avoid cache aliasing when PAT is enabled */ | ||
484 | static inline int range_is_allowed(unsigned long pfn, unsigned long size) | 485 | static inline int range_is_allowed(unsigned long pfn, unsigned long size) |
485 | { | 486 | { |
486 | u64 from = ((u64)pfn) << PAGE_SHIFT; | 487 | u64 from = ((u64)pfn) << PAGE_SHIFT; |
487 | u64 to = from + size; | 488 | u64 to = from + size; |
488 | u64 cursor = from; | 489 | u64 cursor = from; |
489 | 490 | ||
491 | if (!pat_enabled) | ||
492 | return 1; | ||
493 | |||
490 | while (cursor < to) { | 494 | while (cursor < to) { |
491 | if (!devmem_is_allowed(pfn)) { | 495 | if (!devmem_is_allowed(pfn)) { |
492 | printk(KERN_INFO | 496 | printk(KERN_INFO |