diff options
author | Will Deacon <will.deacon@arm.com> | 2016-06-07 17:55:15 +0100 |
---|---|---|
committer | Amit Pundir <amit.pundir@linaro.org> | 2016-12-12 14:42:15 +0000 |
commit | 18f41ad6976a772f283b6563963957b85d833e5b (patch) | |
tree | 125f84582c5fd9ba94c5ccb7d1c439f09cf77119 /net/ipv4/ping.c | |
parent | f82be531155c6ce5890df4ffe6fad9b1fa2eafac (diff) |
UPSTREAM: arm64: mm: always take dirty state from new pte in ptep_set_access_flags
(Cherry picked from commit 0106d456c4cb1770253fefc0ab23c9ca760b43f7)
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.
Cc: <stable@vger.kernel.org> # 4.3+
Fixes: 66dbd6e61a52 ("arm64: Implement ptep_set_access_flags() for hardware AF/DBM")
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Alexander Graf <agraf@suse.de>
Tested-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Fixes: Change-Id: Id2a0b0d8eb6e7df6325ecb48b88b8401a5dd09e5
("UPSTREAM: arm64: Implement ptep_set_access_flags() for hardware AF/DBM")
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
Diffstat (limited to 'net/ipv4/ping.c')
0 files changed, 0 insertions, 0 deletions