[PATCH v6 08/12] s390/mm: Clear skeys for newly mapped huge guest pmds

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Similarly to the pte skey handling, where we set the storage key to
the default key for each newly mapped pte, we have to also do that for
huge pmds.

Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx>
---
 arch/s390/mm/pgtable.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index c393a6b0f362..6550ed56fcdf 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -410,14 +410,34 @@ static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm,
 	return old;
 }
 
+static void pmdp_clear_skeys(struct mm_struct *mm, pmd_t *pmdp, pmd_t new)
+{
+	unsigned long paddr = pmd_val(new) & HPAGE_MASK;
+
+	/*
+	 * After a guest has used the first storage key instruction,
+	 * we must ensure, that each newly mapped huge pmd has all
+	 * skeys cleared before mapping it.
+	 */
+	if (!mm_uses_skeys(mm) ||
+	    !pmd_none(*pmdp) ||
+	    !pmd_large(new) ||
+	    (pmd_val(new) & _SEGMENT_ENTRY_INVALID))
+		return;
+
+	__storage_key_init_range(paddr, paddr + HPAGE_SIZE - 1);
+}
+
 pmd_t pmdp_xchg_direct(struct mm_struct *mm, unsigned long addr,
 		       pmd_t *pmdp, pmd_t new)
 {
 	pmd_t old;
 
 	preempt_disable();
-	if (mm_has_pgste(mm))
+	if (mm_has_pgste(mm)) {
+		pmdp_clear_skeys(mm, pmdp, new);
 		pmdp_notify(mm, addr);
+	}
 	old = pmdp_flush_direct(mm, addr, pmdp);
 	*pmdp = new;
 	preempt_enable();
@@ -431,8 +451,10 @@ pmd_t pmdp_xchg_lazy(struct mm_struct *mm, unsigned long addr,
 	pmd_t old;
 
 	preempt_disable();
-	if (mm_has_pgste(mm))
+	if (mm_has_pgste(mm)) {
+		pmdp_clear_skeys(mm, pmdp, new);
 		pmdp_notify(mm, addr);
+	}
 	old = pmdp_flush_lazy(mm, addr, pmdp);
 	*pmdp = new;
 	preempt_enable();
-- 
2.14.3




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux