x86: Disabling x2apic if nox2apic is specified
PATCH 1/1 x86: Disabling x2apic if nox2apic is specified
for
1. x2apic preenabled system
2. first kernel have x2apic enabled, and try to boot second kernel with "nox2apic"
Signed-off-by Yinghai Lu <[email protected]>
--- arch/x86/include/asm/apic.h | 6 ++++ arch/x86/include/asm/apicdef.h | 1 arch/x86/kernel/acpi/boot.c | 10 ++++++- arch/x86/kernel/apic/apic.c | 54 ++++++++++++++++++++++++++++++++--------- arch/x86/mm/srat_64.c | 12 ++++++++- 5 files changed, 69 insertions(+), 14 deletions(-)
arch/x86/include/asm/apic.h +6 -0
@@ -176,6 +176,7 @@ static inline u64 native_x2apic_icr_read }extern int x2apic_phys; +extern int nox2apic;extern void check_x2apic (void );extern void enable_x2apic (void );extern void x2apic_icr_write (u32 low,u32 id);
@@ -186,6 +187,10 @@ static inline int x2apic_enabled(void)if (!cpu_has_x2apic)return 0 ; +/* avoid to read msr */ +if (nox2apic) +return 0 ; +rdmsr (MSR_IA32_APICBASE , msr, msr2);if (msr &X2APIC_ENABLE )return 1 ;
@@ -214,6 +219,7 @@ static inline void x2apic_force_phys(voi#define x2apic_preenabled 0#define x2apic_supported () 0 +#define nox2apic 1#endif extern void enable_IR_x2apic (void );
arch/x86/kernel/acpi/boot.c +8 -2
@@ -213,6 +213,8 @@ static int __init acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) {struct acpi_madt_local_x2apic *processor =NULL ; +int apic_id; +u8 enabled; processor = (struct acpi_madt_local_x2apic *)header;
@@ -221,6 +223,8 @@ acpi_parse_x2apic(struct acpi_subtable_hacpi_table_print_madt_entry (header); + apic_id = processor->local_apic_id; + enabled = processor->lapic_flags &ACPI_MADT_ENABLED ;#ifdef CONFIG_X86_X2APIC /* * We need to register disabled CPU as well to permit
@@ -229,8 +233,10 @@ acpi_parse_x2apic(struct acpi_subtable_h* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -acpi_register_lapic (processor->local_apic_id,/* APIC ID */ - processor->lapic_flags &ACPI_MADT_ENABLED ); +if (nox2apic && (apic_id >=0xff ) && enabled) + printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); +else +acpi_register_lapic (apic_id, enabled);#else printk(KERN_WARNING PREFIX "x2apic entry ignored\n");#endif
arch/x86/kernel/apic/apic.c +43 -11
112 lines not on this page · raw message
arch/x86/mm/srat_64.c +11 -1
@@ -125,6 +125,13 @@ acpi_numa_x2apic_affinity_init(struct acif ((pa->flags &ACPI_SRAT_CPU_ENABLED ) ==0 )return ; pxm = pa->proximity_domain; + apic_id = pa->apic_id; +#ifdef CONFIG_X86_X2APIC +if (nox2apic && (apic_id >=0xff )) { +printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , + pxm, apic_id); +return ; + } node =setup_node (pxm);if (node <0 ) {printk (KERN_ERR "SRAT: Too many proximity domains %x\n" , pxm);
@@ -132,12 +139,15 @@ acpi_numa_x2apic_affinity_init(struct ac return; } - apic_id = pa->apic_id; apicid_to_node[apic_id] = node;node_set (node, cpu_nodes_parsed); acpi_numa =1 ;printk (KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n" , pxm, apic_id, node); +#else +printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , + pxm, apic_id); +#endif }/* Callback for Proximity Domain -> LAPIC mapping */
arch/x86/include/asm/apicdef.h +1 -0
@@ -140,6 +140,7 @@#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))#define APIC_BASE_MSR 0x800 +#define XAPIC_ENABLE (1UL << 11)#define X2APIC_ENABLE (1UL << 10)#ifdef CONFIG_X86_32