]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: s390: move gmap_shadow_pgt_lookup() into kvm
authorClaudio Imbrenda <imbrenda@linux.ibm.com>
Thu, 23 Jan 2025 14:46:24 +0000 (15:46 +0100)
committerClaudio Imbrenda <imbrenda@linux.ibm.com>
Fri, 31 Jan 2025 11:03:53 +0000 (12:03 +0100)
Move gmap_shadow_pgt_lookup() from mm/gmap.c into kvm/gaccess.c .

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Link: https://lore.kernel.org/r/20250123144627.312456-13-imbrenda@linux.ibm.com
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-ID: <20250123144627.312456-13-imbrenda@linux.ibm.com>

arch/s390/include/asm/gmap.h
arch/s390/kvm/gaccess.c
arch/s390/kvm/gmap.h
arch/s390/mm/gmap.c

index b489c458961878556d671ede30ffcdb0cf5804ec..4e73ef46d4b2a88fb184952b7aacb140a0611fd8 100644 (file)
@@ -125,8 +125,6 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt,
                    int fake);
 int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
                    int fake);
-int gmap_shadow_pgt_lookup(struct gmap *sg, unsigned long saddr,
-                          unsigned long *pgt, int *dat_protection, int *fake);
 int gmap_shadow_page(struct gmap *sg, unsigned long saddr, pte_t pte);
 
 void gmap_register_pte_notifier(struct gmap_notifier *);
@@ -142,6 +140,7 @@ void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns);
 int __s390_uv_destroy_range(struct mm_struct *mm, unsigned long start,
                            unsigned long end, bool interruptible);
 int kvm_s390_wiggle_split_folio(struct mm_struct *mm, struct folio *folio, bool split);
+unsigned long *gmap_table_walk(struct gmap *gmap, unsigned long gaddr, int level);
 
 /**
  * s390_uv_destroy_range - Destroy a range of pages in the given mm.
index 9816b0060fbe541909c29818e88aeb2d3ef60749..bb1340389369cbc8877a3af3933349f775699f07 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/gmap.h>
 #include <asm/dat-bits.h>
 #include "kvm-s390.h"
+#include "gmap.h"
 #include "gaccess.h"
 
 /*
@@ -1392,6 +1393,42 @@ shadow_pgt:
        return 0;
 }
 
+/**
+ * shadow_pgt_lookup() - find a shadow page table
+ * @sg: pointer to the shadow guest address space structure
+ * @saddr: the address in the shadow aguest address space
+ * @pgt: parent gmap address of the page table to get shadowed
+ * @dat_protection: if the pgtable is marked as protected by dat
+ * @fake: pgt references contiguous guest memory block, not a pgtable
+ *
+ * Returns 0 if the shadow page table was found and -EAGAIN if the page
+ * table was not found.
+ *
+ * Called with sg->mm->mmap_lock in read.
+ */
+static int shadow_pgt_lookup(struct gmap *sg, unsigned long saddr, unsigned long *pgt,
+                            int *dat_protection, int *fake)
+{
+       unsigned long *table;
+       struct page *page;
+       int rc;
+
+       spin_lock(&sg->guest_table_lock);
+       table = gmap_table_walk(sg, saddr, 1); /* get segment pointer */
+       if (table && !(*table & _SEGMENT_ENTRY_INVALID)) {
+               /* Shadow page tables are full pages (pte+pgste) */
+               page = pfn_to_page(*table >> PAGE_SHIFT);
+               *pgt = page->index & ~GMAP_SHADOW_FAKE_TABLE;
+               *dat_protection = !!(*table & _SEGMENT_ENTRY_PROTECT);
+               *fake = !!(page->index & GMAP_SHADOW_FAKE_TABLE);
+               rc = 0;
+       } else  {
+               rc = -EAGAIN;
+       }
+       spin_unlock(&sg->guest_table_lock);
+       return rc;
+}
+
 /**
  * kvm_s390_shadow_fault - handle fault on a shadow page table
  * @vcpu: virtual cpu
@@ -1415,6 +1452,9 @@ int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg,
        int dat_protection, fake;
        int rc;
 
+       if (KVM_BUG_ON(!gmap_is_shadow(sg), vcpu->kvm))
+               return -EFAULT;
+
        mmap_read_lock(sg->mm);
        /*
         * We don't want any guest-2 tables to change - so the parent
@@ -1423,7 +1463,7 @@ int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg,
         */
        ipte_lock(vcpu->kvm);
 
-       rc = gmap_shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection, &fake);
+       rc = shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection, &fake);
        if (rc)
                rc = kvm_s390_shadow_tables(sg, saddr, &pgt, &dat_protection,
                                            &fake);
index 978f541059f0275c160d7dde30696a070ca2eb19..c8f031c9ea5f2a2acf3d7c442d8784e34a220189 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef ARCH_KVM_S390_GMAP_H
 #define ARCH_KVM_S390_GMAP_H
 
+#define GMAP_SHADOW_FAKE_TABLE 1ULL
+
 int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb);
 int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr);
 int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr);
index 07df1a7b5ebe5b8a00714bef3c9ea8a07d074b15..918ea14515a1ea0a753c73725f0739f96b0ee497 100644 (file)
@@ -36,8 +36,6 @@
 
 #define GMAP_SHADOW_FAKE_TABLE 1ULL
 
-static inline unsigned long *gmap_table_walk(struct gmap *gmap, unsigned long gaddr, int level);
-
 static struct page *gmap_alloc_crst(void)
 {
        struct page *page;
@@ -738,8 +736,7 @@ static void gmap_call_notifier(struct gmap *gmap, unsigned long start,
  *
  * Note: Can also be called for shadow gmaps.
  */
-static inline unsigned long *gmap_table_walk(struct gmap *gmap,
-                                            unsigned long gaddr, int level)
+unsigned long *gmap_table_walk(struct gmap *gmap, unsigned long gaddr, int level)
 {
        const int asce_type = gmap->asce & _ASCE_TYPE_MASK;
        unsigned long *table = gmap->table;
@@ -790,6 +787,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap,
        }
        return table;
 }
+EXPORT_SYMBOL(gmap_table_walk);
 
 /**
  * gmap_pte_op_walk - walk the gmap page table, get the page table lock
@@ -1744,46 +1742,6 @@ out_free:
 }
 EXPORT_SYMBOL_GPL(gmap_shadow_sgt);
 
-/**
- * gmap_shadow_pgt_lookup - find a shadow page table
- * @sg: pointer to the shadow guest address space structure
- * @saddr: the address in the shadow aguest address space
- * @pgt: parent gmap address of the page table to get shadowed
- * @dat_protection: if the pgtable is marked as protected by dat
- * @fake: pgt references contiguous guest memory block, not a pgtable
- *
- * Returns 0 if the shadow page table was found and -EAGAIN if the page
- * table was not found.
- *
- * Called with sg->mm->mmap_lock in read.
- */
-int gmap_shadow_pgt_lookup(struct gmap *sg, unsigned long saddr,
-                          unsigned long *pgt, int *dat_protection,
-                          int *fake)
-{
-       unsigned long *table;
-       struct page *page;
-       int rc;
-
-       BUG_ON(!gmap_is_shadow(sg));
-       spin_lock(&sg->guest_table_lock);
-       table = gmap_table_walk(sg, saddr, 1); /* get segment pointer */
-       if (table && !(*table & _SEGMENT_ENTRY_INVALID)) {
-               /* Shadow page tables are full pages (pte+pgste) */
-               page = pfn_to_page(*table >> PAGE_SHIFT);
-               *pgt = page->index & ~GMAP_SHADOW_FAKE_TABLE;
-               *dat_protection = !!(*table & _SEGMENT_ENTRY_PROTECT);
-               *fake = !!(page->index & GMAP_SHADOW_FAKE_TABLE);
-               rc = 0;
-       } else  {
-               rc = -EAGAIN;
-       }
-       spin_unlock(&sg->guest_table_lock);
-       return rc;
-
-}
-EXPORT_SYMBOL_GPL(gmap_shadow_pgt_lookup);
-
 /**
  * gmap_shadow_pgt - instantiate a shadow page table
  * @sg: pointer to the shadow guest address space structure