diff options
Diffstat (limited to 'arch/x86/kernel/vsmp_64.c')
| -rw-r--r-- | arch/x86/kernel/vsmp_64.c | 44 | 
1 files changed, 40 insertions, 4 deletions
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 8eeb55a551b..992f890283e 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -16,6 +16,7 @@  #include <linux/pci_ids.h>  #include <linux/pci_regs.h>  #include <linux/smp.h> +#include <linux/irq.h>  #include <asm/apic.h>  #include <asm/pci-direct.h> @@ -95,6 +96,18 @@ static void __init set_vsmp_pv_ops(void)  	ctl = readl(address + 4);  	printk(KERN_INFO "vSMP CTL: capabilities:0x%08x  control:0x%08x\n",  	       cap, ctl); + +	/* If possible, let the vSMP foundation route the interrupt optimally */ +#ifdef CONFIG_SMP +	if (cap & ctl & BIT(8)) { +		ctl &= ~BIT(8); +#ifdef CONFIG_PROC_FS +		/* Don't let users change irq affinity via procfs */ +		no_irq_affinity = 1; +#endif +	} +#endif +  	if (cap & ctl & (1 << 4)) {  		/* Setup irq ops and turn on vSMP  IRQ fastpath handling */  		pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); @@ -102,12 +115,11 @@ static void __init set_vsmp_pv_ops(void)  		pv_irq_ops.save_fl  = PV_CALLEE_SAVE(vsmp_save_fl);  		pv_irq_ops.restore_fl  = PV_CALLEE_SAVE(vsmp_restore_fl);  		pv_init_ops.patch = vsmp_patch; -  		ctl &= ~(1 << 4); -		writel(ctl, address + 4); -		ctl = readl(address + 4); -		printk(KERN_INFO "vSMP CTL: control set to:0x%08x\n", ctl);  	} +	writel(ctl, address + 4); +	ctl = readl(address + 4); +	pr_info("vSMP CTL: control set to:0x%08x\n", ctl);  	early_iounmap(address, 8);  } @@ -187,12 +199,36 @@ static void __init vsmp_cap_cpus(void)  #endif  } +static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) +{ +	return hard_smp_processor_id() >> index_msb; +} + +/* + * In vSMP, all cpus should be capable of handling interrupts, regardless of + * the APIC used. + */ +static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask, +					  const struct cpumask *mask) +{ +	cpumask_setall(retmask); +} + +static void vsmp_apic_post_init(void) +{ +	/* need to update phys_pkg_id */ +	apic->phys_pkg_id = apicid_phys_pkg_id; +	apic->vector_allocation_domain = fill_vector_allocation_domain; +} +  void __init vsmp_init(void)  {  	detect_vsmp_box();  	if (!is_vsmp_box())  		return; +	x86_platform.apic_post_init = vsmp_apic_post_init; +  	vsmp_cap_cpus();  	set_vsmp_pv_ops();  |