Linux 3.16.38
From: Ben Hutchings
Date: Fri Oct 21 2016 - 09:56:21 EST
I'm announcing the release of the 3.16.38 kernel.
All users of the 3.16 kernel series should upgrade.
The updated 3.16.y git tree can be found at:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-3.16.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git
The diff from 3.16.37 is attached to this message.
Ben.
------------
Makefile | 2 +-
include/linux/mm.h | 1 +
mm/gup.c | 14 ++++++++++++--
3 files changed, 14 insertions(+), 3 deletions(-)
Ben Hutchings (1):
Linux 3.16.38
Linus Torvalds (1):
mm: remove gup_flags FOLL_WRITE games from __get_user_pages()
diff --git a/Makefile b/Makefile
index e49d13717d31..37083fbc8784 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 16
-SUBLEVEL = 37
+SUBLEVEL = 38
EXTRAVERSION =
NAME = Museum of Fishiegoodies
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7ac72a725798..e648c24e8410 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2007,6 +2007,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma,
#define FOLL_HWPOISON 0x100 /* check page is hwpoisoned */
#define FOLL_NUMA 0x200 /* force NUMA hinting page fault */
#define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */
+#define FOLL_COW 0x4000 /* internal GUP flag */
typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
void *data);
diff --git a/mm/gup.c b/mm/gup.c
index 9cb1cfbe4677..2e4b9873b5aa 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -28,6 +28,16 @@ static struct page *no_page_table(struct vm_area_struct *vma,
return NULL;
}
+/*
+ * FOLL_FORCE can write to even unwritable pte's, but only
+ * after we've gone through a COW cycle and they are dirty.
+ */
+static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
+{
+ return pte_write(pte) ||
+ ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
+}
+
static struct page *follow_page_pte(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmd, unsigned int flags)
{
@@ -62,7 +72,7 @@ retry:
}
if ((flags & FOLL_NUMA) && pte_numa(pte))
goto no_page;
- if ((flags & FOLL_WRITE) && !pte_write(pte)) {
+ if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) {
pte_unmap_unlock(ptep, ptl);
return NULL;
}
@@ -302,7 +312,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
* reCOWed by userspace write).
*/
if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
- *flags &= ~FOLL_WRITE;
+ *flags |= FOLL_COW;
return 0;
}
Attachment:
signature.asc
Description: Digital signature