From: Ard Biesheuvel Allow permission changes on huge vmappings in cases where no splitting is needed (i.e., the region is aligned sufficiently), or when the system has support for splitting live mappings. Signed-off-by: Ard Biesheuvel --- arch/arm64/mm/pageattr.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index bbe98ac9ad8c..20ff9cb273c1 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -169,8 +169,6 @@ static int change_memory_common(unsigned long addr, int numpages, * we are operating on does not result in such splitting. * * Let's restrict ourselves to mappings created by vmalloc (or vmap). - * Disallow VM_ALLOW_HUGE_VMAP mappings to guarantee that only page - * mappings are updated and splitting is never needed. * * So check whether the [addr, addr + size) interval is entirely * covered by precisely one VM area that has the VM_ALLOC flag set. @@ -179,7 +177,16 @@ static int change_memory_common(unsigned long addr, int numpages, if (!area || ((unsigned long)kasan_reset_tag((void *)end) > (unsigned long)kasan_reset_tag(area->addr) + area->size) || - ((area->flags & (VM_ALLOC | VM_ALLOW_HUGE_VMAP)) != VM_ALLOC)) + !(area->flags & VM_ALLOC)) + return -EINVAL; + + /* + * Disallow VM_ALLOW_HUGE_VMAP mappings unless the region is PMD + * aligned, or splitting live huge mappings is supported. + */ + if ((area->flags & VM_ALLOW_HUGE_VMAP) && + ((start % PMD_SIZE) || (size % PMD_SIZE)) && + WARN_ON_ONCE(!system_supports_bbml2_noabort())) return -EINVAL; if (!numpages) -- 2.55.0.860.g4b6b3295ed-goog