Commit 753e8abc authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Catalin Marinas

arm64: mm: fix thinko in non-global page table attribute check

The routine pgattr_change_is_safe() was extended in commit 4e602056
("arm64: mm: Permit transitioning from Global to Non-Global without BBM")
to permit changing the nG attribute from not set to set, but did so in a
way that inadvertently disallows such changes if other permitted attribute
changes take place at the same time. So update the code to take this into
account.

Fixes: 4e602056 ("arm64: mm: Permit transitioning from Global to ...")
Cc: <stable@vger.kernel.org> # 4.14.x-
Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
Reviewed-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 4a3928c6
...@@ -108,7 +108,7 @@ static bool pgattr_change_is_safe(u64 old, u64 new) ...@@ -108,7 +108,7 @@ static bool pgattr_change_is_safe(u64 old, u64 new)
* The following mapping attributes may be updated in live * The following mapping attributes may be updated in live
* kernel mappings without the need for break-before-make. * kernel mappings without the need for break-before-make.
*/ */
static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE; static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG;
/* creating or taking down mappings is always safe */ /* creating or taking down mappings is always safe */
if (old == 0 || new == 0) if (old == 0 || new == 0)
...@@ -118,9 +118,9 @@ static bool pgattr_change_is_safe(u64 old, u64 new) ...@@ -118,9 +118,9 @@ static bool pgattr_change_is_safe(u64 old, u64 new)
if ((old | new) & PTE_CONT) if ((old | new) & PTE_CONT)
return false; return false;
/* Transitioning from Global to Non-Global is safe */ /* Transitioning from Non-Global to Global is unsafe */
if (((old ^ new) == PTE_NG) && (new & PTE_NG)) if (old & ~new & PTE_NG)
return true; return false;
return ((old ^ new) & ~mask) == 0; return ((old ^ new) & ~mask) == 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment