diff options
Diffstat (limited to 'arch/arm/xen/enlighten.c')
| -rw-r--r-- | arch/arm/xen/enlighten.c | 87 | 
1 files changed, 59 insertions, 28 deletions
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 83e4f959ee4..1e632430570 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -23,6 +23,7 @@  #include <linux/of_address.h>  #include <linux/cpuidle.h>  #include <linux/cpufreq.h> +#include <linux/cpu.h>  #include <linux/mm.h> @@ -96,7 +97,7 @@ static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,  	struct remap_data *info = data;  	struct page *page = info->pages[info->index++];  	unsigned long pfn = page_to_pfn(page); -	pte_t pte = pfn_pte(pfn, info->prot); +	pte_t pte = pte_mkspecial(pfn_pte(pfn, info->prot));  	if (map_foreign_page(pfn, info->fgmfn, info->domid))  		return -EFAULT; @@ -154,7 +155,7 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,  }  EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); -static void __init xen_percpu_init(void *unused) +static void xen_percpu_init(void)  {  	struct vcpu_register_vcpu_info info;  	struct vcpu_info *vcpup; @@ -193,6 +194,31 @@ static void xen_power_off(void)  		BUG();  } +static int xen_cpu_notification(struct notifier_block *self, +				unsigned long action, +				void *hcpu) +{ +	switch (action) { +	case CPU_STARTING: +		xen_percpu_init(); +		break; +	default: +		break; +	} + +	return NOTIFY_OK; +} + +static struct notifier_block xen_cpu_notifier = { +	.notifier_call = xen_cpu_notification, +}; + +static irqreturn_t xen_arm_callback(int irq, void *arg) +{ +	xen_hvm_evtchn_do_upcall(); +	return IRQ_HANDLED; +} +  /*   * see Documentation/devicetree/bindings/arm/xen.txt for the   * documentation of the Xen Device Tree format. @@ -208,6 +234,7 @@ static int __init xen_guest_init(void)  	const char *version = NULL;  	const char *xen_prefix = "xen,xen-";  	struct resource res; +	phys_addr_t grant_frames;  	node = of_find_compatible_node(NULL, NULL, "xen,xen");  	if (!node) { @@ -224,10 +251,14 @@ static int __init xen_guest_init(void)  	}  	if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res))  		return 0; -	xen_hvm_resume_frames = res.start >> PAGE_SHIFT; +	grant_frames = res.start;  	xen_events_irq = irq_of_parse_and_map(node, 0); -	pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n", -			version, xen_events_irq, xen_hvm_resume_frames); +	pr_info("Xen %s support found, events_irq=%d gnttab_frame=%pa\n", +			version, xen_events_irq, &grant_frames); + +	if (xen_events_irq < 0) +		return -ENODEV; +  	xen_domain_type = XEN_HVM_DOMAIN;  	xen_setup_features(); @@ -265,6 +296,10 @@ static int __init xen_guest_init(void)  	if (xen_vcpu_info == NULL)  		return -ENOMEM; +	if (gnttab_setup_auto_xlat_frames(grant_frames)) { +		free_percpu(xen_vcpu_info); +		return -ENOMEM; +	}  	gnttab_init();  	if (!xen_initial_domain())  		xenbus_probe(NULL); @@ -276,9 +311,21 @@ static int __init xen_guest_init(void)  	disable_cpuidle();  	disable_cpufreq(); +	xen_init_IRQ(); + +	if (request_percpu_irq(xen_events_irq, xen_arm_callback, +			       "events", &xen_vcpu)) { +		pr_err("Error request IRQ %d\n", xen_events_irq); +		return -EINVAL; +	} + +	xen_percpu_init(); + +	register_cpu_notifier(&xen_cpu_notifier); +  	return 0;  } -core_initcall(xen_guest_init); +early_initcall(xen_guest_init);  static int __init xen_pm_init(void)  { @@ -292,30 +339,13 @@ static int __init xen_pm_init(void)  }  late_initcall(xen_pm_init); -static irqreturn_t xen_arm_callback(int irq, void *arg) -{ -	xen_hvm_evtchn_do_upcall(); -	return IRQ_HANDLED; -} -static int __init xen_init_events(void) -{ -	if (!xen_domain() || xen_events_irq < 0) -		return -ENODEV; - -	xen_init_IRQ(); - -	if (request_percpu_irq(xen_events_irq, xen_arm_callback, -			"events", &xen_vcpu)) { -		pr_err("Error requesting IRQ %d\n", xen_events_irq); -		return -EINVAL; -	} - -	on_each_cpu(xen_percpu_init, NULL, 0); +/* empty stubs */ +void xen_arch_pre_suspend(void) { } +void xen_arch_post_suspend(int suspend_cancelled) { } +void xen_timer_resume(void) { } +void xen_arch_resume(void) { } -	return 0; -} -postcore_initcall(xen_init_events);  /* In the hypervisor.S file. */  EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); @@ -328,4 +358,5 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);  EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);  EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);  EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op); +EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);  EXPORT_SYMBOL_GPL(privcmd_call);  | 
