aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/xenbus/xenbus_probe.c')
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c137
1 files changed, 123 insertions, 14 deletions
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 217bcc092a96..27c48c90b2ab 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -674,29 +674,107 @@ void unregister_xenstore_notifier(struct notifier_block *nb)
674} 674}
675EXPORT_SYMBOL_GPL(unregister_xenstore_notifier); 675EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
676 676
677void xenbus_probe(struct work_struct *unused) 677static void xenbus_probe(void)
678{ 678{
679 xenstored_ready = 1; 679 xenstored_ready = 1;
680 680
681 /*
682 * In the HVM case, xenbus_init() deferred its call to
683 * xs_init() in case callbacks were not operational yet.
684 * So do it now.
685 */
686 if (xen_store_domain_type == XS_HVM)
687 xs_init();
688
681 /* Notify others that xenstore is up */ 689 /* Notify others that xenstore is up */
682 blocking_notifier_call_chain(&xenstore_chain, 0, NULL); 690 blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
683} 691}
684EXPORT_SYMBOL_GPL(xenbus_probe);
685 692
686static int __init xenbus_probe_initcall(void) 693/*
694 * Returns true when XenStore init must be deferred in order to
695 * allow the PCI platform device to be initialised, before we
696 * can actually have event channel interrupts working.
697 */
698static bool xs_hvm_defer_init_for_callback(void)
687{ 699{
688 if (!xen_domain()) 700#ifdef CONFIG_XEN_PVHVM
689 return -ENODEV; 701 return xen_store_domain_type == XS_HVM &&
702 !xen_have_vector_callback;
703#else
704 return false;
705#endif
706}
690 707
691 if (xen_initial_domain() || xen_hvm_domain()) 708static int xenbus_probe_thread(void *unused)
692 return 0; 709{
710 DEFINE_WAIT(w);
693 711
694 xenbus_probe(NULL); 712 /*
713 * We actually just want to wait for *any* trigger of xb_waitq,
714 * and run xenbus_probe() the moment it occurs.
715 */
716 prepare_to_wait(&xb_waitq, &w, TASK_INTERRUPTIBLE);
717 schedule();
718 finish_wait(&xb_waitq, &w);
719
720 DPRINTK("probing");
721 xenbus_probe();
695 return 0; 722 return 0;
696} 723}
697 724
725static int __init xenbus_probe_initcall(void)
726{
727 /*
728 * Probe XenBus here in the XS_PV case, and also XS_HVM unless we
729 * need to wait for the platform PCI device to come up.
730 */
731 if (xen_store_domain_type == XS_PV ||
732 (xen_store_domain_type == XS_HVM &&
733 !xs_hvm_defer_init_for_callback()))
734 xenbus_probe();
735
736 /*
737 * For XS_LOCAL, spawn a thread which will wait for xenstored
738 * or a xenstore-stubdom to be started, then probe. It will be
739 * triggered when communication starts happening, by waiting
740 * on xb_waitq.
741 */
742 if (xen_store_domain_type == XS_LOCAL) {
743 struct task_struct *probe_task;
744
745 probe_task = kthread_run(xenbus_probe_thread, NULL,
746 "xenbus_probe");
747 if (IS_ERR(probe_task))
748 return PTR_ERR(probe_task);
749 }
750 return 0;
751}
698device_initcall(xenbus_probe_initcall); 752device_initcall(xenbus_probe_initcall);
699 753
754int xen_set_callback_via(uint64_t via)
755{
756 struct xen_hvm_param a;
757 int ret;
758
759 a.domid = DOMID_SELF;
760 a.index = HVM_PARAM_CALLBACK_IRQ;
761 a.value = via;
762
763 ret = HYPERVISOR_hvm_op(HVMOP_set_param, &a);
764 if (ret)
765 return ret;
766
767 /*
768 * If xenbus_probe_initcall() deferred the xenbus_probe()
769 * due to the callback not functioning yet, we can do it now.
770 */
771 if (!xenstored_ready && xs_hvm_defer_init_for_callback())
772 xenbus_probe();
773
774 return ret;
775}
776EXPORT_SYMBOL_GPL(xen_set_callback_via);
777
700/* Set up event channel for xenstored which is run as a local process 778/* Set up event channel for xenstored which is run as a local process
701 * (this is normally used only in dom0) 779 * (this is normally used only in dom0)
702 */ 780 */
@@ -760,7 +838,7 @@ static struct notifier_block xenbus_resume_nb = {
760 838
761static int __init xenbus_init(void) 839static int __init xenbus_init(void)
762{ 840{
763 int err = 0; 841 int err;
764 uint64_t v = 0; 842 uint64_t v = 0;
765 xen_store_domain_type = XS_UNKNOWN; 843 xen_store_domain_type = XS_UNKNOWN;
766 844
@@ -800,6 +878,29 @@ static int __init xenbus_init(void)
800 err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); 878 err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
801 if (err) 879 if (err)
802 goto out_error; 880 goto out_error;
881 /*
882 * Uninitialized hvm_params are zero and return no error.
883 * Although it is theoretically possible to have
884 * HVM_PARAM_STORE_PFN set to zero on purpose, in reality it is
885 * not zero when valid. If zero, it means that Xenstore hasn't
886 * been properly initialized. Instead of attempting to map a
887 * wrong guest physical address return error.
888 *
889 * Also recognize all bits set as an invalid value.
890 */
891 if (!v || !~v) {
892 err = -ENOENT;
893 goto out_error;
894 }
895 /* Avoid truncation on 32-bit. */
896#if BITS_PER_LONG == 32
897 if (v > ULONG_MAX) {
898 pr_err("%s: cannot handle HVM_PARAM_STORE_PFN=%llx > ULONG_MAX\n",
899 __func__, v);
900 err = -EINVAL;
901 goto out_error;
902 }
903#endif
803 xen_store_gfn = (unsigned long)v; 904 xen_store_gfn = (unsigned long)v;
804 xen_store_interface = 905 xen_store_interface =
805 xen_remap(xen_store_gfn << XEN_PAGE_SHIFT, 906 xen_remap(xen_store_gfn << XEN_PAGE_SHIFT,
@@ -810,11 +911,17 @@ static int __init xenbus_init(void)
810 break; 911 break;
811 } 912 }
812 913
813 /* Initialize the interface to xenstore. */ 914 /*
814 err = xs_init(); 915 * HVM domains may not have a functional callback yet. In that
815 if (err) { 916 * case let xs_init() be called from xenbus_probe(), which will
816 pr_warn("Error initializing xenstore comms: %i\n", err); 917 * get invoked at an appropriate time.
817 goto out_error; 918 */
919 if (xen_store_domain_type != XS_HVM) {
920 err = xs_init();
921 if (err) {
922 pr_warn("Error initializing xenstore comms: %i\n", err);
923 goto out_error;
924 }
818 } 925 }
819 926
820 if ((xen_store_domain_type != XS_LOCAL) && 927 if ((xen_store_domain_type != XS_LOCAL) &&
@@ -828,8 +935,10 @@ static int __init xenbus_init(void)
828 */ 935 */
829 proc_create_mount_point("xen"); 936 proc_create_mount_point("xen");
830#endif 937#endif
938 return 0;
831 939
832out_error: 940out_error:
941 xen_store_domain_type = XS_UNKNOWN;
833 return err; 942 return err;
834} 943}
835 944