:p
atchew
Login
In this serie I've taken out patches from the R82 branch already in the ML[1] and some new patches I've done based on the current status of staging that will not impact the current Armv8-R earlyboot work. [1] https://patchwork.kernel.org/project/xen-devel/cover/20230626033443.2943270-1-Penny.Zheng@arm.com/ Luca Fancellu (3): common/vmap: Fall back to simple allocator when !HAS_VMAP arm/setup: Move MMU specific extern declarations to mmu/setup.h xen/arm: Use vmap_contig instead of __vmap where it's possible Penny Zheng (1): xen/arm: do not give memory back to static heap xen/arch/arm/alternative.c | 3 +- xen/arch/arm/arm32/mmu/mm.c | 4 +- xen/arch/arm/cpuerrata.c | 5 +-- xen/arch/arm/include/asm/mmu/setup.h | 31 ++++++++++++++ xen/arch/arm/include/asm/setup.h | 20 +++------ xen/arch/arm/kernel.c | 9 ++-- xen/arch/arm/livepatch.c | 3 +- xen/arch/arm/mmu/setup.c | 8 +++- xen/arch/arm/setup.c | 27 ++++++------ xen/common/device-tree/bootfdt.c | 4 +- xen/common/device-tree/bootinfo.c | 2 +- xen/common/page_alloc.c | 5 +++ xen/include/xen/bootfdt.h | 14 ++++++- xen/include/xen/vmap.h | 61 ++++++++++++++++------------ xen/include/xen/xvmalloc.h | 36 +++++++++++++--- 15 files changed, 156 insertions(+), 76 deletions(-) create mode 100644 xen/arch/arm/include/asm/mmu/setup.h -- 2.34.1
When HAS_VMAP is disabled, the xv{malloc,zalloc,...} functions should fall back to the simple x{malloc,zalloc,...} variant, implement that because MPU systems won't have virtual memory. Additionally remove VMAP_VIRT_START from vmap.h guards since MPU systems won't have it defined and protect with #ifdef CONFIG_HAS_VMAP all the declaration that won't be used in a MPU system built without HAS_VMAP. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- Changes from v1: - put back static inline iounmap - changed commit message - hide not used declaration for system with !HAS_VMAP - correct function declared in xvmalloc.h to be static inline - prefer '#ifdef' instead of '#if defined' where possible --- --- xen/include/xen/vmap.h | 61 ++++++++++++++++++++++---------------- xen/include/xen/xvmalloc.h | 36 ++++++++++++++++++---- 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/xen/include/xen/vmap.h b/xen/include/xen/vmap.h index XXXXXXX..XXXXXXX 100644 --- a/xen/include/xen/vmap.h +++ b/xen/include/xen/vmap.h @@ -XXX,XX +XXX,XX @@ * purpose area (VMAP_DEFAULT) and a livepatch-specific area (VMAP_XEN). The * latter is used when loading livepatches and the former for everything else. */ -#if !defined(__XEN_VMAP_H__) && defined(VMAP_VIRT_START) +#ifndef __XEN_VMAP_H__ #define __XEN_VMAP_H__ #include <xen/mm-frame.h> #include <xen/page-size.h> +/* + * MPU systems won't have HAS_VMAP enabled, but will provide implementation + * only for some of the functions of this module. So hide the definition for + * some of these function to systems where !HAS_VMAP + */ +#ifdef CONFIG_HAS_VMAP + /* Identifiers for the linear ranges tracked by vmap */ enum vmap_region { /* @@ -XXX,XX +XXX,XX @@ void *__vmap(const mfn_t *mfn, unsigned int granularity, unsigned int nr, */ void *vmap(const mfn_t *mfn, unsigned int nr); -/* - * Maps physically contiguous pages onto the VMAP_DEFAULT vmap region - * - * @param mfn Base mfn of the physical region - * @param nr Number of mfns in the physical region - * @return Pointer to the mapped area on success; NULL otherwise. - */ -void *vmap_contig(mfn_t mfn, unsigned int nr); - -/* - * Unmaps a range of virtually contiguous memory from one of the vmap regions - * - * The system remembers internally how wide the mapping is and unmaps it all. - * It also can determine the vmap region type from the `va`. - * - * @param va Virtual base address of the range to unmap - */ -void vunmap(const void *va); - /* * Allocate `size` octets of possibly non-contiguous physical memory and map * them contiguously in the VMAP_DEFAULT vmap region @@ -XXX,XX +XXX,XX @@ void *vzalloc(size_t size); */ void vfree(void *va); +/* Return the number of pages in the mapping starting at address 'va' */ +unsigned int vmap_size(const void *va); + +/* Pointer to 1 octet past the end of the VMAP_DEFAULT virtual area */ +void *arch_vmap_virt_end(void); + +#endif /* CONFIG_HAS_VMAP */ + +/* + * Maps physically contiguous pages onto the VMAP_DEFAULT vmap region + * + * @param mfn Base mfn of the physical region + * @param nr Number of mfns in the physical region + * @return Pointer to the mapped area on success; NULL otherwise. + */ +void *vmap_contig(mfn_t mfn, unsigned int nr); + +/* + * Unmaps a range of virtually contiguous memory from one of the vmap regions + * + * The system remembers internally how wide the mapping is and unmaps it all. + * It also can determine the vmap region type from the `va`. + * + * @param va Virtual base address of the range to unmap + */ +void vunmap(const void *va); + /* * Analogous to vmap_contig(), but for IO memory * @@ -XXX,XX +XXX,XX @@ void vfree(void *va); */ void __iomem *ioremap(paddr_t pa, size_t len); -/* Return the number of pages in the mapping starting at address 'va' */ -unsigned int vmap_size(const void *va); - /* Analogous to vunmap(), but for IO memory mapped via ioremap() */ static inline void iounmap(void __iomem *va) { @@ -XXX,XX +XXX,XX @@ static inline void iounmap(void __iomem *va) vunmap((void *)(addr & PAGE_MASK)); } -/* Pointer to 1 octet past the end of the VMAP_DEFAULT virtual area */ -void *arch_vmap_virt_end(void); - /* Initialises the VMAP_DEFAULT virtual range */ static inline void vm_init(void) { diff --git a/xen/include/xen/xvmalloc.h b/xen/include/xen/xvmalloc.h index XXXXXXX..XXXXXXX 100644 --- a/xen/include/xen/xvmalloc.h +++ b/xen/include/xen/xvmalloc.h @@ -XXX,XX +XXX,XX @@ ((typeof(ptr))_xvrealloc(ptr, offsetof(typeof(*(ptr)), field[nr]), \ __alignof__(typeof(*(ptr))))) +#ifdef CONFIG_HAS_VMAP + /* Free any of the above. */ void xvfree(void *va); +/* Underlying functions */ +void *_xvmalloc(size_t size, unsigned int align); +void *_xvzalloc(size_t size, unsigned int align); +void *_xvrealloc(void *va, size_t size, unsigned int align); + +#else /* !CONFIG_HAS_VMAP */ + +static inline void xvfree(void *va) +{ + xfree(va); +} + +static inline void *_xvmalloc(size_t size, unsigned int align) +{ + return _xmalloc(size, align); +} + +static inline void *_xvzalloc(size_t size, unsigned int align) +{ + return _xzalloc(size, align); +} + +static inline void *_xvrealloc(void *va, size_t size, unsigned int align) +{ + return _xrealloc(va, size, align); +} + +#endif /* CONFIG_HAS_VMAP */ + /* Free an allocation, and zero the pointer to it. */ #define XVFREE(p) do { \ xvfree(p); \ (p) = NULL; \ } while ( false ) -/* Underlying functions */ -void *_xvmalloc(size_t size, unsigned int align); -void *_xvzalloc(size_t size, unsigned int align); -void *_xvrealloc(void *va, size_t size, unsigned int align); - static inline void *_xvmalloc_array( size_t size, unsigned int align, unsigned long num) { -- 2.34.1
Move some extern declarations related to MMU structures and define from asm/setup.h to asm/mmu/setup.h, in order to increase encapsulation and allow the MPU part to build, since it has no clue about them. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- Changes from v1: - Moved extern to mmu/setup.h instead of mmu/mm.h - moved also pte_of_xenaddr() --- --- xen/arch/arm/include/asm/mmu/setup.h | 31 ++++++++++++++++++++++++++++ xen/arch/arm/include/asm/setup.h | 20 ++++++------------ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 xen/arch/arm/include/asm/mmu/setup.h diff --git a/xen/arch/arm/include/asm/mmu/setup.h b/xen/arch/arm/include/asm/mmu/setup.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/arm/include/asm/mmu/setup.h @@ -XXX,XX +XXX,XX @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __ARM_MMU_SETUP_H__ +#define __ARM_MMU_SETUP_H__ + +#include <asm/lpae.h> +#include <asm/mmu/layout.h> + +extern lpae_t boot_pgtable[XEN_PT_LPAE_ENTRIES]; + +#ifdef CONFIG_ARM_64 +extern lpae_t boot_first[XEN_PT_LPAE_ENTRIES]; +extern lpae_t boot_first_id[XEN_PT_LPAE_ENTRIES]; +#endif +extern lpae_t boot_second[XEN_PT_LPAE_ENTRIES]; +extern lpae_t boot_second_id[XEN_PT_LPAE_ENTRIES]; +extern lpae_t boot_third[XEN_PT_LPAE_ENTRIES * XEN_NR_ENTRIES(2)]; +extern lpae_t boot_third_id[XEN_PT_LPAE_ENTRIES]; + +/* Find where Xen will be residing at runtime and return a PT entry */ +lpae_t pte_of_xenaddr(vaddr_t va); + +#endif /* __ARM_MMU_SETUP_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/include/asm/setup.h +++ b/xen/arch/arm/include/asm/setup.h @@ -XXX,XX +XXX,XX @@ #include <xen/bootfdt.h> #include <xen/device_tree.h> +#if defined(CONFIG_MMU) +# include <asm/mmu/setup.h> +#elif !defined(CONFIG_MPU) +# error "Unknown memory management layout" +#endif + #define MAX_FDT_SIZE SZ_2M struct map_range_data @@ -XXX,XX +XXX,XX @@ int map_irq_to_domain(struct domain *d, unsigned int irq, int map_range_to_domain(const struct dt_device_node *dev, uint64_t addr, uint64_t len, void *data); -extern lpae_t boot_pgtable[XEN_PT_LPAE_ENTRIES]; - -#ifdef CONFIG_ARM_64 -extern lpae_t boot_first[XEN_PT_LPAE_ENTRIES]; -extern lpae_t boot_first_id[XEN_PT_LPAE_ENTRIES]; -#endif -extern lpae_t boot_second[XEN_PT_LPAE_ENTRIES]; -extern lpae_t boot_second_id[XEN_PT_LPAE_ENTRIES]; -extern lpae_t boot_third[XEN_PT_LPAE_ENTRIES * XEN_NR_ENTRIES(2)]; -extern lpae_t boot_third_id[XEN_PT_LPAE_ENTRIES]; - -/* Find where Xen will be residing at runtime and return a PT entry */ -lpae_t pte_of_xenaddr(vaddr_t va); - extern const char __ro_after_init_start[], __ro_after_init_end[]; struct init_info -- 2.34.1
Currently the arm code uses __vmap function in few parts to map physically contiguous pages, vmap_contig was introduced recently and does the same because it's a wrapper for __vmap, so use the latter instead of the direct __vmap function. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> Acked-by: Julien Grall <jgrall@amazon.com> --- Changes v1: - Add ack-by Julien --- --- xen/arch/arm/alternative.c | 3 +-- xen/arch/arm/cpuerrata.c | 5 ++--- xen/arch/arm/kernel.c | 2 +- xen/arch/arm/livepatch.c | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/alternative.c b/xen/arch/arm/alternative.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/alternative.c +++ b/xen/arch/arm/alternative.c @@ -XXX,XX +XXX,XX @@ void __init apply_alternatives_all(void) * The text and inittext section are read-only. So re-map Xen to * be able to patch the code. */ - xenmap = __vmap(&xen_mfn, 1U << xen_order, 1, 1, PAGE_HYPERVISOR, - VMAP_DEFAULT); + xenmap = vmap_contig(xen_mfn, 1U << xen_order); /* Re-mapping Xen is not expected to fail during boot. */ BUG_ON(!xenmap); diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/cpuerrata.c +++ b/xen/arch/arm/cpuerrata.c @@ -XXX,XX +XXX,XX @@ static bool copy_hyp_vect_bpi(unsigned int slot, const char *hyp_vec_start, * Vectors are part of the text that are mapped read-only. So re-map * the vector table to be able to update vectors. */ - dst_remapped = __vmap(&dst_mfn, - 1UL << get_order_from_bytes(VECTOR_TABLE_SIZE), - 1, 1, PAGE_HYPERVISOR, VMAP_DEFAULT); + dst_remapped = vmap_contig(dst_mfn, + 1UL << get_order_from_bytes(VECTOR_TABLE_SIZE)); if ( !dst_remapped ) return false; diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -XXX,XX +XXX,XX @@ static __init int kernel_decompress(struct bootmodule *mod, uint32_t offset) return -ENOMEM; } mfn = page_to_mfn(pages); - output = __vmap(&mfn, 1 << kernel_order_out, 1, 1, PAGE_HYPERVISOR, VMAP_DEFAULT); + output = vmap_contig(mfn, 1 << kernel_order_out); rc = perform_gunzip(output, input, size); clean_dcache_va_range(output, output_size); diff --git a/xen/arch/arm/livepatch.c b/xen/arch/arm/livepatch.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/livepatch.c +++ b/xen/arch/arm/livepatch.c @@ -XXX,XX +XXX,XX @@ int arch_livepatch_quiesce(void) * The text section is read-only. So re-map Xen to be able to patch * the code. */ - vmap_of_xen_text = __vmap(&text_mfn, 1U << text_order, 1, 1, PAGE_HYPERVISOR, - VMAP_DEFAULT); + vmap_of_xen_text = vmap_contig(text_mfn, 1U << text_order); if ( !vmap_of_xen_text ) { -- 2.34.1
From: Penny Zheng <Penny.Zheng@arm.com> If Xenheap is statically configured in Device Tree, its size is definite. So, the memory shall not be given back into static heap, like it's normally done in free_init_memory, etc, once the initialization is finished. Extract static_heap flag from init data bootinfo, as it will be needed after destroying the init data section. Introduce a new helper xen_is_using_staticheap() to tell whether Xenheap is statically configured in the Device Tree. Signed-off-by: Penny Zheng <penny.zheng@arm.com> Signed-off-by: Wei Chen <wei.chen@arm.com> Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- Changes from v1: - moved static_heap to common/page_alloc.c - protect static_heap access with CONFIG_STATIC_MEMORY - update comment in arm/kernel.c kernel_decompress() --- --- xen/arch/arm/arm32/mmu/mm.c | 4 ++-- xen/arch/arm/kernel.c | 7 ++++--- xen/arch/arm/mmu/setup.c | 8 ++++++-- xen/arch/arm/setup.c | 27 ++++++++++++++------------- xen/common/device-tree/bootfdt.c | 4 +++- xen/common/device-tree/bootinfo.c | 2 +- xen/common/page_alloc.c | 5 +++++ xen/include/xen/bootfdt.h | 14 +++++++++++++- 8 files changed, 48 insertions(+), 23 deletions(-) diff --git a/xen/arch/arm/arm32/mmu/mm.c b/xen/arch/arm/arm32/mmu/mm.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/arm32/mmu/mm.c +++ b/xen/arch/arm/arm32/mmu/mm.c @@ -XXX,XX +XXX,XX @@ void __init setup_mm(void) total_pages = ram_size >> PAGE_SHIFT; - if ( bootinfo.static_heap ) + if ( xen_is_using_staticheap() ) { const struct membanks *reserved_mem = bootinfo_get_reserved_mem(); @@ -XXX,XX +XXX,XX @@ void __init setup_mm(void) do { - e = bootinfo.static_heap ? + e = xen_is_using_staticheap() ? fit_xenheap_in_static_heap(pfn_to_paddr(xenheap_pages), MB(32)) : consider_modules(ram_start, ram_end, pfn_to_paddr(xenheap_pages), diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -XXX,XX +XXX,XX @@ static __init int kernel_decompress(struct bootmodule *mod, uint32_t offset) size += offset; /* - * Free the original kernel, update the pointers to the - * decompressed kernel + * In case Xen is not using the static heap feature, free the original + * kernel, update the pointers to the decompressed kernel */ - fw_unreserved_regions(addr, addr + size, init_domheap_pages, 0); + if ( !xen_is_using_staticheap() ) + fw_unreserved_regions(addr, addr + size, init_domheap_pages, 0); return 0; } diff --git a/xen/arch/arm/mmu/setup.c b/xen/arch/arm/mmu/setup.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/mmu/setup.c +++ b/xen/arch/arm/mmu/setup.c @@ -XXX,XX +XXX,XX @@ void free_init_memory(void) if ( rc ) panic("Unable to remove the init section (rc = %d)\n", rc); - init_domheap_pages(pa, pa + len); - printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10); + if ( !xen_is_using_staticheap() ) + { + init_domheap_pages(pa, pa + len); + printk("Freed %ldkB init memory.\n", + (long)(__init_end-__init_begin) >> 10); + } } /** diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -XXX,XX +XXX,XX @@ void __init discard_initial_modules(void) struct bootmodules *mi = &bootinfo.modules; int i; - for ( i = 0; i < mi->nr_mods; i++ ) + if ( !xen_is_using_staticheap() ) { - paddr_t s = mi->module[i].start; - paddr_t e = s + PAGE_ALIGN(mi->module[i].size); - - if ( mi->module[i].kind == BOOTMOD_XEN ) - continue; + for ( i = 0; i < mi->nr_mods; i++ ) + { + paddr_t s = mi->module[i].start; + paddr_t e = s + PAGE_ALIGN(mi->module[i].size); - if ( !mfn_valid(maddr_to_mfn(s)) || - !mfn_valid(maddr_to_mfn(e)) ) - continue; + if ( mi->module[i].kind == BOOTMOD_XEN ) + continue; - fw_unreserved_regions(s, e, init_domheap_pages, 0); - } + if ( !mfn_valid(maddr_to_mfn(s)) || + !mfn_valid(maddr_to_mfn(e)) ) + continue; - mi->nr_mods = 0; + fw_unreserved_regions(s, e, init_domheap_pages, 0); + } - remove_early_mappings(); + mi->nr_mods = 0; + } } /* Relocate the FDT in Xen heap */ diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c index XXXXXXX..XXXXXXX 100644 --- a/xen/common/device-tree/bootfdt.c +++ b/xen/common/device-tree/bootfdt.c @@ -XXX,XX +XXX,XX @@ static int __init process_chosen_node(const void *fdt, int node, if ( rc ) return rc; - bootinfo.static_heap = true; +#ifdef CONFIG_STATIC_MEMORY + static_heap = true; +#endif } printk("Checking for initrd in /chosen\n"); diff --git a/xen/common/device-tree/bootinfo.c b/xen/common/device-tree/bootinfo.c index XXXXXXX..XXXXXXX 100644 --- a/xen/common/device-tree/bootinfo.c +++ b/xen/common/device-tree/bootinfo.c @@ -XXX,XX +XXX,XX @@ void __init populate_boot_allocator(void) const struct membanks *reserved_mem = bootinfo_get_reserved_mem(); paddr_t s, e; - if ( bootinfo.static_heap ) + if ( xen_is_using_staticheap() ) { for ( i = 0 ; i < reserved_mem->nr_banks; i++ ) { diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index XXXXXXX..XXXXXXX 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -XXX,XX +XXX,XX @@ #define PGT_TYPE_INFO_INITIALIZER 0 #endif +#ifdef CONFIG_STATIC_MEMORY +/* Flag saved when Xen is using the static heap feature (xen,static-heap) */ +bool __ro_after_init static_heap; +#endif + unsigned long __read_mostly max_page; unsigned long __read_mostly total_pages; paddr_t __ro_after_init mem_hotplug; diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h index XXXXXXX..XXXXXXX 100644 --- a/xen/include/xen/bootfdt.h +++ b/xen/include/xen/bootfdt.h @@ -XXX,XX +XXX,XX @@ struct bootinfo { #ifdef CONFIG_STATIC_SHM struct shared_meminfo shmem; #endif - bool static_heap; }; #ifdef CONFIG_ACPI @@ -XXX,XX +XXX,XX @@ struct bootinfo { extern struct bootinfo bootinfo; +#ifdef CONFIG_STATIC_MEMORY +extern bool static_heap; +#endif + bool check_reserved_regions_overlap(paddr_t region_start, paddr_t region_size); @@ -XXX,XX +XXX,XX @@ static inline struct shmem_membank_extra *bootinfo_get_shmem_extra(void) } #endif +static inline bool xen_is_using_staticheap(void) +{ +#ifdef CONFIG_STATIC_MEMORY + return static_heap; +#else + return false; +#endif +} + #endif /* XEN_BOOTFDT_H */ -- 2.34.1
In this serie I've taken out patches from the R82 branch already in the ML[1] and some new patches I've done based on the current status of staging that will not impact the current Armv8-R earlyboot work. [1] https://patchwork.kernel.org/project/xen-devel/cover/20230626033443.2943270-1-Penny.Zheng@arm.com/ Changes between v2 and v3: - New patch - changes to previous patch are listed inside them Luca Fancellu (4): common/vmap: Fall back to simple allocator when !HAS_VMAP arm/setup: Move MMU specific extern declarations to mmu/setup.h xen/arm: Use vmap_contig instead of __vmap where it's possible xen/arm: Move setup_frametable_mappings to arm/mmu Penny Zheng (1): xen/arm: Check for Static Heap feature when freeing resources xen/arch/arm/alternative.c | 3 +- xen/arch/arm/arm32/mmu/mm.c | 4 +- xen/arch/arm/cpuerrata.c | 5 +-- xen/arch/arm/include/asm/mmu/setup.h | 31 ++++++++++++++ xen/arch/arm/include/asm/setup.h | 20 +++------ xen/arch/arm/kernel.c | 9 ++-- xen/arch/arm/livepatch.c | 3 +- xen/arch/arm/mm.c | 40 ------------------ xen/arch/arm/mmu/Makefile | 1 + xen/arch/arm/mmu/mm.c | 61 ++++++++++++++++++++++++++++ xen/arch/arm/mmu/setup.c | 8 +++- xen/arch/arm/setup.c | 27 ++++++------ xen/common/device-tree/bootfdt.c | 4 +- xen/common/device-tree/bootinfo.c | 2 +- xen/common/page_alloc.c | 5 +++ xen/include/xen/bootfdt.h | 1 - xen/include/xen/mm.h | 13 ++++++ xen/include/xen/vmap.h | 2 +- xen/include/xen/xvmalloc.h | 36 +++++++++++++--- 19 files changed, 184 insertions(+), 91 deletions(-) create mode 100644 xen/arch/arm/include/asm/mmu/setup.h create mode 100644 xen/arch/arm/mmu/mm.c -- 2.34.1
When HAS_VMAP is disabled, the xv{malloc,zalloc,...} functions should fall back to the simple x{malloc,zalloc,...} variant, implement that because MPU systems won't have virtual memory. Additionally remove VMAP_VIRT_START from vmap.h guards since MPU systems won't have it defined. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- Changes from v2: - Don't protect declarations. Changes from v1: - put back static inline iounmap - changed commit message - hide not used declaration for system with !HAS_VMAP - correct function declared in xvmalloc.h to be static inline - prefer '#ifdef' instead of '#if defined' where possible --- --- xen/include/xen/vmap.h | 2 +- xen/include/xen/xvmalloc.h | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/xen/include/xen/vmap.h b/xen/include/xen/vmap.h index XXXXXXX..XXXXXXX 100644 --- a/xen/include/xen/vmap.h +++ b/xen/include/xen/vmap.h @@ -XXX,XX +XXX,XX @@ * purpose area (VMAP_DEFAULT) and a livepatch-specific area (VMAP_XEN). The * latter is used when loading livepatches and the former for everything else. */ -#if !defined(__XEN_VMAP_H__) && defined(VMAP_VIRT_START) +#ifndef __XEN_VMAP_H__ #define __XEN_VMAP_H__ #include <xen/mm-frame.h> diff --git a/xen/include/xen/xvmalloc.h b/xen/include/xen/xvmalloc.h index XXXXXXX..XXXXXXX 100644 --- a/xen/include/xen/xvmalloc.h +++ b/xen/include/xen/xvmalloc.h @@ -XXX,XX +XXX,XX @@ ((typeof(ptr))_xvrealloc(ptr, offsetof(typeof(*(ptr)), field[nr]), \ __alignof__(typeof(*(ptr))))) +#ifdef CONFIG_HAS_VMAP + /* Free any of the above. */ void xvfree(void *va); +/* Underlying functions */ +void *_xvmalloc(size_t size, unsigned int align); +void *_xvzalloc(size_t size, unsigned int align); +void *_xvrealloc(void *va, size_t size, unsigned int align); + +#else /* !CONFIG_HAS_VMAP */ + +static inline void xvfree(void *va) +{ + xfree(va); +} + +static inline void *_xvmalloc(size_t size, unsigned int align) +{ + return _xmalloc(size, align); +} + +static inline void *_xvzalloc(size_t size, unsigned int align) +{ + return _xzalloc(size, align); +} + +static inline void *_xvrealloc(void *va, size_t size, unsigned int align) +{ + return _xrealloc(va, size, align); +} + +#endif /* CONFIG_HAS_VMAP */ + /* Free an allocation, and zero the pointer to it. */ #define XVFREE(p) do { \ xvfree(p); \ (p) = NULL; \ } while ( false ) -/* Underlying functions */ -void *_xvmalloc(size_t size, unsigned int align); -void *_xvzalloc(size_t size, unsigned int align); -void *_xvrealloc(void *va, size_t size, unsigned int align); - static inline void *_xvmalloc_array( size_t size, unsigned int align, unsigned long num) { -- 2.34.1
Move some extern declarations related to MMU structures and define from asm/setup.h to asm/mmu/setup.h, in order to increase encapsulation and allow the MPU part to build, since it has no clue about them. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- Changes from v2: - No changes Changes from v1: - Moved extern to mmu/setup.h instead of mmu/mm.h - moved also pte_of_xenaddr() --- --- xen/arch/arm/include/asm/mmu/setup.h | 31 ++++++++++++++++++++++++++++ xen/arch/arm/include/asm/setup.h | 20 ++++++------------ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 xen/arch/arm/include/asm/mmu/setup.h diff --git a/xen/arch/arm/include/asm/mmu/setup.h b/xen/arch/arm/include/asm/mmu/setup.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/arm/include/asm/mmu/setup.h @@ -XXX,XX +XXX,XX @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __ARM_MMU_SETUP_H__ +#define __ARM_MMU_SETUP_H__ + +#include <asm/lpae.h> +#include <asm/mmu/layout.h> + +extern lpae_t boot_pgtable[XEN_PT_LPAE_ENTRIES]; + +#ifdef CONFIG_ARM_64 +extern lpae_t boot_first[XEN_PT_LPAE_ENTRIES]; +extern lpae_t boot_first_id[XEN_PT_LPAE_ENTRIES]; +#endif +extern lpae_t boot_second[XEN_PT_LPAE_ENTRIES]; +extern lpae_t boot_second_id[XEN_PT_LPAE_ENTRIES]; +extern lpae_t boot_third[XEN_PT_LPAE_ENTRIES * XEN_NR_ENTRIES(2)]; +extern lpae_t boot_third_id[XEN_PT_LPAE_ENTRIES]; + +/* Find where Xen will be residing at runtime and return a PT entry */ +lpae_t pte_of_xenaddr(vaddr_t va); + +#endif /* __ARM_MMU_SETUP_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/include/asm/setup.h +++ b/xen/arch/arm/include/asm/setup.h @@ -XXX,XX +XXX,XX @@ #include <xen/bootfdt.h> #include <xen/device_tree.h> +#if defined(CONFIG_MMU) +# include <asm/mmu/setup.h> +#elif !defined(CONFIG_MPU) +# error "Unknown memory management layout" +#endif + #define MAX_FDT_SIZE SZ_2M struct map_range_data @@ -XXX,XX +XXX,XX @@ int map_irq_to_domain(struct domain *d, unsigned int irq, int map_range_to_domain(const struct dt_device_node *dev, uint64_t addr, uint64_t len, void *data); -extern lpae_t boot_pgtable[XEN_PT_LPAE_ENTRIES]; - -#ifdef CONFIG_ARM_64 -extern lpae_t boot_first[XEN_PT_LPAE_ENTRIES]; -extern lpae_t boot_first_id[XEN_PT_LPAE_ENTRIES]; -#endif -extern lpae_t boot_second[XEN_PT_LPAE_ENTRIES]; -extern lpae_t boot_second_id[XEN_PT_LPAE_ENTRIES]; -extern lpae_t boot_third[XEN_PT_LPAE_ENTRIES * XEN_NR_ENTRIES(2)]; -extern lpae_t boot_third_id[XEN_PT_LPAE_ENTRIES]; - -/* Find where Xen will be residing at runtime and return a PT entry */ -lpae_t pte_of_xenaddr(vaddr_t va); - extern const char __ro_after_init_start[], __ro_after_init_end[]; struct init_info -- 2.34.1
Currently the arm code uses __vmap function in few parts to map physically contiguous pages, vmap_contig was introduced recently and does the same because it's a wrapper for __vmap, so use the latter instead of the direct __vmap function. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> Acked-by: Julien Grall <jgrall@amazon.com> Acked-by: Roger Pau Monné <roger.pau@citrix.com> --- Changes from v2: - Add ack-by Roger Changes from v1: - Add ack-by Julien --- --- xen/arch/arm/alternative.c | 3 +-- xen/arch/arm/cpuerrata.c | 5 ++--- xen/arch/arm/kernel.c | 2 +- xen/arch/arm/livepatch.c | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/alternative.c b/xen/arch/arm/alternative.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/alternative.c +++ b/xen/arch/arm/alternative.c @@ -XXX,XX +XXX,XX @@ void __init apply_alternatives_all(void) * The text and inittext section are read-only. So re-map Xen to * be able to patch the code. */ - xenmap = __vmap(&xen_mfn, 1U << xen_order, 1, 1, PAGE_HYPERVISOR, - VMAP_DEFAULT); + xenmap = vmap_contig(xen_mfn, 1U << xen_order); /* Re-mapping Xen is not expected to fail during boot. */ BUG_ON(!xenmap); diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/cpuerrata.c +++ b/xen/arch/arm/cpuerrata.c @@ -XXX,XX +XXX,XX @@ static bool copy_hyp_vect_bpi(unsigned int slot, const char *hyp_vec_start, * Vectors are part of the text that are mapped read-only. So re-map * the vector table to be able to update vectors. */ - dst_remapped = __vmap(&dst_mfn, - 1UL << get_order_from_bytes(VECTOR_TABLE_SIZE), - 1, 1, PAGE_HYPERVISOR, VMAP_DEFAULT); + dst_remapped = vmap_contig(dst_mfn, + 1UL << get_order_from_bytes(VECTOR_TABLE_SIZE)); if ( !dst_remapped ) return false; diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -XXX,XX +XXX,XX @@ static __init int kernel_decompress(struct bootmodule *mod, uint32_t offset) return -ENOMEM; } mfn = page_to_mfn(pages); - output = __vmap(&mfn, 1 << kernel_order_out, 1, 1, PAGE_HYPERVISOR, VMAP_DEFAULT); + output = vmap_contig(mfn, 1 << kernel_order_out); rc = perform_gunzip(output, input, size); clean_dcache_va_range(output, output_size); diff --git a/xen/arch/arm/livepatch.c b/xen/arch/arm/livepatch.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/livepatch.c +++ b/xen/arch/arm/livepatch.c @@ -XXX,XX +XXX,XX @@ int arch_livepatch_quiesce(void) * The text section is read-only. So re-map Xen to be able to patch * the code. */ - vmap_of_xen_text = __vmap(&text_mfn, 1U << text_order, 1, 1, PAGE_HYPERVISOR, - VMAP_DEFAULT); + vmap_of_xen_text = vmap_contig(text_mfn, 1U << text_order); if ( !vmap_of_xen_text ) { -- 2.34.1
From: Penny Zheng <Penny.Zheng@arm.com> If the Xen heap is statically configured in Device Tree, its size is definite, so only the defined memory shall be given to the boot allocator. Have a check where init_domheap_pages() is called which takes into account if static heap feature is used. Extract static_heap flag from init data bootinfo, as it will be needed after destroying the init data section. Introduce a new helper using_static_heap() to tell whether Xen Heap is statically configured in the Device Tree. Signed-off-by: Penny Zheng <penny.zheng@arm.com> Signed-off-by: Wei Chen <wei.chen@arm.com> Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- Changes from v2: - Change xen_is_using_staticheap() to using_static_heap() - Move declaration of static_heap and using_static_heap() to xen/mm.h - Reprased first part of the commit message and title Changes from v1: - moved static_heap to common/page_alloc.c - protect static_heap access with CONFIG_STATIC_MEMORY - update comment in arm/kernel.c kernel_decompress() --- --- xen/arch/arm/arm32/mmu/mm.c | 4 ++-- xen/arch/arm/kernel.c | 7 ++++--- xen/arch/arm/mmu/setup.c | 8 ++++++-- xen/arch/arm/setup.c | 27 ++++++++++++++------------- xen/common/device-tree/bootfdt.c | 4 +++- xen/common/device-tree/bootinfo.c | 2 +- xen/common/page_alloc.c | 5 +++++ xen/include/xen/bootfdt.h | 1 - xen/include/xen/mm.h | 13 +++++++++++++ 9 files changed, 48 insertions(+), 23 deletions(-) diff --git a/xen/arch/arm/arm32/mmu/mm.c b/xen/arch/arm/arm32/mmu/mm.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/arm32/mmu/mm.c +++ b/xen/arch/arm/arm32/mmu/mm.c @@ -XXX,XX +XXX,XX @@ void __init setup_mm(void) total_pages = ram_size >> PAGE_SHIFT; - if ( bootinfo.static_heap ) + if ( using_static_heap() ) { const struct membanks *reserved_mem = bootinfo_get_reserved_mem(); @@ -XXX,XX +XXX,XX @@ void __init setup_mm(void) do { - e = bootinfo.static_heap ? + e = using_static_heap() ? fit_xenheap_in_static_heap(pfn_to_paddr(xenheap_pages), MB(32)) : consider_modules(ram_start, ram_end, pfn_to_paddr(xenheap_pages), diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -XXX,XX +XXX,XX @@ static __init int kernel_decompress(struct bootmodule *mod, uint32_t offset) size += offset; /* - * Free the original kernel, update the pointers to the - * decompressed kernel + * In case Xen is not using the static heap feature, free the original + * kernel, update the pointers to the decompressed kernel */ - fw_unreserved_regions(addr, addr + size, init_domheap_pages, 0); + if ( !using_static_heap() ) + fw_unreserved_regions(addr, addr + size, init_domheap_pages, 0); return 0; } diff --git a/xen/arch/arm/mmu/setup.c b/xen/arch/arm/mmu/setup.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/mmu/setup.c +++ b/xen/arch/arm/mmu/setup.c @@ -XXX,XX +XXX,XX @@ void free_init_memory(void) if ( rc ) panic("Unable to remove the init section (rc = %d)\n", rc); - init_domheap_pages(pa, pa + len); - printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10); + if ( !using_static_heap() ) + { + init_domheap_pages(pa, pa + len); + printk("Freed %ldkB init memory.\n", + (long)(__init_end-__init_begin) >> 10); + } } /** diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -XXX,XX +XXX,XX @@ void __init discard_initial_modules(void) struct bootmodules *mi = &bootinfo.modules; int i; - for ( i = 0; i < mi->nr_mods; i++ ) + if ( !using_static_heap() ) { - paddr_t s = mi->module[i].start; - paddr_t e = s + PAGE_ALIGN(mi->module[i].size); - - if ( mi->module[i].kind == BOOTMOD_XEN ) - continue; + for ( i = 0; i < mi->nr_mods; i++ ) + { + paddr_t s = mi->module[i].start; + paddr_t e = s + PAGE_ALIGN(mi->module[i].size); - if ( !mfn_valid(maddr_to_mfn(s)) || - !mfn_valid(maddr_to_mfn(e)) ) - continue; + if ( mi->module[i].kind == BOOTMOD_XEN ) + continue; - fw_unreserved_regions(s, e, init_domheap_pages, 0); - } + if ( !mfn_valid(maddr_to_mfn(s)) || + !mfn_valid(maddr_to_mfn(e)) ) + continue; - mi->nr_mods = 0; + fw_unreserved_regions(s, e, init_domheap_pages, 0); + } - remove_early_mappings(); + mi->nr_mods = 0; + } } /* Relocate the FDT in Xen heap */ diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c index XXXXXXX..XXXXXXX 100644 --- a/xen/common/device-tree/bootfdt.c +++ b/xen/common/device-tree/bootfdt.c @@ -XXX,XX +XXX,XX @@ static int __init process_chosen_node(const void *fdt, int node, if ( rc ) return rc; - bootinfo.static_heap = true; +#ifdef CONFIG_STATIC_MEMORY + static_heap = true; +#endif } printk("Checking for initrd in /chosen\n"); diff --git a/xen/common/device-tree/bootinfo.c b/xen/common/device-tree/bootinfo.c index XXXXXXX..XXXXXXX 100644 --- a/xen/common/device-tree/bootinfo.c +++ b/xen/common/device-tree/bootinfo.c @@ -XXX,XX +XXX,XX @@ void __init populate_boot_allocator(void) const struct membanks *reserved_mem = bootinfo_get_reserved_mem(); paddr_t s, e; - if ( bootinfo.static_heap ) + if ( using_static_heap() ) { for ( i = 0 ; i < reserved_mem->nr_banks; i++ ) { diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index XXXXXXX..XXXXXXX 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -XXX,XX +XXX,XX @@ #define PGT_TYPE_INFO_INITIALIZER 0 #endif +#ifdef CONFIG_STATIC_MEMORY +/* Flag saved when Xen is using the static heap feature (xen,static-heap) */ +bool __ro_after_init static_heap; +#endif + unsigned long __read_mostly max_page; unsigned long __read_mostly total_pages; paddr_t __ro_after_init mem_hotplug; diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h index XXXXXXX..XXXXXXX 100644 --- a/xen/include/xen/bootfdt.h +++ b/xen/include/xen/bootfdt.h @@ -XXX,XX +XXX,XX @@ struct bootinfo { #ifdef CONFIG_STATIC_SHM struct shared_meminfo shmem; #endif - bool static_heap; }; #ifdef CONFIG_ACPI diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index XXXXXXX..XXXXXXX 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -XXX,XX +XXX,XX @@ struct page_info; +#ifdef CONFIG_STATIC_MEMORY +extern bool static_heap; +#endif + +static inline bool using_static_heap(void) +{ +#ifdef CONFIG_STATIC_MEMORY + return static_heap; +#else + return false; +#endif +} + void put_page(struct page_info *page); bool __must_check get_page(struct page_info *page, const struct domain *domain); -- 2.34.1
Move the current setup_frametable_mappings implementation to arm/mmu under a new file mm.c, this implementation depends on virtual memory and won't be used as it is for MPU systems. Take the occasion to fix code style issues related to the line length. Moved also frametable_virt_end since it is used only on MMU systems. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> --- Changes to v2: - New patch --- --- xen/arch/arm/mm.c | 40 ------------------------- xen/arch/arm/mmu/Makefile | 1 + xen/arch/arm/mmu/mm.c | 61 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 40 deletions(-) create mode 100644 xen/arch/arm/mmu/mm.c diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -XXX,XX +XXX,XX @@ #define virt_to_mfn(va) _mfn(__virt_to_mfn(va)) unsigned long frametable_base_pdx __read_mostly; -unsigned long frametable_virt_end __read_mostly; void flush_page_to_ram(unsigned long mfn, bool sync_icache) { @@ -XXX,XX +XXX,XX @@ void flush_page_to_ram(unsigned long mfn, bool sync_icache) invalidate_icache(); } -/* Map a frame table to cover physical addresses ps through pe */ -void __init setup_frametable_mappings(paddr_t ps, paddr_t pe) -{ - unsigned long nr_pdxs = mfn_to_pdx(mfn_add(maddr_to_mfn(pe), -1)) - - mfn_to_pdx(maddr_to_mfn(ps)) + 1; - unsigned long frametable_size = nr_pdxs * sizeof(struct page_info); - mfn_t base_mfn; - const unsigned long mapping_size = frametable_size < MB(32) ? MB(2) : MB(32); - int rc; - - /* - * The size of paddr_t should be sufficient for the complete range of - * physical address. - */ - BUILD_BUG_ON((sizeof(paddr_t) * BITS_PER_BYTE) < PADDR_BITS); - BUILD_BUG_ON(sizeof(struct page_info) != PAGE_INFO_SIZE); - - if ( frametable_size > FRAMETABLE_SIZE ) - panic("The frametable cannot cover the physical region %#"PRIpaddr" - %#"PRIpaddr"\n", - ps, pe); - - frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ps)); - /* Round up to 2M or 32M boundary, as appropriate. */ - frametable_size = ROUNDUP(frametable_size, mapping_size); - base_mfn = alloc_boot_pages(frametable_size >> PAGE_SHIFT, 32<<(20-12)); - - rc = map_pages_to_xen(FRAMETABLE_VIRT_START, base_mfn, - frametable_size >> PAGE_SHIFT, - PAGE_HYPERVISOR_RW | _PAGE_BLOCK); - if ( rc ) - panic("Unable to setup the frametable mappings.\n"); - - memset(&frame_table[0], 0, nr_pdxs * sizeof(struct page_info)); - memset(&frame_table[nr_pdxs], -1, - frametable_size - (nr_pdxs * sizeof(struct page_info))); - - frametable_virt_end = FRAMETABLE_VIRT_START + (nr_pdxs * sizeof(struct page_info)); -} - int steal_page( struct domain *d, struct page_info *page, unsigned int memflags) { diff --git a/xen/arch/arm/mmu/Makefile b/xen/arch/arm/mmu/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/mmu/Makefile +++ b/xen/arch/arm/mmu/Makefile @@ -XXX,XX +XXX,XX @@ +obj-y += mm.o obj-y += p2m.o obj-y += pt.o obj-y += setup.o diff --git a/xen/arch/arm/mmu/mm.c b/xen/arch/arm/mmu/mm.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/arm/mmu/mm.c @@ -XXX,XX +XXX,XX @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <xen/init.h> +#include <xen/lib.h> +#include <xen/macros.h> +#include <xen/mm.h> +#include <xen/mm-frame.h> +#include <xen/pdx.h> +#include <xen/string.h> + +unsigned long frametable_virt_end __read_mostly; + +/* Map a frame table to cover physical addresses ps through pe */ +void __init setup_frametable_mappings(paddr_t ps, paddr_t pe) +{ + unsigned long nr_pdxs = mfn_to_pdx(mfn_add(maddr_to_mfn(pe), -1)) - + mfn_to_pdx(maddr_to_mfn(ps)) + 1; + unsigned long frametable_size = nr_pdxs * sizeof(struct page_info); + mfn_t base_mfn; + const unsigned long mapping_size = frametable_size < MB(32) ? MB(2) + : MB(32); + int rc; + + /* + * The size of paddr_t should be sufficient for the complete range of + * physical address. + */ + BUILD_BUG_ON((sizeof(paddr_t) * BITS_PER_BYTE) < PADDR_BITS); + BUILD_BUG_ON(sizeof(struct page_info) != PAGE_INFO_SIZE); + + if ( frametable_size > FRAMETABLE_SIZE ) + panic("The frametable cannot cover the physical region %#"PRIpaddr" - %#"PRIpaddr"\n", + ps, pe); + + frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ps)); + /* Round up to 2M or 32M boundary, as appropriate. */ + frametable_size = ROUNDUP(frametable_size, mapping_size); + base_mfn = alloc_boot_pages(frametable_size >> PAGE_SHIFT, 32<<(20-12)); + + rc = map_pages_to_xen(FRAMETABLE_VIRT_START, base_mfn, + frametable_size >> PAGE_SHIFT, + PAGE_HYPERVISOR_RW | _PAGE_BLOCK); + if ( rc ) + panic("Unable to setup the frametable mappings.\n"); + + memset(&frame_table[0], 0, nr_pdxs * sizeof(struct page_info)); + memset(&frame_table[nr_pdxs], -1, + frametable_size - (nr_pdxs * sizeof(struct page_info))); + + frametable_virt_end = FRAMETABLE_VIRT_START + (nr_pdxs * + sizeof(struct page_info)); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ -- 2.34.1