--- v5
+++ v4
@@ -1,25 +1,62 @@
-Introduce CONFIG_SPF which turns on the Speculative Page Fault handler when
-building for 64bits with SMP.
+From: Peter Zijlstra <peterz@infradead.org>
+One of the side effects of speculating on faults (without holding
+mmap_sem) is that we can race with free_pgtables() and therefore we
+cannot assume the page-tables will stick around.
+
+Remove the reliance on the pte pointer.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+
+[Remove only if !__HAVE_ARCH_CALL_SPF]
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
- arch/x86/Kconfig | 4 ++++
- 1 file changed, 4 insertions(+)
+ mm/memory.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index 063f1e0d51aa..a726618b7018 100644
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
-@@ -2865,6 +2865,10 @@ config X86_DMA_REMAP
- config HAVE_GENERIC_GUP
- def_bool y
+diff --git a/mm/memory.c b/mm/memory.c
+index 6632c9b357c9..4e4fe233d066 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2287,6 +2287,7 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
+ }
+ EXPORT_SYMBOL_GPL(apply_to_page_range);
-+config SPF
-+ def_bool y
-+ depends on X86_64 && SMP
++#ifndef __HAVE_ARCH_CALL_SPF
+ /*
+ * handle_pte_fault chooses page fault handler according to an entry which was
+ * read non-atomically. Before making any commitment, on those architectures
+@@ -2296,7 +2297,7 @@ EXPORT_SYMBOL_GPL(apply_to_page_range);
+ * and do_anonymous_page can safely check later on).
+ */
+ static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd,
+- pte_t *page_table, pte_t orig_pte)
++ pte_t *page_table, pte_t orig_pte)
+ {
+ int same = 1;
+ #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+@@ -2310,6 +2311,7 @@ static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd,
+ pte_unmap(page_table);
+ return same;
+ }
++#endif
+
+ static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va, struct vm_area_struct *vma)
+ {
+@@ -2871,11 +2873,14 @@ int do_swap_page(struct vm_fault *vmf)
+
+ if (vma_readahead)
+ page = swap_readahead_detect(vmf, &swap_ra);
+
- source "net/Kconfig"
++#ifndef __HAVE_ARCH_CALL_SPF
+ if (!pte_unmap_same(vma->vm_mm, vmf->pmd, vmf->pte, vmf->orig_pte)) {
+ if (page)
+ put_page(page);
+ goto out;
+ }
++#endif
- source "drivers/Kconfig"
+ entry = pte_to_swp_entry(vmf->orig_pte);
+ if (unlikely(non_swap_entry(entry))) {
--
2.7.4