Commit a3607581 authored by Henry Wang's avatar Henry Wang Committed by Juergen Gross

drivers/xen: Improve the late XenStore init protocol

Currently, the late XenStore init protocol is only triggered properly
for the case that HVM_PARAM_STORE_PFN is ~0ULL (invalid). For the
case that XenStore interface is allocated but not ready (the connection
status is not XENSTORE_CONNECTED), Linux should also wait until the
XenStore is set up properly.

Introduce a macro to describe the XenStore interface is ready, use
it in xenbus_probe_initcall() to select the code path of doing the
late XenStore init protocol or not. Since now we have more than one
condition for XenStore late init, rework the check in xenbus_probe()
for the free_irq().

Take the opportunity to enhance the check of the allocated XenStore
interface can be properly mapped, and return error early if the
memremap() fails.

Fixes: 5b335394 ("xen: add support for initializing xenstore later as HVM domain")
Signed-off-by: default avatarHenry Wang <xin.wang2@amd.com>
Signed-off-by: default avatarMichal Orzel <michal.orzel@amd.com>
Reviewed-by: default avatarStefano Stabellini <sstabellini@kernel.org>
Link: https://lore.kernel.org/r/20240517011516.1451087-1-xin.wang2@amd.comSigned-off-by: default avatarJuergen Gross <jgross@suse.com>
parent 89af61fb
...@@ -65,13 +65,17 @@ ...@@ -65,13 +65,17 @@
#include "xenbus.h" #include "xenbus.h"
static int xs_init_irq; static int xs_init_irq = -1;
int xen_store_evtchn; int xen_store_evtchn;
EXPORT_SYMBOL_GPL(xen_store_evtchn); EXPORT_SYMBOL_GPL(xen_store_evtchn);
struct xenstore_domain_interface *xen_store_interface; struct xenstore_domain_interface *xen_store_interface;
EXPORT_SYMBOL_GPL(xen_store_interface); EXPORT_SYMBOL_GPL(xen_store_interface);
#define XS_INTERFACE_READY \
((xen_store_interface != NULL) && \
(xen_store_interface->connection == XENSTORE_CONNECTED))
enum xenstore_init xen_store_domain_type; enum xenstore_init xen_store_domain_type;
EXPORT_SYMBOL_GPL(xen_store_domain_type); EXPORT_SYMBOL_GPL(xen_store_domain_type);
...@@ -751,7 +755,7 @@ static void xenbus_probe(void) ...@@ -751,7 +755,7 @@ static void xenbus_probe(void)
{ {
xenstored_ready = 1; xenstored_ready = 1;
if (!xen_store_interface) { if (!xen_store_interface)
xen_store_interface = memremap(xen_store_gfn << XEN_PAGE_SHIFT, xen_store_interface = memremap(xen_store_gfn << XEN_PAGE_SHIFT,
XEN_PAGE_SIZE, MEMREMAP_WB); XEN_PAGE_SIZE, MEMREMAP_WB);
/* /*
...@@ -762,8 +766,8 @@ static void xenbus_probe(void) ...@@ -762,8 +766,8 @@ static void xenbus_probe(void)
* being called and the event channel not being enabled again * being called and the event channel not being enabled again
* afterwards, resulting in missed event notifications. * afterwards, resulting in missed event notifications.
*/ */
if (xs_init_irq >= 0)
free_irq(xs_init_irq, &xb_waitq); free_irq(xs_init_irq, &xb_waitq);
}
/* /*
* In the HVM case, xenbus_init() deferred its call to * In the HVM case, xenbus_init() deferred its call to
...@@ -822,7 +826,7 @@ static int __init xenbus_probe_initcall(void) ...@@ -822,7 +826,7 @@ static int __init xenbus_probe_initcall(void)
if (xen_store_domain_type == XS_PV || if (xen_store_domain_type == XS_PV ||
(xen_store_domain_type == XS_HVM && (xen_store_domain_type == XS_HVM &&
!xs_hvm_defer_init_for_callback() && !xs_hvm_defer_init_for_callback() &&
xen_store_interface != NULL)) XS_INTERFACE_READY))
xenbus_probe(); xenbus_probe();
/* /*
...@@ -831,7 +835,7 @@ static int __init xenbus_probe_initcall(void) ...@@ -831,7 +835,7 @@ static int __init xenbus_probe_initcall(void)
* started, then probe. It will be triggered when communication * started, then probe. It will be triggered when communication
* starts happening, by waiting on xb_waitq. * starts happening, by waiting on xb_waitq.
*/ */
if (xen_store_domain_type == XS_LOCAL || xen_store_interface == NULL) { if (xen_store_domain_type == XS_LOCAL || !XS_INTERFACE_READY) {
struct task_struct *probe_task; struct task_struct *probe_task;
probe_task = kthread_run(xenbus_probe_thread, NULL, probe_task = kthread_run(xenbus_probe_thread, NULL,
...@@ -1014,6 +1018,12 @@ static int __init xenbus_init(void) ...@@ -1014,6 +1018,12 @@ static int __init xenbus_init(void)
xen_store_interface = xen_store_interface =
memremap(xen_store_gfn << XEN_PAGE_SHIFT, memremap(xen_store_gfn << XEN_PAGE_SHIFT,
XEN_PAGE_SIZE, MEMREMAP_WB); XEN_PAGE_SIZE, MEMREMAP_WB);
if (!xen_store_interface) {
pr_err("%s: cannot map HVM_PARAM_STORE_PFN=%llx\n",
__func__, v);
err = -EINVAL;
goto out_error;
}
if (xen_store_interface->connection != XENSTORE_CONNECTED) if (xen_store_interface->connection != XENSTORE_CONNECTED)
wait = true; wait = true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment