aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2014-08-28 15:21:41 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-09-02 04:30:43 -0400
commit3e03d4c46daa849880837d802e41c14132a03ef9 (patch)
tree758d0d843efe23586a2546ee9edf04e506231c25 /arch/s390/include
parentab3f285f227fec62868037e9b1b1fd18294a83b8 (diff)
KVM: s390/mm: Fix storage key corruption during swapping
Since 3.12 or more precisely commit 0944fe3f4a32 ("s390/mm: implement software referenced bits") guest storage keys get corrupted during paging. This commit added another valid->invalid translation for page tables - namely ptep_test_and_clear_young. We have to transfer the storage key into the pgste in that case. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: stable@vger.kernel.org # v3.12+
Diffstat (limited to 'arch/s390/include')
-rw-r--r--arch/s390/include/asm/pgtable.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index b76317c1f3eb..32686e891313 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -1127,7 +1127,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
1127 unsigned long addr, pte_t *ptep) 1127 unsigned long addr, pte_t *ptep)
1128{ 1128{
1129 pgste_t pgste; 1129 pgste_t pgste;
1130 pte_t pte; 1130 pte_t pte, oldpte;
1131 int young; 1131 int young;
1132 1132
1133 if (mm_has_pgste(vma->vm_mm)) { 1133 if (mm_has_pgste(vma->vm_mm)) {
@@ -1135,12 +1135,13 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
1135 pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste); 1135 pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste);
1136 } 1136 }
1137 1137
1138 pte = *ptep; 1138 oldpte = pte = *ptep;
1139 ptep_flush_direct(vma->vm_mm, addr, ptep); 1139 ptep_flush_direct(vma->vm_mm, addr, ptep);
1140 young = pte_young(pte); 1140 young = pte_young(pte);
1141 pte = pte_mkold(pte); 1141 pte = pte_mkold(pte);
1142 1142
1143 if (mm_has_pgste(vma->vm_mm)) { 1143 if (mm_has_pgste(vma->vm_mm)) {
1144 pgste = pgste_update_all(&oldpte, pgste, vma->vm_mm);
1144 pgste = pgste_set_pte(ptep, pgste, pte); 1145 pgste = pgste_set_pte(ptep, pgste, pte);
1145 pgste_set_unlock(ptep, pgste); 1146 pgste_set_unlock(ptep, pgste);
1146 } else 1147 } else