in xenbus/xenbus_probe.c [910:1014]
static int __init xenbus_init(void)
{
int err;
uint64_t v = 0;
xen_store_domain_type = XS_UNKNOWN;
if (!xen_domain())
return -ENODEV;
xenbus_ring_ops_init();
if (xen_pv_domain())
xen_store_domain_type = XS_PV;
if (xen_hvm_domain())
xen_store_domain_type = XS_HVM;
if (xen_hvm_domain() && xen_initial_domain())
xen_store_domain_type = XS_LOCAL;
if (xen_pv_domain() && !xen_start_info->store_evtchn)
xen_store_domain_type = XS_LOCAL;
if (xen_pv_domain() && xen_start_info->store_evtchn)
xenstored_ready = 1;
switch (xen_store_domain_type) {
case XS_LOCAL:
err = xenstored_local_init();
if (err)
goto out_error;
xen_store_interface = gfn_to_virt(xen_store_gfn);
break;
case XS_PV:
xen_store_evtchn = xen_start_info->store_evtchn;
xen_store_gfn = xen_start_info->store_mfn;
xen_store_interface = gfn_to_virt(xen_store_gfn);
break;
case XS_HVM:
err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
if (err)
goto out_error;
xen_store_evtchn = (int)v;
err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
if (err)
goto out_error;
/*
* Uninitialized hvm_params are zero and return no error.
* Although it is theoretically possible to have
* HVM_PARAM_STORE_PFN set to zero on purpose, in reality it is
* not zero when valid. If zero, it means that Xenstore hasn't
* been properly initialized. Instead of attempting to map a
* wrong guest physical address return error.
*
* Also recognize all bits set as an invalid value.
*/
if (!v || !~v) {
err = -ENOENT;
goto out_error;
}
/* Avoid truncation on 32-bit. */
#if BITS_PER_LONG == 32
if (v > ULONG_MAX) {
pr_err("%s: cannot handle HVM_PARAM_STORE_PFN=%llx > ULONG_MAX\n",
__func__, v);
err = -EINVAL;
goto out_error;
}
#endif
xen_store_gfn = (unsigned long)v;
xen_store_interface =
xen_remap(xen_store_gfn << XEN_PAGE_SHIFT,
XEN_PAGE_SIZE);
break;
default:
pr_warn("Xenstore state unknown\n");
break;
}
/*
* HVM domains may not have a functional callback yet. In that
* case let xs_init() be called from xenbus_probe(), which will
* get invoked at an appropriate time.
*/
if (xen_store_domain_type != XS_HVM) {
err = xs_init();
if (err) {
pr_warn("Error initializing xenstore comms: %i\n", err);
goto out_error;
}
}
if ((xen_store_domain_type != XS_LOCAL) &&
(xen_store_domain_type != XS_UNKNOWN))
xen_resume_notifier_register(&xenbus_resume_nb);
#ifdef CONFIG_XEN_COMPAT_XENFS
/*
* Create xenfs mountpoint in /proc for compatibility with
* utilities that expect to find "xenbus" under "/proc/xen".
*/
proc_create_mount_point("xen");
#endif
return 0;
out_error:
xen_store_domain_type = XS_UNKNOWN;
return err;
}