[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 39/52] xen/mpu: support free_init_memory in MPU system
This commit refines free_init_memory() to make it support in MPU system. We are supporting modify_xen_mappings() in MPU system too, and it is responsible for modifying memory permission of a existing MPU memory region. Currently, we only support modifying a *WHOLE* MPU memory region, part-region modification is not supported, as in worst case, it will leave three fragments behind. In MPU system, we map init text and init data section, each with a MPU memory region. So we shall destroy it seperately in free_init_memory(). Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx> Signed-off-by: Wei Chen <wei.chen@xxxxxxx> --- v3: - As MMU and MPU could share a lot of codes, we made the changes in original function free_init_memory() in mm.c --- xen/arch/arm/mm.c | 14 +++++++++++++- xen/arch/arm/mpu/mm.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 247d17cfa1..ba4ae74e18 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -177,7 +177,12 @@ int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int flags) ASSERT(IS_ALIGNED(s, PAGE_SIZE)); ASSERT(IS_ALIGNED(e, PAGE_SIZE)); ASSERT(s <= e); +#ifndef CONFIG_HAS_MPU return xen_pt_update(s, INVALID_MFN, (e - s) >> PAGE_SHIFT, flags); +#else + return xen_mpumap_update(virt_to_maddr((void *)s), + virt_to_maddr((void *)e), flags); +#endif } /* Release all __init and __initdata ranges to be reused */ @@ -212,10 +217,17 @@ void free_init_memory(void) for ( i = 0; i < nr; i++ ) *(p + i) = insn; + /* Remove init text section */ rc = destroy_xen_mappings((unsigned long)__init_begin, + (unsigned long)inittext_end); + if ( rc ) + panic("Unable to remove the init text section (rc = %d)\n", rc); + + /* Remove init data section */ + rc = destroy_xen_mappings((unsigned long)inittext_end, (unsigned long)__init_end); if ( rc ) - panic("Unable to remove the init section (rc = %d)\n", rc); + panic("Unable to remove the init data section (rc = %d)\n", rc); if ( !xen_is_using_staticheap() ) { diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index b2419f0603..79d1c10d05 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -496,8 +496,39 @@ static int xen_mpumap_update_entry(paddr_t base, paddr_t limit, if ( (rc < 0) || (rc == MPUMAP_REGION_OVERLAP) ) return -EINVAL; + /* We are updating the permission. */ + if ( (flags & _PAGE_PRESENT) && (rc == MPUMAP_REGION_FOUND || + rc == MPUMAP_REGION_INCLUSIVE) ) + { + /* + * Currently, we only support modifying a *WHOLE* MPU memory region, + * part-region modification is not supported, as in worst case, it will + * leave three fragments behind. + * part-region modification will be introduced only when actual usage + * come + */ + if ( rc == MPUMAP_REGION_INCLUSIVE ) + { + region_printk("mpu: part-region modification is not supported\n"); + return -EINVAL; + } + + /* We don't allow changing memory attributes. */ + if (xen_mpumap[idx].prlar.reg.ai != PAGE_AI_MASK(flags) ) + { + region_printk("Modifying memory attributes is not allowed (0x%x -> 0x%x).\n", + xen_mpumap[idx].prlar.reg.ai, PAGE_AI_MASK(flags)); + return -EINVAL; + } + + /* Set new permission */ + xen_mpumap[idx].prbar.reg.ap = PAGE_AP_MASK(flags); + xen_mpumap[idx].prbar.reg.xn = PAGE_XN_MASK(flags); + + write_protection_region((const pr_t*)(&xen_mpumap[idx]), idx); + } /* We are inserting a mapping => Create new region. */ - if ( flags & _PAGE_PRESENT ) + else if ( flags & _PAGE_PRESENT ) { if ( rc != MPUMAP_REGION_FAILED ) return -EINVAL; -- 2.25.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |