mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: dom0less delay xenstore initialization
To allocate the xenstore event channel and initialize the grant table entry, the xenstore domid is neeed. A dom0 is created before the domUs, so it is normally available through hardware_domain. With capabilities and dom0less, the xenstore domain may not be created first. Keep the population of the page and HVM_PARAM_STORE_PFN in the normal domain construction, but delay event channel creation and grant seeding to after all domUs are created. HVM_PARAM_STORE_PFN now serves as indication to setup xenstore since the device tree is no longer immediately available. 0 means no xenstore. ~0ULL means legacy so only the event channel needs setup, and any other value means to seed the page. dom0 needs to set xs_domid when it is serving as the xenstore domain. The domain running xenstored needs to be the handler for VIRQ_DOM_EXC, so set that as well - it otherwise defaults to hardware domain. Signed-off-by: Jason Andryuk <jason.andryuk@amd.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
1 parent
52cb53f181
commit
379a23677e
3 files changed
+53
-18
No files matched your search
@@ -20,6 +20,15 @@
|
||||
#include <asm/static-memory.h>
|
||||
#include <asm/static-shmem.h>
|
||||
|
||||
static domid_t __initdata xs_domid = DOMID_INVALID;
|
||||
static bool __initdata need_xenstore;
|
||||
|
||||
void __init set_xs_domain(struct domain *d)
|
||||
{
|
||||
xs_domid = d->domain_id;
|
||||
set_global_virq_handler(d, VIRQ_DOM_EXC);
|
||||
}
|
||||
|
||||
bool __init is_dom0less_mode(void)
|
||||
{
|
||||
struct bootmodules *mods = &bootinfo.modules;
|
||||
@@ -679,7 +688,7 @@ static int __init alloc_xenstore_evtchn(struct domain *d)
|
||||
int rc;
|
||||
|
||||
alloc.dom = d->domain_id;
|
||||
alloc.remote_dom = hardware_domain->domain_id;
|
||||
alloc.remote_dom = xs_domid;
|
||||
rc = evtchn_alloc_unbound(&alloc, 0);
|
||||
if ( rc )
|
||||
{
|
||||
@@ -745,16 +754,10 @@ static int __init alloc_xenstore_params(struct kernel_info *kinfo)
|
||||
struct domain *d = kinfo->d;
|
||||
int rc = 0;
|
||||
|
||||
if ( kinfo->dom0less_feature & (DOM0LESS_XENSTORE | DOM0LESS_XS_LEGACY) )
|
||||
{
|
||||
ASSERT(hardware_domain);
|
||||
rc = alloc_xenstore_evtchn(d);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
if ( (kinfo->dom0less_feature & (DOM0LESS_XENSTORE | DOM0LESS_XS_LEGACY))
|
||||
== (DOM0LESS_XENSTORE | DOM0LESS_XS_LEGACY) )
|
||||
d->arch.hvm.params[HVM_PARAM_STORE_PFN] = ~0ULL;
|
||||
}
|
||||
|
||||
if ( kinfo->dom0less_feature & DOM0LESS_XENSTORE )
|
||||
else if ( kinfo->dom0less_feature & DOM0LESS_XENSTORE )
|
||||
{
|
||||
rc = alloc_xenstore_page(d);
|
||||
if ( rc < 0 )
|
||||
@@ -764,6 +767,30 @@ static int __init alloc_xenstore_params(struct kernel_info *kinfo)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __init initialize_domU_xenstore(void)
|
||||
{
|
||||
struct domain *d;
|
||||
|
||||
if ( xs_domid == DOMID_INVALID )
|
||||
return;
|
||||
|
||||
for_each_domain( d )
|
||||
{
|
||||
uint64_t gfn = d->arch.hvm.params[HVM_PARAM_STORE_PFN];
|
||||
int rc;
|
||||
|
||||
if ( gfn == 0 )
|
||||
continue;
|
||||
|
||||
if ( is_xenstore_domain(d) )
|
||||
continue;
|
||||
|
||||
rc = alloc_xenstore_evtchn(d);
|
||||
if ( rc < 0 )
|
||||
panic("%pd: Failed to allocate xenstore_evtchn\n", d);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init domain_vcpu_affinity(struct domain *d,
|
||||
const struct dt_device_node *node)
|
||||
{
|
||||
@@ -899,17 +926,13 @@ static int __init construct_domU(struct domain *d,
|
||||
rc == -ENODATA ||
|
||||
(rc == 0 && !strcmp(dom0less_enhanced, "enabled")) )
|
||||
{
|
||||
if ( hardware_domain )
|
||||
kinfo.dom0less_feature = DOM0LESS_ENHANCED;
|
||||
else
|
||||
panic("At the moment, Xenstore support requires dom0 to be present\n");
|
||||
need_xenstore = true;
|
||||
kinfo.dom0less_feature = DOM0LESS_ENHANCED;
|
||||
}
|
||||
else if ( rc == 0 && !strcmp(dom0less_enhanced, "legacy") )
|
||||
{
|
||||
if ( hardware_domain )
|
||||
kinfo.dom0less_feature = DOM0LESS_ENHANCED_LEGACY;
|
||||
else
|
||||
panic("At the moment, Xenstore support requires dom0 to be present\n");
|
||||
need_xenstore = true;
|
||||
kinfo.dom0less_feature = DOM0LESS_ENHANCED_LEGACY;
|
||||
}
|
||||
else if ( rc == 0 && !strcmp(dom0less_enhanced, "no-xenstore") )
|
||||
kinfo.dom0less_feature = DOM0LESS_ENHANCED_NO_XS;
|
||||
@@ -1156,7 +1179,15 @@ void __init create_domUs(void)
|
||||
if ( rc )
|
||||
panic("Could not set up domain %s (rc = %d)\n",
|
||||
dt_node_name(node), rc);
|
||||
|
||||
if ( d_cfg.flags & XEN_DOMCTL_CDF_xs_domain )
|
||||
set_xs_domain(d);
|
||||
}
|
||||
|
||||
if ( need_xenstore && xs_domid == DOMID_INVALID )
|
||||
panic("xenstore requested, but xenstore domain not present\n");
|
||||
|
||||
initialize_domU_xenstore();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2408,6 +2408,8 @@ void __init create_dom0(void)
|
||||
rc = construct_dom0(dom0);
|
||||
if ( rc )
|
||||
panic("Could not set up DOM0 guest OS (rc = %d)\n", rc);
|
||||
|
||||
set_xs_domain(dom0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
void create_domUs(void);
|
||||
bool is_dom0less_mode(void);
|
||||
void set_xs_domain(struct domain *d);
|
||||
|
||||
#else /* !CONFIG_DOM0LESS_BOOT */
|
||||
|
||||
@@ -17,6 +18,7 @@ static inline bool is_dom0less_mode(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline void set_xs_domain(struct domain *d) {}
|
||||
|
||||
#endif /* CONFIG_DOM0LESS_BOOT */
|
||||
|
||||
|
||||