Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 5b3353949e89 ("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>

authored by

Henry Wang and committed by
Juergen Gross
a3607581 89af61fb

+23 -13
+23 -13
drivers/xen/xenbus/xenbus_probe.c
··· 65 65 #include "xenbus.h" 66 66 67 67 68 - static int xs_init_irq; 68 + static int xs_init_irq = -1; 69 69 int xen_store_evtchn; 70 70 EXPORT_SYMBOL_GPL(xen_store_evtchn); 71 71 72 72 struct xenstore_domain_interface *xen_store_interface; 73 73 EXPORT_SYMBOL_GPL(xen_store_interface); 74 + 75 + #define XS_INTERFACE_READY \ 76 + ((xen_store_interface != NULL) && \ 77 + (xen_store_interface->connection == XENSTORE_CONNECTED)) 74 78 75 79 enum xenstore_init xen_store_domain_type; 76 80 EXPORT_SYMBOL_GPL(xen_store_domain_type); ··· 755 751 { 756 752 xenstored_ready = 1; 757 753 758 - if (!xen_store_interface) { 754 + if (!xen_store_interface) 759 755 xen_store_interface = memremap(xen_store_gfn << XEN_PAGE_SHIFT, 760 756 XEN_PAGE_SIZE, MEMREMAP_WB); 761 - /* 762 - * Now it is safe to free the IRQ used for xenstore late 763 - * initialization. No need to unbind: it is about to be 764 - * bound again from xb_init_comms. Note that calling 765 - * unbind_from_irqhandler now would result in xen_evtchn_close() 766 - * being called and the event channel not being enabled again 767 - * afterwards, resulting in missed event notifications. 768 - */ 757 + /* 758 + * Now it is safe to free the IRQ used for xenstore late 759 + * initialization. No need to unbind: it is about to be 760 + * bound again from xb_init_comms. Note that calling 761 + * unbind_from_irqhandler now would result in xen_evtchn_close() 762 + * being called and the event channel not being enabled again 763 + * afterwards, resulting in missed event notifications. 764 + */ 765 + if (xs_init_irq >= 0) 769 766 free_irq(xs_init_irq, &xb_waitq); 770 - } 771 767 772 768 /* 773 769 * In the HVM case, xenbus_init() deferred its call to ··· 826 822 if (xen_store_domain_type == XS_PV || 827 823 (xen_store_domain_type == XS_HVM && 828 824 !xs_hvm_defer_init_for_callback() && 829 - xen_store_interface != NULL)) 825 + XS_INTERFACE_READY)) 830 826 xenbus_probe(); 831 827 832 828 /* ··· 835 831 * started, then probe. It will be triggered when communication 836 832 * starts happening, by waiting on xb_waitq. 837 833 */ 838 - if (xen_store_domain_type == XS_LOCAL || xen_store_interface == NULL) { 834 + if (xen_store_domain_type == XS_LOCAL || !XS_INTERFACE_READY) { 839 835 struct task_struct *probe_task; 840 836 841 837 probe_task = kthread_run(xenbus_probe_thread, NULL, ··· 1018 1014 xen_store_interface = 1019 1015 memremap(xen_store_gfn << XEN_PAGE_SHIFT, 1020 1016 XEN_PAGE_SIZE, MEMREMAP_WB); 1017 + if (!xen_store_interface) { 1018 + pr_err("%s: cannot map HVM_PARAM_STORE_PFN=%llx\n", 1019 + __func__, v); 1020 + err = -EINVAL; 1021 + goto out_error; 1022 + } 1021 1023 if (xen_store_interface->connection != XENSTORE_CONNECTED) 1022 1024 wait = true; 1023 1025 }