mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-07 22:42:04 +00:00
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: 5b3353949e
("xen: add support for initializing xenstore later as HVM domain")
Signed-off-by: Henry Wang <xin.wang2@amd.com>
Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Link: https://lore.kernel.org/r/20240517011516.1451087-1-xin.wang2@amd.com
Signed-off-by: Juergen Gross <jgross@suse.com>
This commit is contained in:
parent
89af61fb8f
commit
a3607581cd
@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user