|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 09/15] x86/PVH: split pvh_setup_vmx_realmode_helpers()
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);
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |