diff options
author | Daniel De Graaf <dgdegra@tycho.nsa.gov> | 2011-10-13 16:07:08 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-10-14 09:25:18 -0400 |
commit | e4184aaf3b2c4f2b69306f6cfc4bab8733c6c5f1 (patch) | |
tree | 0a7c8492040c7696a2fed05884fa71c6a494c40d /drivers/xen | |
parent | 77447991b6c9aef83d101aae4a9e5d83c206b9c5 (diff) |
xenbus: don't rely on xen_initial_domain to detect local xenstore
The xenstore daemon does not have to run in the xen initial domain;
however, Linux currently uses xen_initial_domain to test if a loopback
event channel should be used instead of the event channel provided in
Xen's start_info structure. Instead, if the event channel passed in the
start_info structure is not valid, assume that this domain will run
xenstored locally and set up the event channel.
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Ian Campbell <Ian.Campbell@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/xenbus/xenbus_probe.c | 101 |
1 files changed, 53 insertions, 48 deletions
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index d5347fe15882..13b0f05bafb7 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -696,64 +696,74 @@ static int __init xenbus_probe_initcall(void) | |||
696 | 696 | ||
697 | device_initcall(xenbus_probe_initcall); | 697 | device_initcall(xenbus_probe_initcall); |
698 | 698 | ||
699 | static int __init xenbus_init(void) | 699 | /* Set up event channel for xenstored which is run as a local process |
700 | * (this is normally used only in dom0) | ||
701 | */ | ||
702 | static int __init xenstored_local_init(void) | ||
700 | { | 703 | { |
701 | int err = 0; | 704 | int err = 0; |
702 | unsigned long page = 0; | 705 | unsigned long page = 0; |
706 | struct evtchn_alloc_unbound alloc_unbound; | ||
703 | 707 | ||
704 | DPRINTK(""); | 708 | /* Allocate Xenstore page */ |
709 | page = get_zeroed_page(GFP_KERNEL); | ||
710 | if (!page) | ||
711 | goto out_err; | ||
705 | 712 | ||
706 | err = -ENODEV; | 713 | xen_store_mfn = xen_start_info->store_mfn = |
707 | if (!xen_domain()) | 714 | pfn_to_mfn(virt_to_phys((void *)page) >> |
708 | return err; | 715 | PAGE_SHIFT); |
709 | 716 | ||
710 | /* | 717 | /* Next allocate a local port which xenstored can bind to */ |
711 | * Domain0 doesn't have a store_evtchn or store_mfn yet. | 718 | alloc_unbound.dom = DOMID_SELF; |
712 | */ | 719 | alloc_unbound.remote_dom = DOMID_SELF; |
713 | if (xen_initial_domain()) { | ||
714 | struct evtchn_alloc_unbound alloc_unbound; | ||
715 | 720 | ||
716 | /* Allocate Xenstore page */ | 721 | err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, |
717 | page = get_zeroed_page(GFP_KERNEL); | 722 | &alloc_unbound); |
718 | if (!page) | 723 | if (err == -ENOSYS) |
719 | goto out_error; | 724 | goto out_err; |
720 | 725 | ||
721 | xen_store_mfn = xen_start_info->store_mfn = | 726 | BUG_ON(err); |
722 | pfn_to_mfn(virt_to_phys((void *)page) >> | 727 | xen_store_evtchn = xen_start_info->store_evtchn = |
723 | PAGE_SHIFT); | 728 | alloc_unbound.port; |
724 | 729 | ||
725 | /* Next allocate a local port which xenstored can bind to */ | 730 | return 0; |
726 | alloc_unbound.dom = DOMID_SELF; | ||
727 | alloc_unbound.remote_dom = DOMID_SELF; | ||
728 | 731 | ||
729 | err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, | 732 | out_err: |
730 | &alloc_unbound); | 733 | if (page != 0) |
731 | if (err == -ENOSYS) | 734 | free_page(page); |
732 | goto out_error; | 735 | return err; |
736 | } | ||
733 | 737 | ||
734 | BUG_ON(err); | 738 | static int __init xenbus_init(void) |
735 | xen_store_evtchn = xen_start_info->store_evtchn = | 739 | { |
736 | alloc_unbound.port; | 740 | int err = 0; |
737 | 741 | ||
738 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 742 | if (!xen_domain()) |
743 | return -ENODEV; | ||
744 | |||
745 | if (xen_hvm_domain()) { | ||
746 | uint64_t v = 0; | ||
747 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); | ||
748 | if (err) | ||
749 | goto out_error; | ||
750 | xen_store_evtchn = (int)v; | ||
751 | err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); | ||
752 | if (err) | ||
753 | goto out_error; | ||
754 | xen_store_mfn = (unsigned long)v; | ||
755 | xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE); | ||
739 | } else { | 756 | } else { |
740 | if (xen_hvm_domain()) { | 757 | xen_store_evtchn = xen_start_info->store_evtchn; |
741 | uint64_t v = 0; | 758 | xen_store_mfn = xen_start_info->store_mfn; |
742 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); | 759 | if (xen_store_evtchn) |
743 | if (err) | 760 | xenstored_ready = 1; |
744 | goto out_error; | 761 | else { |
745 | xen_store_evtchn = (int)v; | 762 | err = xenstored_local_init(); |
746 | err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); | ||
747 | if (err) | 763 | if (err) |
748 | goto out_error; | 764 | goto out_error; |
749 | xen_store_mfn = (unsigned long)v; | ||
750 | xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE); | ||
751 | } else { | ||
752 | xen_store_evtchn = xen_start_info->store_evtchn; | ||
753 | xen_store_mfn = xen_start_info->store_mfn; | ||
754 | xen_store_interface = mfn_to_virt(xen_store_mfn); | ||
755 | xenstored_ready = 1; | ||
756 | } | 765 | } |
766 | xen_store_interface = mfn_to_virt(xen_store_mfn); | ||
757 | } | 767 | } |
758 | 768 | ||
759 | /* Initialize the interface to xenstore. */ | 769 | /* Initialize the interface to xenstore. */ |
@@ -772,12 +782,7 @@ static int __init xenbus_init(void) | |||
772 | proc_mkdir("xen", NULL); | 782 | proc_mkdir("xen", NULL); |
773 | #endif | 783 | #endif |
774 | 784 | ||
775 | return 0; | 785 | out_error: |
776 | |||
777 | out_error: | ||
778 | if (page != 0) | ||
779 | free_page(page); | ||
780 | |||
781 | return err; | 786 | return err; |
782 | } | 787 | } |
783 | 788 | ||