This is a note to let you know that I've just added the patch titled arm64: mm: always take dirty state from new pte in ptep_set_access_flags to the 4.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: arm64-mm-always-take-dirty-state-from-new-pte-in-ptep_set_access_flags.patch and it can be found in the queue-4.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 0106d456c4cb1770253fefc0ab23c9ca760b43f7 Mon Sep 17 00:00:00 2001 From: Will Deacon <will.deacon@xxxxxxx> Date: Tue, 7 Jun 2016 17:55:15 +0100 Subject: arm64: mm: always take dirty state from new pte in ptep_set_access_flags From: Will Deacon <will.deacon@xxxxxxx> commit 0106d456c4cb1770253fefc0ab23c9ca760b43f7 upstream. Commit 66dbd6e61a52 ("arm64: Implement ptep_set_access_flags() for hardware AF/DBM") ensured that pte flags are updated atomically in the face of potential concurrent, hardware-assisted updates. However, Alex reports that: | This patch breaks swapping for me. | In the broken case, you'll see either systemd cpu time spike (because | it's stuck in a page fault loop) or the system hang (because the | application owning the screen is stuck in a page fault loop). It turns out that this is because the 'dirty' argument to ptep_set_access_flags is always 0 for read faults, and so we can't use it to set PTE_RDONLY. The failing sequence is: 1. We put down a PTE_WRITE | PTE_DIRTY | PTE_AF pte 2. Memory pressure -> pte_mkold(pte) -> clear PTE_AF 3. A read faults due to the missing access flag 4. ptep_set_access_flags is called with dirty = 0, due to the read fault 5. pte is then made PTE_WRITE | PTE_DIRTY | PTE_AF | PTE_RDONLY (!) 6. A write faults, but pte_write is true so we get stuck The solution is to check the new page table entry (as would be done by the generic, non-atomic definition of ptep_set_access_flags that just calls set_pte_at) to establish the dirty state. Fixes: 66dbd6e61a52 ("arm64: Implement ptep_set_access_flags() for hardware AF/DBM") Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx> Reported-by: Alexander Graf <agraf@xxxxxxx> Tested-by: Alexander Graf <agraf@xxxxxxx> Signed-off-by: Will Deacon <will.deacon@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- arch/arm64/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -109,7 +109,7 @@ int ptep_set_access_flags(struct vm_area * PTE_RDONLY is cleared by default in the asm below, so set it in * back if necessary (read-only or clean PTE). */ - if (!pte_write(entry) || !dirty) + if (!pte_write(entry) || !pte_sw_dirty(entry)) pte_val(entry) |= PTE_RDONLY; /* Patches currently in stable-queue which might be from will.deacon@xxxxxxx are queue-4.6/drivers-perf-arm_pmu-defer-the-setting-of-__oprofile_cpu_pmu.patch queue-4.6/arm64-provide-model-name-in-proc-cpuinfo-for-per_linux32-tasks.patch queue-4.6/arm64-mm-always-take-dirty-state-from-new-pte-in-ptep_set_access_flags.patch queue-4.6/arm-fix-ptrace_setvfpregs-on-smp-systems.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html