[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 6/9] xen/arm: Support dtb /memreserve/ regions
This requires a mapping of the DTB during setup_mm. Previously this was in the BOOT_MISC slot, which is clobbered by setup_pagetables. Split it out into its own slot which can be preserved. Also handle these regions as part of consider_modules() and when adding pages to the heaps to ensure we do not locate any part of Xen or the heaps over them. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v2: drop accidentally included debug prints fixed handling of avoid reserved regions with heaps don't discard initial modules, since the FDT can (but is not required to) be reserved --- xen/arch/arm/arm32/head.S | 2 +- xen/arch/arm/arm64/head.S | 2 +- xen/arch/arm/mm.c | 10 ++++++- xen/arch/arm/setup.c | 67 +++++++++++++++++++++++++++++++++++++++--- xen/arch/arm/traps.c | 1 - xen/common/device_tree.c | 13 +++++++- xen/include/asm-arm/config.h | 7 +++-- xen/include/asm-arm/mm.h | 2 ++ 8 files changed, 92 insertions(+), 12 deletions(-) diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S index 79e95b6..5072e2a 100644 --- a/xen/arch/arm/arm32/head.S +++ b/xen/arch/arm/arm32/head.S @@ -301,7 +301,7 @@ cpu_init_done: orr r2, r2, #PT_UPPER(MEM) orr r2, r2, #PT_LOWER(MEM) /* r2:r3 := 2MB RAM incl. DTB */ add r4, r4, #8 - strd r2, r3, [r1, r4] /* Map it in the early boot slot */ + strd r2, r3, [r1, r4] /* Map it in the early fdt slot */ pt_ready: PRINT("- Turning on paging -\r\n") diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index 21b7e4d..33ff489 100644 --- a/xen/arch/arm/arm64/head.S +++ b/xen/arch/arm/arm64/head.S @@ -255,7 +255,7 @@ skip_bss: mov x3, #PT_MEM /* x2 := 2MB RAM incl. DTB */ orr x2, x2, x3 add x4, x4, #8 - str x2, [x1, x4] /* Map it in the early boot slot */ + str x2, [x1, x4] /* Map it in the early fdt slot */ pt_ready: PRINT("- Turning on paging -\r\n") diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 69c157a..86e3207 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -361,6 +361,13 @@ static inline lpae_t pte_of_xenaddr(vaddr_t va) return mfn_to_xen_entry(mfn); } +void __init remove_early_mappings(void) +{ + lpae_t pte = {0}; + write_pte(xen_second + second_table_offset(BOOT_FDT_VIRT_START), pte); + flush_xen_data_tlb_range_va(BOOT_FDT_VIRT_START, SECOND_SIZE); +} + /* Boot-time pagetable setup. * Changes here may need matching changes in head.S */ void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr) @@ -401,7 +408,8 @@ void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr) p[second_linear_offset(va)].bits = 0; } for ( i = 0; i < 4 * LPAE_ENTRIES; i++) - if ( p[i].pt.valid ) + /* The FDT is not relocated */ + if ( p[i].pt.valid && i != second_linear_offset(BOOT_FDT_VIRT_START) ) p[i].pt.base += (phys_offset - boot_phys_offset) >> PAGE_SHIFT; /* Change pagetables to the copy in the relocated Xen */ diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 0d9eaf7..5a47bda 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -35,6 +35,7 @@ #include <xen/cpu.h> #include <xen/pfn.h> #include <xen/vmap.h> +#include <xen/libfdt/libfdt.h> #include <asm/page.h> #include <asm/current.h> #include <asm/setup.h> @@ -147,6 +148,33 @@ static void __init processor_id(void) } } +static void dt_unreserved_regions(paddr_t s, paddr_t e, + void (*cb)(paddr_t, paddr_t), int first) +{ + int i, nr = fdt_num_mem_rsv(device_tree_flattened); + + for ( i = first; i < nr ; i++ ) + { + paddr_t r_s, r_e; + + if ( fdt_get_mem_rsv(device_tree_flattened, i, &r_s, &r_e ) < 0 ) + /* If we can't read it, pretend it doesn't exist... */ + continue; + + r_e += r_s; /* fdt_get_mem_rsc returns length */ + + + if ( s < r_e && r_s < e ) + { + dt_unreserved_regions(r_e, e, cb, i+1); + dt_unreserved_regions(s, r_s, cb, i+1); + return; + } + } + + cb(s, e); +} + void __init discard_initial_modules(void) { struct dt_module_info *mi = &early_info.modules; @@ -157,10 +185,12 @@ void __init discard_initial_modules(void) paddr_t s = mi->module[i].start; paddr_t e = s + PAGE_ALIGN(mi->module[i].size); - init_domheap_pages(s, e); + dt_unreserved_regions(s, e, init_domheap_pages, 0); } mi->nr_mods = 0; + + remove_early_mappings(); } /* @@ -177,6 +207,7 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e, { const struct dt_module_info *mi = &early_info.modules; int i; + int nr_rsvd; s = (s+align-1) & ~(align-1); e = e & ~(align-1); @@ -184,6 +215,7 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e, if ( s > e || e - s < size ) return 0; + /* First check the boot modules */ for ( i = first_mod; i <= mi->nr_mods; i++ ) { paddr_t mod_s = mi->module[i].start; @@ -199,6 +231,32 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e, } } + /* Now check any fdt reserved areas. */ + + nr_rsvd = fdt_num_mem_rsv(device_tree_flattened); + + for ( ; i < mi->nr_mods + nr_rsvd; i++ ) + { + paddr_t mod_s, mod_e; + + if ( fdt_get_mem_rsv(device_tree_flattened, + i - mi->nr_mods, + &mod_s, &mod_e ) < 0 ) + /* If we can't read it, pretend it doesn't exist... */ + continue; + + /* fdt_get_mem_rsv returns length */ + mod_e += mod_s; + + if ( s < mod_e && mod_s < e ) + { + mod_e = consider_modules(mod_e, e, size, align, i+1); + if ( mod_e ) + return mod_e; + + return consider_modules(s, mod_s, size, align, i+1); + } + } return e; } @@ -226,6 +284,7 @@ static paddr_t __init next_module(paddr_t s, paddr_t *n) lowest = mod_s; *n = mod_e; } + return lowest; } @@ -401,7 +460,7 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) n = pfn_to_paddr(xenheap_mfn_start+xenheap_pages); } - init_boot_pages(s, e); + dt_unreserved_regions(s, e, init_boot_pages, 0); s = n; } @@ -460,7 +519,7 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) xenheap_mfn_end = e; - init_boot_pages(s, e); + dt_unreserved_regions(s, e, init_boot_pages, 0); s = n; } } @@ -524,7 +583,7 @@ void __init start_xen(unsigned long boot_phys_offset, smp_clear_cpu_maps(); /* This is mapped by head.S */ - device_tree_flattened = (void *)BOOT_MISC_VIRT_START + device_tree_flattened = (void *)BOOT_FDT_VIRT_START + (fdt_paddr & ((1 << SECOND_SHIFT) - 1)); fdt_size = device_tree_early_init(device_tree_flattened, fdt_paddr); diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 0e9a141..aacbd18 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -810,7 +810,6 @@ void vcpu_show_execution_state(struct vcpu *v) void do_unexpected_trap(const char *msg, struct cpu_user_regs *regs) { - printk("CPU%d: Unexpected Trap: %s\n", smp_processor_id(), msg); show_execution_state(regs); while(1); } diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c index 9e0c224..132a2bd 100644 --- a/xen/common/device_tree.c +++ b/xen/common/device_tree.c @@ -489,7 +489,7 @@ static void __init early_print_info(void) { struct dt_mem_info *mi = &early_info.mem; struct dt_module_info *mods = &early_info.modules; - int i; + int i, nr_rsvd; for ( i = 0; i < mi->nr_banks; i++ ) early_printk("RAM: %"PRIpaddr" - %"PRIpaddr"\n", @@ -502,6 +502,17 @@ static void __init early_print_info(void) mods->module[i].start, mods->module[i].start + mods->module[i].size, mods->module[i].cmdline); + nr_rsvd = fdt_num_mem_rsv(device_tree_flattened); + for ( i = 0; i < nr_rsvd; i++ ) + { + paddr_t s, e; + if ( fdt_get_mem_rsv(device_tree_flattened, i, &s, &e) < 0 ) + continue; + /* fdt_get_mem_rsv returns length */ + e += s; + early_printk(" RESVD[%d]: %"PRIpaddr" - %"PRIpaddr"\n", + i, s, e); + } } /** diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h index 624c73e..efeb952 100644 --- a/xen/include/asm-arm/config.h +++ b/xen/include/asm-arm/config.h @@ -80,10 +80,10 @@ * 0 - 2M Unmapped * 2M - 4M Xen text, data, bss * 4M - 6M Fixmap: special-purpose 4K mapping slots - * 6M - 8M Early boot misc (see below) + * 6M - 8M Early boot mapping of FDT + * 8M - 10M Early boot misc (see below) * * The early boot misc area is used: - * - in head.S for the DTB for device_tree_early_init(). * - in setup_pagetables() when relocating Xen. * * ARM32 layout: @@ -116,7 +116,8 @@ #define XEN_VIRT_START _AT(vaddr_t,0x00200000) #define FIXMAP_ADDR(n) (_AT(vaddr_t,0x00400000) + (n) * PAGE_SIZE) -#define BOOT_MISC_VIRT_START _AT(vaddr_t,0x00600000) +#define BOOT_FDT_VIRT_START _AT(vaddr_t,0x00600000) +#define BOOT_MISC_VIRT_START _AT(vaddr_t,0x00800000) #define HYPERVISOR_VIRT_START XEN_VIRT_START diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h index 97c2ee0..467687a 100644 --- a/xen/include/asm-arm/mm.h +++ b/xen/include/asm-arm/mm.h @@ -155,6 +155,8 @@ extern unsigned long total_pages; /* Boot-time pagetable setup */ extern void setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr); +/* Remove early mappings */ +extern void remove_early_mappings(void); /* Allocate and initialise pagetables for a secondary CPU */ extern int __cpuinit init_secondary_pagetables(int cpu); /* Switch secondary CPUS to its own pagetables and finalise MMU setup */ -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |