aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2015-01-07 02:31:34 -0500
committerThomas Gleixner <tglx@linutronix.de>2015-01-15 05:24:23 -0500
commit07806c50bddd2f0493f97584198733946952409c (patch)
tree6ea63d3bcba212a7bc3bc580c0a552eef0f67283 /arch/x86/kernel/apic
parent89356cf20ecb0b9975b1dad9ed605dd4c6e68bcd (diff)
x86/apic: Refine enable_IR_x2apic() and related functions
Refine enable_IR_x2apic() and related functions for better readability. [ tglx: Removed the XAPIC mode change and split it out into a seperate patch. Added comments. ] Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Cc: Tony Luck <tony.luck@intel.com> Cc: iommu@lists.linux-foundation.org Cc: H. Peter Anvin <hpa@linux.intel.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: David Rientjes <rientjes@google.com> Cc: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com> Cc: Jan Beulich <JBeulich@suse.com> Cc: Richard Weinberger <richard@nod.at> Cc: Oren Twaig <oren@scalemp.com> Link: http://lkml.kernel.org/r/1420615903-28253-8-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r--arch/x86/kernel/apic/apic.c92
1 files changed, 47 insertions, 45 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 11358df3bd08..fa77be8d0b17 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1573,7 +1573,7 @@ void enable_x2apic(void)
1573} 1573}
1574#endif /* CONFIG_X86_X2APIC */ 1574#endif /* CONFIG_X86_X2APIC */
1575 1575
1576int __init enable_IR(void) 1576static int __init try_to_enable_IR(void)
1577{ 1577{
1578#ifdef CONFIG_IRQ_REMAP 1578#ifdef CONFIG_IRQ_REMAP
1579 if (!irq_remapping_supported()) { 1579 if (!irq_remapping_supported()) {
@@ -1586,17 +1586,51 @@ int __init enable_IR(void)
1586 "io-apic setup\n"); 1586 "io-apic setup\n");
1587 return -1; 1587 return -1;
1588 } 1588 }
1589 1589#endif
1590 return irq_remapping_enable(); 1590 return irq_remapping_enable();
1591}
1592
1593static __init void try_to_enable_x2apic(int ir_stat)
1594{
1595#ifdef CONFIG_X86_X2APIC
1596 if (!x2apic_supported())
1597 return;
1598
1599 if (ir_stat < 0) {
1600 /* IR is required if there is APIC ID > 255 even when running
1601 * under KVM
1602 */
1603 if (max_physical_apicid > 255 ||
1604 !hypervisor_x2apic_available()) {
1605 pr_info("IRQ remapping doesn't support X2APIC mode, disable x2apic.\n");
1606 if (x2apic_preenabled)
1607 disable_x2apic();
1608 return;
1609 }
1610
1611 /*
1612 * without IR all CPUs can be addressed by IOAPIC/MSI
1613 * only in physical mode
1614 */
1615 x2apic_force_phys();
1616
1617 } else if (ir_stat == IRQ_REMAP_XAPIC_MODE) {
1618 pr_info("x2apic not enabled, IRQ remapping is in xapic mode\n");
1619 return;
1620 }
1621
1622 if (!x2apic_mode) {
1623 x2apic_mode = 1;
1624 enable_x2apic();
1625 pr_info("Enabled x2apic\n");
1626 }
1591#endif 1627#endif
1592 return -1;
1593} 1628}
1594 1629
1595void __init enable_IR_x2apic(void) 1630void __init enable_IR_x2apic(void)
1596{ 1631{
1597 unsigned long flags; 1632 unsigned long flags;
1598 int ret; 1633 int ret, ir_stat;
1599 int hardware_init_ret;
1600 1634
1601 if (!IS_ENABLED(CONFIG_X86_X2APIC)) { 1635 if (!IS_ENABLED(CONFIG_X86_X2APIC)) {
1602 u64 msr; 1636 u64 msr;
@@ -1606,8 +1640,8 @@ void __init enable_IR_x2apic(void)
1606 panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n"); 1640 panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n");
1607 } 1641 }
1608 1642
1609 hardware_init_ret = irq_remapping_prepare(); 1643 ir_stat = irq_remapping_prepare();
1610 if (hardware_init_ret && !x2apic_supported()) 1644 if (ir_stat < 0 && !x2apic_supported())
1611 return; 1645 return;
1612 1646
1613 ret = save_ioapic_entries(); 1647 ret = save_ioapic_entries();
@@ -1622,45 +1656,13 @@ void __init enable_IR_x2apic(void)
1622 1656
1623 if (x2apic_preenabled && nox2apic) 1657 if (x2apic_preenabled && nox2apic)
1624 disable_x2apic(); 1658 disable_x2apic();
1659 /* If irq_remapping_prepare() succeded, try to enable it */
1660 if (ir_stat >= 0)
1661 ir_stat = try_to_enable_IR();
1662 /* ir_stat contains the remap mode or an error code */
1663 try_to_enable_x2apic(ir_stat);
1625 1664
1626 if (hardware_init_ret) 1665 if (ir_stat < 0)
1627 ret = -1;
1628 else
1629 ret = enable_IR();
1630
1631 if (!x2apic_supported())
1632 goto skip_x2apic;
1633
1634 if (ret < 0) {
1635 /* IR is required if there is APIC ID > 255 even when running
1636 * under KVM
1637 */
1638 if (max_physical_apicid > 255 ||
1639 !hypervisor_x2apic_available()) {
1640 if (x2apic_preenabled)
1641 disable_x2apic();
1642 goto skip_x2apic;
1643 }
1644 /*
1645 * without IR all CPUs can be addressed by IOAPIC/MSI
1646 * only in physical mode
1647 */
1648 x2apic_force_phys();
1649 }
1650
1651 if (ret == IRQ_REMAP_XAPIC_MODE) {
1652 pr_info("x2apic not enabled, IRQ remapping is in xapic mode\n");
1653 goto skip_x2apic;
1654 }
1655
1656 if (x2apic_supported() && !x2apic_mode) {
1657 x2apic_mode = 1;
1658 enable_x2apic();
1659 pr_info("Enabled x2apic\n");
1660 }
1661
1662skip_x2apic:
1663 if (ret < 0) /* IR enabling failed */
1664 restore_ioapic_entries(); 1666 restore_ioapic_entries();
1665 legacy_pic->restore_mask(); 1667 legacy_pic->restore_mask();
1666 local_irq_restore(flags); 1668 local_irq_restore(flags);