@@ -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() )
{
@@ -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;