]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: s390: Fix gmap_helper_zap_one_page() again
authorClaudio Imbrenda <imbrenda@linux.ibm.com>
Tue, 4 Nov 2025 15:40:48 +0000 (16:40 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Mon, 8 Dec 2025 12:06:14 +0000 (13:06 +0100)
A few checks were missing in gmap_helper_zap_one_page(), which can lead
to memory corruption in the guest under specific circumstances.

Add the missing checks.

Fixes: 5deafa27d9ae ("KVM: s390: Fix to clear PTE when discarding a swapped page")
Cc: stable@vger.kernel.org
Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/mm/gmap_helpers.c

index 549f14ad08afebe79d553b7aff51be2fcbd5c297..d41b19925a5ad133642b5494561b06b7ec485783 100644 (file)
@@ -47,6 +47,7 @@ static void ptep_zap_softleaf_entry(struct mm_struct *mm, softleaf_t entry)
 void gmap_helper_zap_one_page(struct mm_struct *mm, unsigned long vmaddr)
 {
        struct vm_area_struct *vma;
+       unsigned long pgstev;
        spinlock_t *ptl;
        pgste_t pgste;
        pte_t *ptep;
@@ -65,9 +66,13 @@ void gmap_helper_zap_one_page(struct mm_struct *mm, unsigned long vmaddr)
        if (pte_swap(*ptep)) {
                preempt_disable();
                pgste = pgste_get_lock(ptep);
+               pgstev = pgste_val(pgste);
 
-               ptep_zap_softleaf_entry(mm, softleaf_from_pte(*ptep));
-               pte_clear(mm, vmaddr, ptep);
+               if ((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED ||
+                   (pgstev & _PGSTE_GPS_ZERO)) {
+                       ptep_zap_softleaf_entry(mm, softleaf_from_pte(*ptep));
+                       pte_clear(mm, vmaddr, ptep);
+               }
 
                pgste_set_unlock(ptep, pgste);
                preempt_enable();