Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1409595
| From | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 4.6 003/100] arm64: Implement ptep_set_access_flags() for hardware AF/DBM |
| Date | 2016-05-30 23:50 +0200 |
| Message-ID | <rEDer-1uu-57@gated-at.bofh.it> (permalink) |
| References | <rECBH-1eG-9@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <catalin.marinas@arm.com>
commit 66dbd6e61a526ae7d11a208238ae2c17e5cacb6b upstream.
When hardware updates of the access and dirty states are enabled, the
default ptep_set_access_flags() implementation based on calling
set_pte_at() directly is potentially racy. This triggers the "racy dirty
state clearing" warning in set_pte_at() because an existing writable PTE
is overridden with a clean entry.
There are two main scenarios for this situation:
1. The CPU getting an access fault does not support hardware updates of
the access/dirty flags. However, a different agent in the system
(e.g. SMMU) can do this, therefore overriding a writable entry with a
clean one could potentially lose the automatically updated dirty
status
2. A more complex situation is possible when all CPUs support hardware
AF/DBM:
a) Initial state: shareable + writable vma and pte_none(pte)
b) Read fault taken by two threads of the same process on different
CPUs
c) CPU0 takes the mmap_sem and proceeds to handling the fault. It
eventually reaches do_set_pte() which sets a writable + clean pte.
CPU0 releases the mmap_sem
d) CPU1 acquires the mmap_sem and proceeds to handle_pte_fault(). The
pte entry it reads is present, writable and clean and it continues
to pte_mkyoung()
e) CPU1 calls ptep_set_access_flags()
If between (d) and (e) the hardware (another CPU) updates the dirty
state (clears PTE_RDONLY), CPU1 will override the PTR_RDONLY bit
marking the entry clean again.
This patch implements an arm64-specific ptep_set_access_flags() function
to perform an atomic update of the PTE flags.
Fixes: 2f4b829c625e ("arm64: Add support for hardware updates of the access and dirty pte bits")
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Ming Lei <tom.leiming@gmail.com>
Tested-by: Julien Grall <julien.grall@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
[will: reworded comment]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/include/asm/pgtable.h | 5 +++
arch/arm64/mm/fault.c | 50 +++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -526,6 +526,11 @@ static inline pmd_t pmd_modify(pmd_t pmd
}
#ifdef CONFIG_ARM64_HW_AFDBM
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+extern int ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep,
+ pte_t entry, int dirty);
+
/*
* Atomic pte/pmd modifications.
*/
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -81,6 +81,56 @@ void show_pte(struct mm_struct *mm, unsi
printk("\n");
}
+#ifdef CONFIG_ARM64_HW_AFDBM
+/*
+ * This function sets the access flags (dirty, accessed), as well as write
+ * permission, and only to a more permissive setting.
+ *
+ * It needs to cope with hardware update of the accessed/dirty state by other
+ * agents in the system and can safely skip the __sync_icache_dcache() call as,
+ * like set_pte_at(), the PTE is never changed from no-exec to exec here.
+ *
+ * Returns whether or not the PTE actually changed.
+ */
+int ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep,
+ pte_t entry, int dirty)
+{
+ pteval_t old_pteval;
+ unsigned int tmp;
+
+ if (pte_same(*ptep, entry))
+ return 0;
+
+ /* only preserve the access flags and write permission */
+ pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY;
+
+ /*
+ * 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)
+ pte_val(entry) |= PTE_RDONLY;
+
+ /*
+ * Setting the flags must be done atomically to avoid racing with the
+ * hardware update of the access/dirty state.
+ */
+ asm volatile("// ptep_set_access_flags\n"
+ " prfm pstl1strm, %2\n"
+ "1: ldxr %0, %2\n"
+ " and %0, %0, %3 // clear PTE_RDONLY\n"
+ " orr %0, %0, %4 // set flags\n"
+ " stxr %w1, %0, %2\n"
+ " cbnz %w1, 1b\n"
+ : "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))
+ : "L" (~PTE_RDONLY), "r" (pte_val(entry)));
+
+ flush_tlb_fix_spurious_fault(vma, address);
+ return 1;
+}
+#endif
+
/*
* The kernel tried to access some page that wasn't present.
*/
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 4.6 000/100] 4.6.1-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 074/100] serial: 8250_mid: recognize interrupt source in handler Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 070/100] tty/serial: atmel: fix hardware handshake selection Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 077/100] clk: bcm2835: add locking to pll*_on/off methods Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 069/100] TTY: n_gsm, fix false positive WARN_ON Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 055/100] usb: misc: usbtest: fix pattern tests for scatterlists. Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 073/100] serial: 8250_mid: use proper bar for DNV platform Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 079/100] watchdog: sp5100_tco: properly check for new register layouts Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 071/100] Fix OpenSSH pty regression on close Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 056/100] USB: leave LPM alone if possible when binding/unbinding interface drivers Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 022/100] fscrypto/f2fs: allow fs-specific key prefix for fs encryption Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 076/100] locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 007/100] kvm: arm64: Fix EC field in inject_abt64 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 068/100] tty: vt, return error when con_startup fails Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 067/100] x86/cpufeature, x86/mm/pkeys: Fix broken compile-time disabling of pkeys Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 042/100] mei: amthif: discard not read messages Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 008/100] perf/x86/intel/uncore: Remove WARN_ON_ONCE in uncore_pci_probe Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 066/100] xen/x86: actually allocate legacy interrupts on PV guests Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 043/100] mei: bus: call mei_cl_read_start under device lock Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 081/100] Fixing oops in callback path Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 059/100] usb: host: xhci-rcar: Avoid long wait in xhci_reset() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 044/100] USB: serial: cp210x: fix hardware flow-control disable Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 060/100] staging: comedi: das1800: fix possible NULL dereference Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:30 +0200
[PATCH 4.6 039/100] Bluetooth: vhci: purge unhandled skbs Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:40 +0200
[PATCH 4.6 038/100] Bluetooth: vhci: fix open_timeout vs. hdev race Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:40 +0200
[PATCH 4.6 016/100] ring-buffer: Prevent overflow of size in ring_buffer_resize() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:40 +0200
[PATCH 4.6 033/100] mmc: sdhci-acpi: Remove MMC_CAP_BUS_WIDTH_TEST for Intel controllers Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 037/100] mmc: sdhci-pci: Remove MMC_CAP_BUS_WIDTH_TEST for Intel controllers Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 031/100] ACPI / PM: Export acpi_device_fix_up_power() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 027/100] irqchip/gic-v3: Configure all interrupts as non-secure Group-1 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 036/100] mmc: longer timeout for long read time quirk Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 020/100] clk: qcom: msm8916: Fix crypto clock flags Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 024/100] mfd: omap-usb-tll: Fix scheduling while atomic BUG Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 018/100] crypto: talitos - fix ahash algorithms registration Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 002/100] arm64: Ensure pmd_present() returns false after pmd_mknotpresent() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 025/100] Input: pwm-beeper - fix - scheduling while atomic Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 026/100] irqchip/gic: Ensure ordering between read of INTACK and shared data Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 030/100] mmc: mmc: Fix partition switch timeout for some eMMCs Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 003/100] arm64: Implement ptep_set_access_flags() for hardware AF/DBM Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 019/100] crypto: sun4i-ss - Replace spinlock_bh by spin_lock_irq{save|restore} Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 023/100] sched/loadavg: Fix loadavg artifacts on fully idle and on fully loaded systems Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 017/100] crypto: caam - fix caam_jr_alloc() ret code Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
[PATCH 4.6 034/100] ACPI / osi: Fix an issue that acpi_osi=!* cannot disable ACPICA internal strings Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-30 23:50 +0200
Re: [PATCH 4.6 000/100] 4.6.1-stable review Guenter Roeck <linux@roeck-us.net> - 2016-06-01 07:40 +0200
Re: [PATCH 4.6 000/100] 4.6.1-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-06-01 18:20 +0200
Re: [PATCH 4.6 000/100] 4.6.1-stable review "Xuetao Guan" <gxt@mprc.pku.edu.cn> - 2016-06-02 06:40 +0200
Re: [PATCH 4.6 000/100] 4.6.1-stable review Shuah Khan <shuahkh@osg.samsung.com> - 2016-06-01 16:30 +0200
csiph-web