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

[RFC 3/4] Add xen superpage splitting support to arm


  • To: "Smith, Jackson" <rsmith@xxxxxxxxxxxxxxxxxxxxx>
  • From: "Smith, Jackson" <rsmith@xxxxxxxxxxxxxxxxxxxxx>
  • Date: Tue, 13 Dec 2022 19:54:07 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=riversideresearch.org; dmarc=pass action=none header.from=riversideresearch.org; dkim=pass header.d=riversideresearch.org; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector5401; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=I0hQaAJM6caWYQsVLchpOdKLdgvJiFe099wRxpfgIbQ=; b=1CKsVqn1PcNis65wzRqOGVxOjJkHRIBph4jSu8QzQUZppcZ2pg8KDzg6FLmy4XIYVzN8lDeXgN/fIseSD1659V3cUYgszp6f1Dxiczc35cCaqHMCunlQ+TZ/PCMTaqDbQ0jHZoijOO6RXA+3vvkBircDtzU/kEIXsb9EoDXX76yqybIjO32PBgW35nVrH2/y8DpYPhiJV4F40jKQj8bmKl+2uGV9lGDfJ1Hwr6HBBghju6NS9+QwaVG0WEC1HTINSN4/rLcMEShzX7TPoJKvQcIfqtSqypybIJBNbSD58zj/waMQVJ8MjIwd6k56OD75wzEOIt7lFe2lvq22YJvGwA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector5401; d=microsoft.com; cv=none; b=O+/0vzajBh+OmvEUVk170fpT1FVhL9xZerkWC9wVoBhm+76ZUfWDDiSq53jgf484a0FCKz7iykqFkUS1g+NzXrBdWOgjdKYTnDBVkOUPqpbcCyIrbTxWfo1+XlATZ+tCexOiqankzhuunFudI9knhUczE7H35F3/nze2i7Uj0oXNp+x7avawrMOx87K2Y/N7pdb7Y8nw62H20CUh629cV8HpGsodfD9bpdoGkXql/0Xure20hcaFD9L1rKSXUCJmhDRXeoomnmhRna9NDsY+OsABU4hgVMtReoHw9HPyfXhf9aalzsDbZWdUboprJoXimBZLAqxn3qL52TYFlIOqmA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=RiversideResearch.org;
  • Cc: "Brookes, Scott" <sbrookes@xxxxxxxxxxxxxxxxxxxxx>, Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, "bertrand.marquis@xxxxxxx" <bertrand.marquis@xxxxxxx>, "jbeulich@xxxxxxxx" <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, "demi@xxxxxxxxxxxxxxxxxxxxxx" <demi@xxxxxxxxxxxxxxxxxxxxxx>, "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>, "christopher.w.clark@xxxxxxxxx" <christopher.w.clark@xxxxxxxxx>
  • Delivery-date: Tue, 13 Dec 2022 19:54:16 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Suggested_attachment_session_id: a5e26e9e-108f-3533-e10a-338a3d7bfe08
  • Thread-index: AQHZDyypbad3do/0AUGsmgE77Sct8w==
  • Thread-topic: [RFC 3/4] Add xen superpage splitting support to arm

Updates xen_pt_update_entry function from xen/arch/arm/mm.c to
automatically split superpages as needed.
---
 xen/arch/arm/mm.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 78 insertions(+), 13 deletions(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 6301752..91b9c2b 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -753,8 +753,78 @@ static int create_xen_table(lpae_t *entry)
 }
 
 #define XEN_TABLE_MAP_FAILED 0
-#define XEN_TABLE_SUPER_PAGE 1
-#define XEN_TABLE_NORMAL_PAGE 2
+#define XEN_TABLE_NORMAL_PAGE 1
+
+/* More or less taken from p2m_split_superpage, without the p2m stuff */
+static bool xen_split_superpage(lpae_t *entry, unsigned int level,
+                                unsigned int target, const unsigned int 
*offsets)
+{
+    struct page_info *page;
+    lpae_t pte, *table;
+    unsigned int i;
+    bool rv = true;
+
+    mfn_t mfn = lpae_get_mfn(*entry);
+    unsigned int next_level = level + 1;
+    unsigned int level_order = XEN_PT_LEVEL_ORDER(next_level);
+
+    ASSERT(level < target);
+    ASSERT(lpae_is_superpage(*entry, level));
+
+    page = alloc_domheap_page(NULL, 0);
+    if ( !page )
+        return false;
+
+    table = __map_domain_page(page);
+
+    /*
+     * We are either splitting a first level 1G page into 512 second level
+     * 2M pages, or a second level 2M page into 512 third level 4K pages.
+     */
+    for ( i = 0; i < XEN_PT_LPAE_ENTRIES; i++ )
+    {
+        lpae_t *new_entry = table + i;
+
+        /*
+         * Use the content of the superpage entry and override
+         * the necessary fields. So the correct permission are kept.
+         */
+        pte = *entry;
+        lpae_set_mfn(pte, mfn_add(mfn, i << level_order));
+
+        /*
+         * First and second level pages set walk.table = 0, but third
+         * level entries set walk.table = 1.
+         */
+        pte.walk.table = (next_level == 3);
+
+        write_pte(new_entry, pte);
+    }
+
+    /*
+     * Shatter superpage in the page to the level we want to make the
+     * changes.
+     * This is done outside the loop to avoid checking the offset to
+     * know whether the entry should be shattered for every entry.
+     */
+    if ( next_level != target )
+        rv = xen_split_superpage(table + offsets[next_level],
+                                 level + 1, target, offsets);
+
+    clean_dcache_va_range(table, PAGE_SIZE);
+    unmap_domain_page(table);
+
+    /*
+     * Generate the entry for this new table we created,
+     * and write it back in place of the superpage entry.
+     */
+    pte = mfn_to_xen_entry(page_to_mfn(page), MT_NORMAL);
+    pte.pt.table = 1;
+    write_pte(entry, pte);
+    clean_dcache(*entry);
+
+    return rv;
+}
 
 /*
  * Take the currently mapped table, find the corresponding entry,
@@ -767,16 +837,15 @@ static int create_xen_table(lpae_t *entry)
  *  XEN_TABLE_MAP_FAILED: Either read_only was set and the entry
  *  was empty, or allocating a new page failed.
  *  XEN_TABLE_NORMAL_PAGE: next level mapped normally
- *  XEN_TABLE_SUPER_PAGE: The next entry points to a superpage.
  */
 static int xen_pt_next_level(bool read_only, unsigned int level,
-                             lpae_t **table, unsigned int offset)
+                             lpae_t **table, const unsigned int *offsets)
 {
     lpae_t *entry;
     int ret;
     mfn_t mfn;
 
-    entry = *table + offset;
+    entry = *table + offsets[level];
 
     if ( !lpae_is_valid(*entry) )
     {
@@ -790,7 +859,8 @@ static int xen_pt_next_level(bool read_only, unsigned int 
level,
 
     /* The function xen_pt_next_level is never called at the 3rd level */
     if ( lpae_is_mapping(*entry, level) )
-        return XEN_TABLE_SUPER_PAGE;
+        /* Shatter the superpage before continuing */
+        xen_split_superpage(entry, level, level + 1, offsets);
 
     mfn = lpae_get_mfn(*entry);
 
@@ -915,7 +985,7 @@ static int xen_pt_update_entry(mfn_t root, unsigned long 
virt,
     table = xen_map_table(root);
     for ( level = HYP_PT_ROOT_LEVEL; level < target; level++ )
     {
-        rc = xen_pt_next_level(read_only, level, &table, offsets[level]);
+        rc = xen_pt_next_level(read_only, level, &table, offsets);
         if ( rc == XEN_TABLE_MAP_FAILED )
         {
             /*
@@ -941,12 +1011,7 @@ static int xen_pt_update_entry(mfn_t root, unsigned long 
virt,
             break;
     }
 
-    if ( level != target )
-    {
-        mm_printk("%s: Shattering superpage is not supported\n", __func__);
-        rc = -EOPNOTSUPP;
-        goto out;
-    }
+    BUG_ON( level != target );
 
     entry = table + offsets[level];
 
-- 
2.7.4




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.