diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2017-04-09 16:09:38 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-27 03:10:38 -0400 |
commit | 3d42ca46f47a4d3cd5abe465735227534c292aed (patch) | |
tree | f1413576d42b24899b0ca4a9e1374f74df4cb530 | |
parent | f79ef57911ee598e0bfb7af1ab51413429a8f9d5 (diff) |
s390/mm: fix CMMA vs KSM vs others
commit a8f60d1fadf7b8b54449fcc9d6b15248917478ba upstream.
On heavy paging with KSM I see guest data corruption. Turns out that
KSM will add pages to its tree, where the mapping return true for
pte_unused (or might become as such later). KSM will unmap such pages
and reinstantiate with different attributes (e.g. write protected or
special, e.g. in replace_page or write_protect_page)). This uncovered
a bug in our pagetable handling: We must remove the unused flag as
soon as an entry becomes present again.
Signed-of-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0362cd5fa187..0cea7026e4ff 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -1029,6 +1029,8 @@ int get_guest_storage_key(struct mm_struct *mm, unsigned long addr, | |||
1029 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | 1029 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
1030 | pte_t *ptep, pte_t entry) | 1030 | pte_t *ptep, pte_t entry) |
1031 | { | 1031 | { |
1032 | if (pte_present(entry)) | ||
1033 | pte_val(entry) &= ~_PAGE_UNUSED; | ||
1032 | if (mm_has_pgste(mm)) | 1034 | if (mm_has_pgste(mm)) |
1033 | ptep_set_pte_at(mm, addr, ptep, entry); | 1035 | ptep_set_pte_at(mm, addr, ptep, entry); |
1034 | else | 1036 | else |