[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 07/13] xen/arm: Extract MMU-specific code
Hi Henry, On 14/08/2023 05:25, Henry Wang wrote: While I agree that dump_pt_walk() is better to be defined in mm.h, I am not entirely sure for ...Currently, most of the MMU-specific code is in mm.{c,h}. To make the mm extendable, this commit extract the MMU-specific code by firstly: - Create a arch/arm/include/asm/mmu/ subdir. - Create a arch/arm/mmu/ subdir. Then move the MMU-specific code to above mmu subdir, which includes below changes: - Move arch/arm/arm64/mm.c to arch/arm/arm64/mmu/mm.c - Move MMU-related declaration in arch/arm/include/asm/mm.h to arch/arm/include/asm/mmu/mm.h - Move the MMU-related declaration dump_pt_walk() in asm/page.h and pte_of_xenaddr() in asm/setup.h to the new asm/mmu/mm.h. ... pte_of_xenaddr(). It was defined in setup.h because this is an helper that is only intended to be used during early boot. That said, it is probably not worth creating a new helper for that. So I would suggest to at least mark pte_of_xenaddr() __init to make clear of the intended usage. - Move MMU-related code in arch/arm/mm.c to arch/arm/mmu/mm.c. Also modify the build system (Makefiles in this case) to pick above mentioned code changes. This patch is a pure code movement, no functional change intended. Signed-off-by: Henry Wang <Henry.Wang@xxxxxxx> --- With the code movement of this patch, the descriptions on top of xen/arch/arm/mm.c and xen/arch/arm/mmu/mm.c might need some changes, suggestions? v5: - Rebase on top of xen/arm: Introduce CONFIG_MMU Kconfig option and xen/arm: mm: add missing extern variable declaration v4: - Rework "[v3,13/52] xen/mmu: extract mmu-specific codes from mm.c/mm.h" with the lastest staging branch, only do the code movement in this patch to ease the review. --- xen/arch/arm/Makefile | 1 + xen/arch/arm/arm64/Makefile | 1 - xen/arch/arm/arm64/mmu/Makefile | 1 + xen/arch/arm/arm64/{ => mmu}/mm.c | 0 xen/arch/arm/include/asm/mm.h | 20 +- xen/arch/arm/include/asm/mmu/mm.h | 55 ++ xen/arch/arm/include/asm/page.h | 15 - xen/arch/arm/include/asm/setup.h | 3 - xen/arch/arm/mm.c | 1119 ---------------------------- xen/arch/arm/mmu/Makefile | 1 + xen/arch/arm/mmu/mm.c | 1146 +++++++++++++++++++++++++++++ I noticed you transferred everything in mm.c But I think some part could go in arm{32,64}/mmu/mm.c. 11 files changed, 1208 insertions(+), 1154 deletions(-) rename xen/arch/arm/arm64/{ => mmu}/mm.c (100%) create mode 100644 xen/arch/arm/include/asm/mmu/mm.h create mode 100644 xen/arch/arm/mmu/Makefile create mode 100644 xen/arch/arm/mmu/mm.c (I haven't checked if the code was moved correctly. I only checked if the split makes sense). To ease the review, I think this patch can be split in a more piecemeal patches. The first two pieces would be : * Patch #1 transfer xen_pt_update()/dump_pt_walk() and their dependencies * Patch #2 transfer root page-table allocation Then you can have some for each small functions. [...] diff --git a/xen/arch/arm/arm64/mm.c b/xen/arch/arm/arm64/mmu/mm.c similarity index 100% rename from xen/arch/arm/arm64/mm.c rename to xen/arch/arm/arm64/mmu/mm.c diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h index aaacba3f04..dc1458b047 100644 --- a/xen/arch/arm/include/asm/mm.h +++ b/xen/arch/arm/include/asm/mm.h @@ -14,6 +14,10 @@ # error "unknown ARM variant" #endif+#ifdef CONFIG_MMU+#include <asm/mmu/mm.h> I am guessing you will need to include <asm/mpu/mm.h> at some point. So I would add a: #else # error "Unknown memory management layout" This would be easier to find out where includes might be missing. [...] @@ -1233,11 +119,6 @@ int map_pages_to_xen(unsigned long virt, return xen_pt_update(virt, mfn, nr_mfns, flags); } [...] +/* MMU setup for secondary CPUS (which already have paging enabled) */ +void mmu_init_secondary_cpu(void) +{ + xen_pt_enforce_wnx(); +} + +#ifdef CONFIG_ARM_32 Rather than #ifdef, I would prefer if we move each implementation to arm32/mmu/mm.c and ... +/* + * Set up the direct-mapped xenheap: + * up to 1GB of contiguous, always-mapped memory. + */ +void __init setup_directmap_mappings(unsigned long base_mfn, + unsigned long nr_mfns) +{ + int rc; + + rc = map_pages_to_xen(XENHEAP_VIRT_START, _mfn(base_mfn), nr_mfns, + PAGE_HYPERVISOR_RW | _PAGE_BLOCK); + if ( rc ) + panic("Unable to setup the directmap mappings.\n"); + + /* Record where the directmap is, for translation routines. */ + directmap_virt_end = XENHEAP_VIRT_START + nr_mfns * PAGE_SIZE; +} +#else /* CONFIG_ARM_64 */ +/* Map the region in the directmap area. */ +void __init setup_directmap_mappings(unsigned long base_mfn, + unsigned long nr_mfns) ... arm64/mmu/mm.c. +{ + int rc; + + /* First call sets the directmap physical and virtual offset. */ + if ( mfn_eq(directmap_mfn_start, INVALID_MFN) ) + { + unsigned long mfn_gb = base_mfn & ~((FIRST_SIZE >> PAGE_SHIFT) - 1); + + directmap_mfn_start = _mfn(base_mfn); + directmap_base_pdx = mfn_to_pdx(_mfn(base_mfn)); + /* + * The base address may not be aligned to the first level + * size (e.g. 1GB when using 4KB pages). This would prevent + * superpage mappings for all the regions because the virtual + * address and machine address should both be suitably aligned. + * + * Prevent that by offsetting the start of the directmap virtual + * address. + */ + directmap_virt_start = DIRECTMAP_VIRT_START + + (base_mfn - mfn_gb) * PAGE_SIZE; + } + + if ( base_mfn < mfn_x(directmap_mfn_start) ) + panic("cannot add directmap mapping at %lx below heap start %lx\n", + base_mfn, mfn_x(directmap_mfn_start)); + + rc = map_pages_to_xen((vaddr_t)__mfn_to_virt(base_mfn), + _mfn(base_mfn), nr_mfns, + PAGE_HYPERVISOR_RW | _PAGE_BLOCK); + if ( rc ) + panic("Unable to setup the directmap mappings.\n"); +} +#endif + +/* Map a frame table to cover physical addresses ps through pe */ +void __init setup_frametable_mappings(paddr_t ps, paddr_t pe) I looked at the implement for the MPU and the code is mainly the same. So can we keep this code in common and just ... +{ + 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); abstract the frametable mapping? THis would also make clear that the BUILD_BUG_ON() above are not specific to the MMU code. + 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)); +} -- Julien Grall
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |