Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07806c50 authored by Jiang Liu's avatar Jiang Liu Committed by Thomas Gleixner
Browse files

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: default avatarJiang 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: default avatarThomas Gleixner <tglx@linutronix.de>
parent 89356cf2
Loading
Loading
Loading
Loading
+47 −45
Original line number Diff line number Diff line
@@ -1573,7 +1573,7 @@ void enable_x2apic(void)
}
#endif /* CONFIG_X86_X2APIC */

int __init enable_IR(void)
static int __init try_to_enable_IR(void)
{
#ifdef CONFIG_IRQ_REMAP
	if (!irq_remapping_supported()) {
@@ -1586,17 +1586,51 @@ int __init enable_IR(void)
			"io-apic setup\n");
		return -1;
	}

#endif
	return irq_remapping_enable();
}

static __init void try_to_enable_x2apic(int ir_stat)
{
#ifdef CONFIG_X86_X2APIC
	if (!x2apic_supported())
		return;

	if (ir_stat < 0) {
		/* IR is required if there is APIC ID > 255 even when running
		 * under KVM
		 */
		if (max_physical_apicid > 255 ||
		    !hypervisor_x2apic_available()) {
			pr_info("IRQ remapping doesn't support X2APIC mode, disable x2apic.\n");
			if (x2apic_preenabled)
				disable_x2apic();
			return;
		}

		/*
		 * without IR all CPUs can be addressed by IOAPIC/MSI
		 * only in physical mode
		 */
		x2apic_force_phys();

	} else if (ir_stat == IRQ_REMAP_XAPIC_MODE) {
		pr_info("x2apic not enabled, IRQ remapping is in xapic mode\n");
		return;
	}

	if (!x2apic_mode) {
		x2apic_mode = 1;
		enable_x2apic();
		pr_info("Enabled x2apic\n");
	}
#endif
	return -1;
}

void __init enable_IR_x2apic(void)
{
	unsigned long flags;
	int ret;
	int hardware_init_ret;
	int ret, ir_stat;

	if (!IS_ENABLED(CONFIG_X86_X2APIC)) {
		u64 msr;
@@ -1606,8 +1640,8 @@ void __init enable_IR_x2apic(void)
			panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n");
	}

	hardware_init_ret = irq_remapping_prepare();
	if (hardware_init_ret && !x2apic_supported())
	ir_stat = irq_remapping_prepare();
	if (ir_stat < 0 && !x2apic_supported())
		return;

	ret = save_ioapic_entries();
@@ -1622,45 +1656,13 @@ void __init enable_IR_x2apic(void)

	if (x2apic_preenabled && nox2apic)
		disable_x2apic();
	/* If irq_remapping_prepare() succeded, try to enable it */
	if (ir_stat >= 0)
		ir_stat = try_to_enable_IR();
	/* ir_stat contains the remap mode or an error code */
	try_to_enable_x2apic(ir_stat);

	if (hardware_init_ret)
		ret = -1;
	else
		ret = enable_IR();

	if (!x2apic_supported())
		goto skip_x2apic;

	if (ret < 0) {
		/* IR is required if there is APIC ID > 255 even when running
		 * under KVM
		 */
		if (max_physical_apicid > 255 ||
		    !hypervisor_x2apic_available()) {
			if (x2apic_preenabled)
				disable_x2apic();
			goto skip_x2apic;
		}
		/*
		 * without IR all CPUs can be addressed by IOAPIC/MSI
		 * only in physical mode
		 */
		x2apic_force_phys();
	}

	if (ret == IRQ_REMAP_XAPIC_MODE) {
		pr_info("x2apic not enabled, IRQ remapping is in xapic mode\n");
		goto skip_x2apic;
	}

	if (x2apic_supported() && !x2apic_mode) {
		x2apic_mode = 1;
		enable_x2apic();
		pr_info("Enabled x2apic\n");
	}

skip_x2apic:
	if (ret < 0) /* IR enabling failed */
	if (ir_stat < 0)
		restore_ioapic_entries();
	legacy_pic->restore_mask();
	local_irq_restore(flags);