diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2015-05-06 10:13:31 -0400 |
---|---|---|
committer | David Vrabel <david.vrabel@citrix.com> | 2015-05-28 07:23:11 -0400 |
commit | 5882bfef6327093bff63569be19795170ff71e5f (patch) | |
tree | 11aa43fab514a95bc53dd063f3f02bee90d7ff17 /arch/arm/xen | |
parent | 81e863c3a28e69fd60411bde9f779b0f8ad0212a (diff) |
arm,arm64/xen: move Xen initialization earlier
Currently, Xen is initialized/discovered in an initcall. This doesn't
allow us to support earlyprintk or choosing the preferred console when
running on Xen.
The current function xen_guest_init is now split in 2 parts:
- xen_early_init: Check if there is a Xen node in the device tree
and setup domain type
- xen_guest_init: Retrieve the information from the device node and
initialize Xen (grant table, shared page...)
The former is called in setup_arch, while the latter is an initcall.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm/xen')
-rw-r--r-- | arch/arm/xen/enlighten.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 6fbdc8fa4a19..3463a9e1ff65 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -53,6 +53,8 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug); | |||
53 | 53 | ||
54 | static __read_mostly unsigned int xen_events_irq; | 54 | static __read_mostly unsigned int xen_events_irq; |
55 | 55 | ||
56 | static __initdata struct device_node *xen_node; | ||
57 | |||
56 | int xen_remap_domain_mfn_array(struct vm_area_struct *vma, | 58 | int xen_remap_domain_mfn_array(struct vm_area_struct *vma, |
57 | unsigned long addr, | 59 | unsigned long addr, |
58 | xen_pfn_t *mfn, int nr, | 60 | xen_pfn_t *mfn, int nr, |
@@ -150,42 +152,28 @@ static irqreturn_t xen_arm_callback(int irq, void *arg) | |||
150 | * documentation of the Xen Device Tree format. | 152 | * documentation of the Xen Device Tree format. |
151 | */ | 153 | */ |
152 | #define GRANT_TABLE_PHYSADDR 0 | 154 | #define GRANT_TABLE_PHYSADDR 0 |
153 | static int __init xen_guest_init(void) | 155 | void __init xen_early_init(void) |
154 | { | 156 | { |
155 | struct xen_add_to_physmap xatp; | ||
156 | static struct shared_info *shared_info_page = 0; | ||
157 | struct device_node *node; | ||
158 | int len; | 157 | int len; |
159 | const char *s = NULL; | 158 | const char *s = NULL; |
160 | const char *version = NULL; | 159 | const char *version = NULL; |
161 | const char *xen_prefix = "xen,xen-"; | 160 | const char *xen_prefix = "xen,xen-"; |
162 | struct resource res; | ||
163 | phys_addr_t grant_frames; | ||
164 | 161 | ||
165 | node = of_find_compatible_node(NULL, NULL, "xen,xen"); | 162 | xen_node = of_find_compatible_node(NULL, NULL, "xen,xen"); |
166 | if (!node) { | 163 | if (!xen_node) { |
167 | pr_debug("No Xen support\n"); | 164 | pr_debug("No Xen support\n"); |
168 | return 0; | 165 | return; |
169 | } | 166 | } |
170 | s = of_get_property(node, "compatible", &len); | 167 | s = of_get_property(xen_node, "compatible", &len); |
171 | if (strlen(xen_prefix) + 3 < len && | 168 | if (strlen(xen_prefix) + 3 < len && |
172 | !strncmp(xen_prefix, s, strlen(xen_prefix))) | 169 | !strncmp(xen_prefix, s, strlen(xen_prefix))) |
173 | version = s + strlen(xen_prefix); | 170 | version = s + strlen(xen_prefix); |
174 | if (version == NULL) { | 171 | if (version == NULL) { |
175 | pr_debug("Xen version not found\n"); | 172 | pr_debug("Xen version not found\n"); |
176 | return 0; | 173 | return; |
177 | } | ||
178 | if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res)) | ||
179 | return 0; | ||
180 | grant_frames = res.start; | ||
181 | xen_events_irq = irq_of_parse_and_map(node, 0); | ||
182 | if (!xen_events_irq) { | ||
183 | pr_debug("Xen event channel interrupt not found\n"); | ||
184 | return -ENODEV; | ||
185 | } | 174 | } |
186 | 175 | ||
187 | pr_info("Xen %s support found, events_irq=%d gnttab_frame=%pa\n", | 176 | pr_info("Xen %s support found\n", version); |
188 | version, xen_events_irq, &grant_frames); | ||
189 | 177 | ||
190 | xen_domain_type = XEN_HVM_DOMAIN; | 178 | xen_domain_type = XEN_HVM_DOMAIN; |
191 | 179 | ||
@@ -195,10 +183,32 @@ static int __init xen_guest_init(void) | |||
195 | xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED; | 183 | xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED; |
196 | else | 184 | else |
197 | xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED); | 185 | xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED); |
186 | } | ||
187 | |||
188 | static int __init xen_guest_init(void) | ||
189 | { | ||
190 | struct xen_add_to_physmap xatp; | ||
191 | struct shared_info *shared_info_page = NULL; | ||
192 | struct resource res; | ||
193 | phys_addr_t grant_frames; | ||
194 | |||
195 | if (!xen_domain()) | ||
196 | return 0; | ||
197 | |||
198 | if (of_address_to_resource(xen_node, GRANT_TABLE_PHYSADDR, &res)) { | ||
199 | pr_err("Xen grant table base address not found\n"); | ||
200 | return -ENODEV; | ||
201 | } | ||
202 | grant_frames = res.start; | ||
203 | |||
204 | xen_events_irq = irq_of_parse_and_map(xen_node, 0); | ||
205 | if (!xen_events_irq) { | ||
206 | pr_err("Xen event channel interrupt not found\n"); | ||
207 | return -ENODEV; | ||
208 | } | ||
209 | |||
210 | shared_info_page = (struct shared_info *)get_zeroed_page(GFP_KERNEL); | ||
198 | 211 | ||
199 | if (!shared_info_page) | ||
200 | shared_info_page = (struct shared_info *) | ||
201 | get_zeroed_page(GFP_KERNEL); | ||
202 | if (!shared_info_page) { | 212 | if (!shared_info_page) { |
203 | pr_err("not enough memory\n"); | 213 | pr_err("not enough memory\n"); |
204 | return -ENOMEM; | 214 | return -ENOMEM; |