aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2015-09-15 08:59:14 -0400
committerard <ard.biesheuvel@linaro.org>2015-12-13 13:18:29 -0500
commitf579b2b10412771ad5eaa785ddaa7b62b97a6e8d (patch)
tree4f002f657e73496ab358f6236e41df0e820d2402
parent1bdb2d4ee05f2fdad4d8a82d7e0ce8d6d91ec4ac (diff)
ARM: factor out allocation routine from __create_mapping()
To allow __create_mapping() to be used for populating UEFI Runtime Services page tables, factor out the allocation routine 'early_alloc' and pass it down as a function pointer into alloc_init_[pud|pmd|pte]. This way, new users of __create_mapping() can supply another allocation function. Tested-by: Ryan Harkin <ryan.harkin@linaro.org> Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-rw-r--r--arch/arm/mm/mmu.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 3100de92148b..87dc49dbe231 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -724,21 +724,30 @@ static void __init *early_alloc(unsigned long sz)
724 return early_alloc_aligned(sz, sz); 724 return early_alloc_aligned(sz, sz);
725} 725}
726 726
727static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) 727static pte_t * __init pte_alloc(pmd_t *pmd, unsigned long addr,
728 unsigned long prot,
729 void *(*alloc)(unsigned long sz))
728{ 730{
729 if (pmd_none(*pmd)) { 731 if (pmd_none(*pmd)) {
730 pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE); 732 pte_t *pte = alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
731 __pmd_populate(pmd, __pa(pte), prot); 733 __pmd_populate(pmd, __pa(pte), prot);
732 } 734 }
733 BUG_ON(pmd_bad(*pmd)); 735 BUG_ON(pmd_bad(*pmd));
734 return pte_offset_kernel(pmd, addr); 736 return pte_offset_kernel(pmd, addr);
735} 737}
736 738
739static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr,
740 unsigned long prot)
741{
742 return pte_alloc(pmd, addr, prot, early_alloc);
743}
744
737static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, 745static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
738 unsigned long end, unsigned long pfn, 746 unsigned long end, unsigned long pfn,
739 const struct mem_type *type) 747 const struct mem_type *type,
748 void *(*alloc)(unsigned long sz))
740{ 749{
741 pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1); 750 pte_t *pte = pte_alloc(pmd, addr, type->prot_l1, alloc);
742 do { 751 do {
743 set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0); 752 set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
744 pfn++; 753 pfn++;
@@ -774,7 +783,8 @@ static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
774 783
775static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, 784static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
776 unsigned long end, phys_addr_t phys, 785 unsigned long end, phys_addr_t phys,
777 const struct mem_type *type) 786 const struct mem_type *type,
787 void *(*alloc)(unsigned long sz))
778{ 788{
779 pmd_t *pmd = pmd_offset(pud, addr); 789 pmd_t *pmd = pmd_offset(pud, addr);
780 unsigned long next; 790 unsigned long next;
@@ -795,7 +805,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
795 __map_init_section(pmd, addr, next, phys, type); 805 __map_init_section(pmd, addr, next, phys, type);
796 } else { 806 } else {
797 alloc_init_pte(pmd, addr, next, 807 alloc_init_pte(pmd, addr, next,
798 __phys_to_pfn(phys), type); 808 __phys_to_pfn(phys), type, alloc);
799 } 809 }
800 810
801 phys += next - addr; 811 phys += next - addr;
@@ -805,14 +815,15 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
805 815
806static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, 816static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
807 unsigned long end, phys_addr_t phys, 817 unsigned long end, phys_addr_t phys,
808 const struct mem_type *type) 818 const struct mem_type *type,
819 void *(*alloc)(unsigned long sz))
809{ 820{
810 pud_t *pud = pud_offset(pgd, addr); 821 pud_t *pud = pud_offset(pgd, addr);
811 unsigned long next; 822 unsigned long next;
812 823
813 do { 824 do {
814 next = pud_addr_end(addr, end); 825 next = pud_addr_end(addr, end);
815 alloc_init_pmd(pud, addr, next, phys, type); 826 alloc_init_pmd(pud, addr, next, phys, type, alloc);
816 phys += next - addr; 827 phys += next - addr;
817 } while (pud++, addr = next, addr != end); 828 } while (pud++, addr = next, addr != end);
818} 829}
@@ -877,7 +888,8 @@ static void __init create_36bit_mapping(struct mm_struct *mm,
877} 888}
878#endif /* !CONFIG_ARM_LPAE */ 889#endif /* !CONFIG_ARM_LPAE */
879 890
880static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md) 891static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md,
892 void *(*alloc)(unsigned long sz))
881{ 893{
882 unsigned long addr, length, end; 894 unsigned long addr, length, end;
883 phys_addr_t phys; 895 phys_addr_t phys;
@@ -911,7 +923,7 @@ static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md)
911 do { 923 do {
912 unsigned long next = pgd_addr_end(addr, end); 924 unsigned long next = pgd_addr_end(addr, end);
913 925
914 alloc_init_pud(pgd, addr, next, phys, type); 926 alloc_init_pud(pgd, addr, next, phys, type, alloc);
915 927
916 phys += next - addr; 928 phys += next - addr;
917 addr = next; 929 addr = next;
@@ -940,7 +952,7 @@ static void __init create_mapping(struct map_desc *md)
940 (long long)__pfn_to_phys((u64)md->pfn), md->virtual); 952 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
941 } 953 }
942 954
943 __create_mapping(&init_mm, md); 955 __create_mapping(&init_mm, md, early_alloc);
944} 956}
945 957
946/* 958/*