| From 753e8abc36b2c966caea075db0c845563c8a19bf Mon Sep 17 00:00:00 2001 |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Date: Fri, 23 Feb 2018 18:04:48 +0000 |
| Subject: arm64: mm: fix thinko in non-global page table attribute check |
| |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| |
| commit 753e8abc36b2c966caea075db0c845563c8a19bf upstream. |
| |
| The routine pgattr_change_is_safe() was extended in commit 4e6020565596 |
| ("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: 4e6020565596 ("arm64: mm: Permit transitioning from Global to ...") |
| Cc: <stable@vger.kernel.org> # 4.14.x- |
| Acked-by: Mark Rutland <mark.rutland@arm.com> |
| Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> |
| Acked-by: Will Deacon <will.deacon@arm.com> |
| Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arm64/mm/mmu.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/arch/arm64/mm/mmu.c |
| +++ b/arch/arm64/mm/mmu.c |
| @@ -107,7 +107,7 @@ static bool pgattr_change_is_safe(u64 ol |
| * The following mapping attributes may be updated in live |
| * 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 */ |
| if (old == 0 || new == 0) |
| @@ -117,9 +117,9 @@ static bool pgattr_change_is_safe(u64 ol |
| if ((old | new) & PTE_CONT) |
| return false; |
| |
| - /* Transitioning from Global to Non-Global is safe */ |
| - if (((old ^ new) == PTE_NG) && (new & PTE_NG)) |
| - return true; |
| + /* Transitioning from Non-Global to Global is unsafe */ |
| + if (old & ~new & PTE_NG) |
| + return false; |
| |
| return ((old ^ new) & ~mask) == 0; |
| } |