[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v7 2/8] xen/arm: Split MMU system SMP MM bringup code to mmu/smpboot.c
Move the code related to secondary page table initialization, clear boot page tables and the global variable definitions of these boot page tables from arch/arm/mm.c to arch/arm/mmu/smpboot.c Since arm32 global variable cpu0_pgtable will be used by both arch/arm/mm.c and arch/arm/mmu/smpboot.c, to avoid exporting this variable, change the variable usage in arch/arm/mmu/smpboot.c to per_cpu(xen_pgtable, 0). To avoid exposing global variable phys_offset, use virt_to_maddr() to calculate init_ttbr for arm64. Take the opportunity to fix the in-code comment coding styles when possible. Signed-off-by: Henry Wang <Henry.Wang@xxxxxxx> Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx> --- v7: - Do not export cpu0_pgtable, replace the variable usage in arch/arm/mmu/smpboot.c to per_cpu(xen_pgtable, 0). - Also move global variable init_ttbr to arch/arm/mmu/smpboot.c. - Use virt_to_maddr() instead of phys_offset to calculate init_ttbr in arm64 implementation of init_secondary_pagetables(). v6: - Rework the original patch "[v5,07/13] xen/arm: Extract MMU-specific code", only split the smpboot related code out in this patch. --- xen/arch/arm/mm.c | 104 ------------------------------- xen/arch/arm/mmu/Makefile | 1 + xen/arch/arm/mmu/smpboot.c | 124 +++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 104 deletions(-) create mode 100644 xen/arch/arm/mmu/smpboot.c diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index fd02493564..b7eb3a6e08 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -27,39 +27,6 @@ #undef mfn_to_virt #define mfn_to_virt(mfn) __mfn_to_virt(mfn_x(mfn)) -/* Static start-of-day pagetables that we use before the allocators - * are up. These are used by all CPUs during bringup before switching - * to the CPUs own pagetables. - * - * These pagetables have a very simple structure. They include: - * - XEN_VIRT_SIZE worth of L3 mappings of xen at XEN_VIRT_START, boot_first - * and boot_second are used to populate the tables down to boot_third - * which contains the actual mapping. - * - a 1:1 mapping of xen at its current physical address. This uses a - * section mapping at whichever of boot_{pgtable,first,second} - * covers that physical address. - * - * For the boot CPU these mappings point to the address where Xen was - * loaded by the bootloader. For secondary CPUs they point to the - * relocated copy of Xen for the benefit of secondary CPUs. - * - * In addition to the above for the boot CPU the device-tree is - * initially mapped in the boot misc slot. This mapping is not present - * for secondary CPUs. - * - * Finally, if EARLY_PRINTK is enabled then xen_fixmap will be mapped - * by the CPU once it has moved off the 1:1 mapping. - */ -DEFINE_BOOT_PAGE_TABLE(boot_pgtable); -#ifdef CONFIG_ARM_64 -DEFINE_BOOT_PAGE_TABLE(boot_first); -DEFINE_BOOT_PAGE_TABLE(boot_first_id); -#endif -DEFINE_BOOT_PAGE_TABLE(boot_second_id); -DEFINE_BOOT_PAGE_TABLE(boot_third_id); -DEFINE_BOOT_PAGE_TABLE(boot_second); -DEFINE_BOOT_PAGE_TABLES(boot_third, XEN_NR_ENTRIES(2)); - /* Main runtime page tables */ /* @@ -94,9 +61,6 @@ DEFINE_BOOT_PAGE_TABLE(xen_fixmap); */ static DEFINE_PAGE_TABLES(xen_xenmap, XEN_NR_ENTRIES(2)); -/* Non-boot CPUs use this to find the correct pagetables. */ -uint64_t init_ttbr; - static paddr_t phys_offset; /* Limits of the Xen heap */ @@ -284,13 +248,6 @@ static void xen_pt_enforce_wnx(void) flush_xen_tlb_local(); } -/* Clear a translation table and clean & invalidate the cache */ -static void clear_table(void *table) -{ - clear_page(table); - clean_and_invalidate_dcache_va_range(table, PAGE_SIZE); -} - /* Boot-time pagetable setup. * Changes here may need matching changes in head.S */ void __init setup_pagetables(unsigned long boot_phys_offset) @@ -369,67 +326,6 @@ void __init setup_pagetables(unsigned long boot_phys_offset) #endif } -static void clear_boot_pagetables(void) -{ - /* - * Clear the copy of the boot pagetables. Each secondary CPU - * rebuilds these itself (see head.S). - */ - clear_table(boot_pgtable); -#ifdef CONFIG_ARM_64 - clear_table(boot_first); - clear_table(boot_first_id); -#endif - clear_table(boot_second); - clear_table(boot_third); -} - -#ifdef CONFIG_ARM_64 -int init_secondary_pagetables(int cpu) -{ - clear_boot_pagetables(); - - /* Set init_ttbr for this CPU coming up. All CPus share a single setof - * pagetables, but rewrite it each time for consistency with 32 bit. */ - init_ttbr = (uintptr_t) xen_pgtable + phys_offset; - clean_dcache(init_ttbr); - return 0; -} -#else -int init_secondary_pagetables(int cpu) -{ - lpae_t *first; - - first = alloc_xenheap_page(); /* root == first level on 32-bit 3-level trie */ - - if ( !first ) - { - printk("CPU%u: Unable to allocate the first page-table\n", cpu); - return -ENOMEM; - } - - /* Initialise root pagetable from root of boot tables */ - memcpy(first, cpu0_pgtable, PAGE_SIZE); - per_cpu(xen_pgtable, cpu) = first; - - if ( !init_domheap_mappings(cpu) ) - { - printk("CPU%u: Unable to prepare the domheap page-tables\n", cpu); - per_cpu(xen_pgtable, cpu) = NULL; - free_xenheap_page(first); - return -ENOMEM; - } - - clear_boot_pagetables(); - - /* Set init_ttbr for this CPU coming up */ - init_ttbr = __pa(first); - clean_dcache(init_ttbr); - - return 0; -} -#endif - /* MMU setup for secondary CPUS (which already have paging enabled) */ void mmu_init_secondary_cpu(void) { diff --git a/xen/arch/arm/mmu/Makefile b/xen/arch/arm/mmu/Makefile index bdfc2e077d..0e82015ee1 100644 --- a/xen/arch/arm/mmu/Makefile +++ b/xen/arch/arm/mmu/Makefile @@ -1 +1,2 @@ obj-y += pt.o +obj-y += smpboot.o diff --git a/xen/arch/arm/mmu/smpboot.c b/xen/arch/arm/mmu/smpboot.c new file mode 100644 index 0000000000..eac805c74c --- /dev/null +++ b/xen/arch/arm/mmu/smpboot.c @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * xen/arch/arm/mmu/smpboot.c + * + * MMU system secondary CPUs MM bringup code. + */ + +#include <xen/domain_page.h> + +/* + * Static start-of-day pagetables that we use before the allocators + * are up. These are used by all CPUs during bringup before switching + * to the CPUs own pagetables. + * + * These pagetables have a very simple structure. They include: + * - XEN_VIRT_SIZE worth of L3 mappings of xen at XEN_VIRT_START, boot_first + * and boot_second are used to populate the tables down to boot_third + * which contains the actual mapping. + * - a 1:1 mapping of xen at its current physical address. This uses a + * section mapping at whichever of boot_{pgtable,first,second} + * covers that physical address. + * + * For the boot CPU these mappings point to the address where Xen was + * loaded by the bootloader. For secondary CPUs they point to the + * relocated copy of Xen for the benefit of secondary CPUs. + * + * In addition to the above for the boot CPU the device-tree is + * initially mapped in the boot misc slot. This mapping is not present + * for secondary CPUs. + * + * Finally, if EARLY_PRINTK is enabled then xen_fixmap will be mapped + * by the CPU once it has moved off the 1:1 mapping. + */ +DEFINE_BOOT_PAGE_TABLE(boot_pgtable); +#ifdef CONFIG_ARM_64 +DEFINE_BOOT_PAGE_TABLE(boot_first); +DEFINE_BOOT_PAGE_TABLE(boot_first_id); +#endif +DEFINE_BOOT_PAGE_TABLE(boot_second_id); +DEFINE_BOOT_PAGE_TABLE(boot_third_id); +DEFINE_BOOT_PAGE_TABLE(boot_second); +DEFINE_BOOT_PAGE_TABLES(boot_third, XEN_NR_ENTRIES(2)); + +/* Non-boot CPUs use this to find the correct pagetables. */ +uint64_t init_ttbr; + +/* Clear a translation table and clean & invalidate the cache */ +static void clear_table(void *table) +{ + clear_page(table); + clean_and_invalidate_dcache_va_range(table, PAGE_SIZE); +} + +static void clear_boot_pagetables(void) +{ + /* + * Clear the copy of the boot pagetables. Each secondary CPU + * rebuilds these itself (see head.S). + */ + clear_table(boot_pgtable); +#ifdef CONFIG_ARM_64 + clear_table(boot_first); + clear_table(boot_first_id); +#endif + clear_table(boot_second); + clear_table(boot_third); +} + +#ifdef CONFIG_ARM_64 +int init_secondary_pagetables(int cpu) +{ + clear_boot_pagetables(); + + /* + * Set init_ttbr for this CPU coming up. All CPus share a single setof + * pagetables, but rewrite it each time for consistency with 32 bit. + */ + init_ttbr = virt_to_maddr((uintptr_t) xen_pgtable); + clean_dcache(init_ttbr); + return 0; +} +#else +int init_secondary_pagetables(int cpu) +{ + lpae_t *first; + + first = alloc_xenheap_page(); /* root == first level on 32-bit 3-level trie */ + + if ( !first ) + { + printk("CPU%u: Unable to allocate the first page-table\n", cpu); + return -ENOMEM; + } + + /* Initialise root pagetable from root of boot tables */ + memcpy(first, per_cpu(xen_pgtable, 0), PAGE_SIZE); + per_cpu(xen_pgtable, cpu) = first; + + if ( !init_domheap_mappings(cpu) ) + { + printk("CPU%u: Unable to prepare the domheap page-tables\n", cpu); + per_cpu(xen_pgtable, cpu) = NULL; + free_xenheap_page(first); + return -ENOMEM; + } + + clear_boot_pagetables(); + + /* Set init_ttbr for this CPU coming up */ + init_ttbr = __pa(first); + clean_dcache(init_ttbr); + + return 0; +} +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ -- 2.25.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |