|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 5/7] x86/domain: Optimise the order of actions in arch_domain_create()
The only relevent initialisation for the idle domain is the context switch and
poisoned pointers. Collect these bits together early in the function and exit
when complete (although as a consequence, the e820 and vtsc lock
initialisation are moved forwards). This allows us to remove subsequent
is_idle_domain() checks and unindent most of the logic.
Furthermore, we no longer call these functions for the idle domain:
* mapcache_domain_init() and tsc_set_info() were previously guarded against
the idle domain, and have had their guards turned into ASSERT()s.
* pit_init() is implicitly guarded by has_vpit().
* psr_domain_init() no longer allocates a socket array.
Finally, two changes are introduced for the benefit of the following patch:
* For PV hardware domains, or XEN_X86_EMU_PIT into emflags rather than into
config->emulation_flags, to facilitating config becoming const.
* References to domcr_flags are moved until after the idle early exist, to
facilitiate them being unavailable for system domains.
No practical change in behaviour.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Wei Liu <wei.liu2@xxxxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
xen/arch/x86/domain.c | 152 ++++++++++++++++++++++-----------------------
xen/arch/x86/domain_page.c | 3 +-
xen/arch/x86/time.c | 4 +-
3 files changed, 78 insertions(+), 81 deletions(-)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 81ee992..48dc2b9 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -430,20 +430,37 @@ int arch_domain_create(struct domain *d, unsigned int
domcr_flags,
struct xen_arch_domainconfig *config)
{
bool paging_initialised = false;
+ uint32_t emflags;
int rc;
- if ( config == NULL && !is_idle_domain(d) )
- return -EINVAL;
-
- d->arch.s3_integrity = domcr_flags & XEN_DOMCTL_CDF_s3_integrity;
-
INIT_LIST_HEAD(&d->arch.pdev_list);
d->arch.relmem = RELMEM_not_started;
INIT_PAGE_LIST_HEAD(&d->arch.relmem_list);
- if ( d->domain_id && !is_idle_domain(d) &&
- cpu_has_amd_erratum(&boot_cpu_data, AMD_ERRATUM_121) )
+ spin_lock_init(&d->arch.e820_lock);
+ spin_lock_init(&d->arch.vtsc_lock);
+
+ /* Minimal initialisation for the idle domain. */
+ if ( unlikely(is_idle_domain(d)) )
+ {
+ static const struct arch_csw idle_csw = {
+ .from = paravirt_ctxt_switch_from,
+ .to = paravirt_ctxt_switch_to,
+ .tail = continue_idle_domain,
+ };
+
+ d->arch.ctxt_switch = &idle_csw;
+
+ d->arch.cpuid = ZERO_BLOCK_PTR; /* Catch stray misuses. */
+ d->arch.msr = ZERO_BLOCK_PTR;
+
+ return 0;
+ }
+ else if ( !config )
+ return -EINVAL;
+
+ if ( d->domain_id && cpu_has_amd_erratum(&boot_cpu_data, AMD_ERRATUM_121) )
{
if ( !opt_allow_unsafe )
{
@@ -456,83 +473,69 @@ int arch_domain_create(struct domain *d, unsigned int
domcr_flags,
d->domain_id);
}
- if ( is_idle_domain(d) )
- {
- d->arch.emulation_flags = 0;
- d->arch.cpuid = ZERO_BLOCK_PTR; /* Catch stray misuses. */
- d->arch.msr = ZERO_BLOCK_PTR;
- }
- else
- {
- uint32_t emflags;
+ d->arch.s3_integrity = domcr_flags & XEN_DOMCTL_CDF_s3_integrity;
- if ( is_hardware_domain(d) && is_pv_domain(d) )
- config->emulation_flags |= XEN_X86_EMU_PIT;
+ emflags = config->emulation_flags;
- emflags = config->emulation_flags;
- if ( emflags & ~XEN_X86_EMU_ALL )
- {
- printk(XENLOG_G_ERR "d%d: Invalid emulation bitmap: %#x\n",
- d->domain_id, emflags);
- return -EINVAL;
- }
+ if ( is_hardware_domain(d) && is_pv_domain(d) )
+ emflags |= XEN_X86_EMU_PIT;
- if ( !emulation_flags_ok(d, emflags) )
- {
- printk(XENLOG_G_ERR "d%d: Xen does not allow %s domain creation "
- "with the current selection of emulators: %#x\n",
- d->domain_id, is_hvm_domain(d) ? "HVM" : "PV", emflags);
- return -EOPNOTSUPP;
- }
- d->arch.emulation_flags = emflags;
+ if ( emflags & ~XEN_X86_EMU_ALL )
+ {
+ printk(XENLOG_G_ERR "d%d: Invalid emulation bitmap: %#x\n",
+ d->domain_id, emflags);
+ return -EINVAL;
}
- mapcache_domain_init(d);
+ if ( !emulation_flags_ok(d, emflags) )
+ {
+ printk(XENLOG_G_ERR "d%d: Xen does not allow %s domain creation "
+ "with the current selection of emulators: %#x\n",
+ d->domain_id, is_hvm_domain(d) ? "HVM" : "PV", emflags);
+ return -EOPNOTSUPP;
+ }
+ d->arch.emulation_flags = emflags;
HYPERVISOR_COMPAT_VIRT_START(d) =
is_pv_domain(d) ? __HYPERVISOR_COMPAT_VIRT_START : ~0u;
- if ( !is_idle_domain(d) )
- {
- /* Need to determine if HAP is enabled before initialising paging */
- if ( is_hvm_domain(d) )
- d->arch.hvm_domain.hap_enabled =
- hvm_funcs.hap_supported && (domcr_flags & XEN_DOMCTL_CDF_hap);
+ /* Need to determine if HAP is enabled before initialising paging */
+ if ( is_hvm_domain(d) )
+ d->arch.hvm_domain.hap_enabled =
+ hvm_funcs.hap_supported && (domcr_flags & XEN_DOMCTL_CDF_hap);
- if ( (rc = paging_domain_init(d, domcr_flags)) != 0 )
- goto fail;
- paging_initialised = 1;
+ if ( (rc = paging_domain_init(d, domcr_flags)) != 0 )
+ goto fail;
+ paging_initialised = true;
- if ( (rc = init_domain_cpuid_policy(d)) )
- goto fail;
+ if ( (rc = init_domain_cpuid_policy(d)) )
+ goto fail;
- if ( (rc = init_domain_msr_policy(d)) )
- goto fail;
+ if ( (rc = init_domain_msr_policy(d)) )
+ goto fail;
- d->arch.ioport_caps =
- rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex);
- rc = -ENOMEM;
- if ( d->arch.ioport_caps == NULL )
- goto fail;
+ d->arch.ioport_caps =
+ rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex);
+ rc = -ENOMEM;
+ if ( d->arch.ioport_caps == NULL )
+ goto fail;
- /*
- * The shared_info machine address must fit in a 32-bit field within a
- * 32-bit guest's start_info structure. Hence we specify MEMF_bits(32).
- */
- if ( (d->shared_info = alloc_xenheap_pages(0, MEMF_bits(32))) == NULL )
- goto fail;
+ /*
+ * The shared_info machine address must fit in a 32-bit field within a
+ * 32-bit guest's start_info structure. Hence we specify MEMF_bits(32).
+ */
+ if ( (d->shared_info = alloc_xenheap_pages(0, MEMF_bits(32))) == NULL )
+ goto fail;
- clear_page(d->shared_info);
- share_xen_page_with_guest(
- virt_to_page(d->shared_info), d, XENSHARE_writable);
+ clear_page(d->shared_info);
+ share_xen_page_with_guest(
+ virt_to_page(d->shared_info), d, XENSHARE_writable);
- if ( (rc = init_domain_irq_mapping(d)) != 0 )
- goto fail;
+ if ( (rc = init_domain_irq_mapping(d)) != 0 )
+ goto fail;
- if ( (rc = iommu_domain_init(d)) != 0 )
- goto fail;
- }
- spin_lock_init(&d->arch.e820_lock);
+ if ( (rc = iommu_domain_init(d)) != 0 )
+ goto fail;
psr_domain_init(d);
@@ -541,25 +544,18 @@ int arch_domain_create(struct domain *d, unsigned int
domcr_flags,
if ( (rc = hvm_domain_initialise(d)) != 0 )
goto fail;
}
- else if ( is_idle_domain(d) )
+ else if ( is_pv_domain(d) )
{
- static const struct arch_csw idle_csw = {
- .from = paravirt_ctxt_switch_from,
- .to = paravirt_ctxt_switch_to,
- .tail = continue_idle_domain,
- };
+ mapcache_domain_init(d);
- d->arch.ctxt_switch = &idle_csw;
- }
- else
- {
if ( (rc = pv_domain_initialise(d)) != 0 )
goto fail;
}
+ else
+ ASSERT_UNREACHABLE(); /* Not HVM and not PV? */
/* initialize default tsc behavior in case tools don't */
tsc_set_info(d, TSC_MODE_DEFAULT, 0UL, 0, 0);
- spin_lock_init(&d->arch.vtsc_lock);
/* PV/PVH guests get an emulated PIT too for video BIOSes to use. */
pit_init(d, cpu_khz);
diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c
index 3432a85..b5780f2 100644
--- a/xen/arch/x86/domain_page.c
+++ b/xen/arch/x86/domain_page.c
@@ -236,8 +236,7 @@ int mapcache_domain_init(struct domain *d)
struct mapcache_domain *dcache = &d->arch.pv_domain.mapcache;
unsigned int bitmap_pages;
- if ( !is_pv_domain(d) || is_idle_domain(d) )
- return 0;
+ ASSERT(is_pv_domain(d));
#ifdef NDEBUG
if ( !mem_hotplug && max_page <= PFN_DOWN(__pa(HYPERVISOR_VIRT_END - 1)) )
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index 1a6fde6..84c1c0c 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -2124,7 +2124,9 @@ void tsc_set_info(struct domain *d,
uint32_t tsc_mode, uint64_t elapsed_nsec,
uint32_t gtsc_khz, uint32_t incarnation)
{
- if ( is_idle_domain(d) || is_hardware_domain(d) )
+ ASSERT(!is_system_domain(d));
+
+ if ( is_hardware_domain(d) )
{
d->arch.vtsc = 0;
return;
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |