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

[PATCH 09/15] x86/PVH: split pvh_setup_vmx_realmode_helpers()


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Mon, 12 Oct 2026 10:24:07 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=google header.d=suse.com header.i="@suse.com" header.h="Content-Transfer-Encoding:Content-Type:In-Reply-To:Autocrypt:Content-Language:References:Cc:To:From:Subject:User-Agent:MIME-Version:Date:Message-ID"
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>, Roger Pau Monné <roger@xxxxxxxxxxxxxx>
  • Delivery-date: Mon, 12 Oct 2026 08:24:09 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

All E820 manipulations want to happen before the initrd is placed, or else
pvh_steal_ram() may steal from the tail part of it. While this is
currently suitably ordered, mapping the initrd directly into Dom0 will
want to happen ahead of pvh_populate_p2m(). Hence as a third step, split
placing VMX data (if needed at all) from actually populating it.

Also move the invocation of pvh_setup_vmx_realmode_helpers() out of
pvh_populate_p2m(). Make it unconditional as well, instead bailing from
the function when pvh_place_vmx_realmode_helpers() wasn't called.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -268,26 +268,30 @@ static int __init pvh_add_mem_range(stru
     return 0;
 }
 
-static int __init pvh_setup_vmx_realmode_helpers(struct domain *d)
+struct vmx_info {
+    paddr_t tss;
+    gfn_t identpt;
+};
+
+static int __init pvh_place_vmx_realmode_helpers(
+    struct domain *d,
+    struct vmx_info *info)
 {
-    uint32_t rc, *ident_pt;
-    mfn_t mfn;
     paddr_t gaddr;
-    struct vcpu *v = d->vcpu[0];
 
     /*
-     * Steal some space from the last RAM region below 4GB and use it to
-     * store the real-mode TSS. It needs to be aligned to 128 so that the
-     * TSS structure (which accounts for the first 104b) doesn't cross
-     * a page boundary.
+     * Steal some space from the last RAM region below 4GB to store the
+     * real-mode TSS.  It needs to be aligned to 128 so that the TSS
+     * structure (which accounts for the first 104b) doesn't cross a page
+     * boundary.
      */
     if ( !pvh_steal_ram(d, HVM_VM86_TSS_SIZE, 128, GB(4), &gaddr) )
     {
-        if ( hvm_copy_to_guest_phys(gaddr, NULL, HVM_VM86_TSS_SIZE, v) !=
-             HVMTRANS_okay )
-            printk("Unable to zero VM86 TSS area\n");
         d->arch.hvm.params[HVM_PARAM_VM86_TSS_SIZED] =
             VM86_TSS_UPDATED | ((uint64_t)HVM_VM86_TSS_SIZE << 32) | gaddr;
+
+        info->tss = gaddr;
+
         if ( pvh_add_mem_range(d, gaddr, gaddr + HVM_VM86_TSS_SIZE,
                                E820_RESERVED) )
             printk("Unable to set VM86 TSS as reserved in the memory map\n");
@@ -302,12 +306,41 @@ static int __init pvh_setup_vmx_realmode
         return -ENOMEM;
     }
 
+    if ( pvh_add_mem_range(d, gaddr, gaddr + PAGE_SIZE, E820_RESERVED) )
+        printk("Unable to set identity page tables as reserved in the memory 
map\n");
+
+    d->arch.hvm.params[HVM_PARAM_IDENT_PT] = gaddr;
+    info->identpt = _gfn(PFN_DOWN(gaddr));
+
+    return 0;
+}
+
+static int __init pvh_setup_vmx_realmode_helpers(
+    const struct domain *d,
+    const struct vmx_info *info)
+{
+    uint32_t rc, *ident_pt;
+    mfn_t mfn;
+    struct vcpu *v = d->vcpu[0];
+
+    /* Bail if no space needed reserving in the first place. */
+    if ( gfn_eq(info->identpt, _gfn(0)) )
+        return 0;
+
+    /* Store the real-mode TSS, if space for it was successfully stolen. */
+    if ( info->tss )
+    {
+        if ( hvm_copy_to_guest_phys(info->tss, NULL, HVM_VM86_TSS_SIZE, v) !=
+             HVMTRANS_okay )
+            printk("Unable to zero VM86 TSS area\n");
+    }
+
     /*
      * Identity-map page table is required for running with CR0.PG=0
      * when using Intel EPT. Create a 32-bit non-PAE page directory of
      * superpages.
      */
-    ident_pt = map_domain_gfn(p2m_get_hostp2m(d), _gfn(PFN_DOWN(gaddr)),
+    ident_pt = map_domain_gfn(p2m_get_hostp2m(d), info->identpt,
                               &mfn, 0, &rc);
     if ( ident_pt == NULL )
     {
@@ -317,9 +350,6 @@ static int __init pvh_setup_vmx_realmode
     write_32bit_pse_identmap(ident_pt);
     unmap_domain_page(ident_pt);
     put_page(mfn_to_page(mfn));
-    d->arch.hvm.params[HVM_PARAM_IDENT_PT] = gaddr;
-    if ( pvh_add_mem_range(d, gaddr, gaddr + PAGE_SIZE, E820_RESERVED) )
-            printk("Unable to set identity page tables as reserved in the 
memory map\n");
 
     return 0;
 }
@@ -481,18 +511,6 @@ static int __init pvh_populate_p2m(
         }
     }
 
-    if ( using_vmx() && !paging_mode_shadow(d) && !vmx_unrestricted_guest(v) )
-    {
-        /*
-         * Since Dom0 cannot be migrated, we will only setup the
-         * unrestricted guest helpers if they are needed by the current
-         * hardware we are running on.
-         */
-        rc = pvh_setup_vmx_realmode_helpers(d);
-        if ( rc )
-            return rc;
-    }
-
     if ( opt_dom0_verbose )
         print_order_stats(d);
 
@@ -1402,6 +1420,7 @@ int __init dom0_construct_pvh(const stru
     struct e820entry *orig_e820;
     unsigned int nr_orig_e820;
     struct acpi_info acpi = {};
+    struct vmx_info vmx = {};
     int rc;
 
     printk(XENLOG_INFO "*** Building a PVH Dom%d ***\n", d->domain_id);
@@ -1462,6 +1481,22 @@ int __init dom0_construct_pvh(const stru
         return rc;
     }
 
+    /*
+     * Since Dom0 cannot be migrated, only set up the unrestricted guest
+     * helpers if they are needed by the hardware we are running on.
+     */
+    if ( using_vmx() && !paging_mode_shadow(d) &&
+         /*
+          * TODO: Unrestricted Guest should be a domain property, not a vCPU
+          * one.
+          */
+         !vmx_unrestricted_guest(d->vcpu[0]) )
+    {
+        rc = pvh_place_vmx_realmode_helpers(d, &vmx);
+        if ( rc )
+            return rc;
+    }
+
     rc = pvh_populate_p2m(d, orig_e820, nr_orig_e820);
     if ( rc )
     {
@@ -1492,6 +1527,10 @@ int __init dom0_construct_pvh(const stru
         return rc;
     }
 
+    rc = pvh_setup_vmx_realmode_helpers(d, &vmx);
+    if ( rc )
+        return rc;
+
     if ( opt_dom0_verbose )
     {
         printk("Dom%u memory map:\n", d->domain_id);




 


Rackspace

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