x86, acpi: add support for x2apic ACPI extensions
Subsystems (4)
PATCH 1/1 x86, acpi: add support for x2apic ACPI extensions
All logical processors with APIC ID values of 255 and greater will have their APIC reported through Processor X2APIC structure (type-9 entry type) and all logical processors with APIC ID less than 255 will have their APIC reported through legacy Processor Local APIC (type-0 entry type) only. This is the same case even for NMI structure reporting.
The Processor X2APIC Affinity structure provides the association between the X2APIC ID of a logical processor and the proximity domain to which the logical processor belongs.
For OSPM, Procssor IDs outside the 0-254 range are to be declared as Device() objects in the ACPI namespace.
Add support for these x2apic ACPI extensions.
---
arch/x86/kernel/acpi/boot.c +53 -1
@@ -230,6 +230,35 @@ static void __cpuinit acpi_register_lapi }static int __init +acpi_parse_x2apic (struct acpi_subtable_header * header,const unsigned long end) +{ +struct acpi_madt_local_x2apic *processor =NULL ; + + processor = (struct acpi_madt_local_x2apic *)header; + +if (BAD_MADT_ENTRY (processor, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +#ifdef CONFIG_X86_X2APIC +/* +* We need to register disabled CPU as well to permit +* counting disabled CPUs. This allows us to size +* cpus_possible_map more accurately, to permit +* 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 ); +#else + printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); +#endif + +return 0 ; +} + +static int __init acpi_parse_lapic (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic *processor =NULL ;
@@ -289,6 +318,24 @@ acpi_parse_lapic_addr_ovr(struct acpi_su }static int __init +acpi_parse_x2apic_nmi (struct acpi_subtable_header * header,const unsigned long end) +{ +struct acpi_madt_local_x2apic_nmi *x2apic_nmi =NULL ; + + x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header; + +if (BAD_MADT_ENTRY (x2apic_nmi, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +if (x2apic_nmi->lint !=1 ) + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); + +return 0 ; +} + +static int __init acpi_parse_lapic_nmi (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic_nmi *lapic_nmi =NULL ;
@@ -816,9 +863,12 @@ static int __init acpi_parse_madt_lapic_ count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_SAPIC , acpi_parse_sapic,MAX_APICS ); -if (!count) +if (!count) { + count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_X2APIC , + acpi_parse_x2apic,MAX_APICS ); count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC , acpi_parse_lapic,MAX_APICS ); + }if (!count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n");/* TBD: Cleanup to allow fallback to MPS */
@@ -830,6 +880,8 @@ static int __init acpi_parse_madt_lapic_ } count = +acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_X2APIC_NMI , acpi_parse_x2apic_nmi,0 ); + count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC_NMI , acpi_parse_lapic_nmi,0 );if (count <0 ) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
arch/x86/mm/srat_64.c +30 -0
@@ -116,6 +116,36 @@ void __init acpi_numa_slit_init(struct areserve_early (phys, phys + length,"ACPI SLIT" ); } +/* Callback for Proximity Domain -> x2APIC mapping */ +void __init +acpi_numa_x2apic_affinity_init (struct acpi_srat_x2apic_cpu_affinity *pa) +{ +int pxm, node; +int apic_id; + +if (srat_disabled ()) +return ; +if (pa->header.length <sizeof (struct acpi_srat_x2apic_cpu_affinity )) { +bad_srat (); +return ; + } +if ((pa->flags &ACPI_SRAT_CPU_ENABLED ) ==0 ) +return ; + pxm = pa->proximity_domain; + node =setup_node (pxm); +if (node <0 ) { +printk (KERN_ERR "SRAT: Too many proximity domains %x\n" , pxm); +bad_srat (); +return ; + } + + apic_id = pa->apic_id; + apicid_to_node[apic_id] = node; + acpi_numa =1 ; +printk (KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n" , + pxm, apic_id, node); +} +/* Callback for Proximity Domain -> LAPIC mapping */ void __init acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa)
drivers/acpi/numa.c +44 -0
62 lines not on this page · raw message
include/linux/acpi.h +1 -0
@@ -97,6 +97,7 @@ void acpi_table_print_madt_entry (struct/* the following four functions are architecture-dependent */ void acpi_numa_slit_init (struct acpi_table_slit *slit);void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); +void acpi_numa_x2apic_affinity_init (struct acpi_srat_x2apic_cpu_affinity *pa);void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);void acpi_numa_arch_fixup (void );
drivers/acpi/processor_core.c +26 -0
@@ -427,6 +427,29 @@ static int map_lapic_id(struct acpi_subtreturn 0 ; } +static int map_x2apic_id (struct acpi_subtable_header *entry, +int device_declaration,u32 acpi_id,int *apic_id) +{ +struct acpi_madt_local_x2apic *apic = + (struct acpi_madt_local_x2apic *)entry; +u32 tmp = apic->local_apic_id; + +/* Only check enabled APICs*/ +if (!(apic->lapic_flags &ACPI_MADT_ENABLED )) +return 0 ; + +/* Device statement declaration type */ +if (device_declaration) { +if (apic->uid == acpi_id) + goto found; + } + +return 0 ; +found: + *apic_id = tmp; +return 1 ; +} +static int map_lsapic_id (struct acpi_subtable_header *entry,int device_declaration,u32 acpi_id,int *apic_id) {
@@ -476,6 +499,9 @@ static int map_madt_entry(int type, u32if (header->type ==ACPI_MADT_TYPE_LOCAL_APIC ) {if (map_lapic_id (header, acpi_id, &apic_id))break ; + }else if (header->type ==ACPI_MADT_TYPE_LOCAL_X2APIC ) { +if (map_x2apic_id (header, type, acpi_id, &apic_id)) +break ; }else if (header->type ==ACPI_MADT_TYPE_LOCAL_SAPIC ) {if (map_lsapic_id (header, type, acpi_id, &apic_id))break ;
drivers/acpi/tables.c +24 -0
@@ -62,6 +62,17 @@ void acpi_table_print_madt_entry(struct }break ; +case ACPI_MADT_TYPE_LOCAL_X2APIC : + { +struct acpi_madt_local_x2apic *p = + (struct acpi_madt_local_x2apic *)header; + printk(KERN_INFO PREFIX +"X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n" , + p->local_apic_id, p->uid, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + } +break ; +case ACPI_MADT_TYPE_IO_APIC : { struct acpi_madt_io_apic *p =
@@ -116,6 +127,19 @@ void acpi_table_print_madt_entry(struct }break ; +case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI : + { +struct acpi_madt_local_x2apic_nmi *p = + (struct acpi_madt_local_x2apic_nmi *)header; + printk(KERN_INFO PREFIX +"X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n" , + p->uid, + mps_inti_flags_polarity[p->inti_flags &ACPI_MADT_POLARITY_MASK ], + mps_inti_flags_trigger[(p->inti_flags &ACPI_MADT_TRIGGER_MASK ) >>2 ], + p->lint); + } +break ; +case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE : { struct acpi_madt_local_apic_override *p =
include/acpi/actbl1.h +3 -3
@@ -1016,9 +1016,9 @@ struct acpi_madt_interrupt_source {struct acpi_madt_local_x2apic {struct acpi_subtable_header header;u16 reserved;/* Reserved - must be zero */ -u32 local_apic_id;/* Processor X2_APIC ID */ +u32 local_apic_id;/* Processor x2APIC ID */ u32 lapic_flags; -u32 uid;/* Extended X2_APIC processor ID */ +u32 uid;/* ACPI processor UID */ };/* 10: Local X2APIC NMI (07/2008) */
@@ -1026,7 +1026,7 @@ struct acpi_madt_local_x2apic {struct acpi_madt_local_x2apic_nmi {struct acpi_subtable_header header;u16 inti_flags; -u32 uid;/* Processor X2_APIC ID */ +u32 uid;/* ACPI processor ID */ u8 lint;/* LINTn to which NMI is connected */ u8 reserved[3 ]; };
Len Brown
reviewerQuoted 84 lines · Suresh Siddha
All logical processors with APIC ID values of 255 and greater will have their APIC reported through Processor X2APIC structure (type-9 entry type) and all logical processors with APIC ID less than 255 will have their APIC reported through legacy Processor Local APIC (type-0 entry type) only. This is the same case even for NMI structure reporting.
The Processor X2APIC Affinity structure provides the association between the X2APIC ID of a logical processor and the proximity domain to which the logical processor belongs.
For OSPM, Procssor IDs outside the 0-254 range are to be declared as
Device()objects in the ACPI namespace.Add support for these x2apic ACPI extensions.
Signed-off-by Suresh Siddha <[email protected]>---
Index:
tip/arch/x86/kernel/acpi/boot.c
===================================================================arch/x86/kernel/acpi/boot.c +47
-0@@ -230,6 +230,35 @@ static void __cpuinit acpi_register_lapi }static int __init +acpi_parse_x2apic (struct acpi_subtable_header * header,const unsigned long end) +{ +struct acpi_madt_local_x2apic *processor =NULL ; + + processor = (struct acpi_madt_local_x2apic *)header; + +if (BAD_MADT_ENTRY (processor, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +#ifdef CONFIG_X86_X2APIC +/* +* We need to register disabled CPU as well to permit +* counting disabled CPUs. This allows us to size +* cpus_possible_map more accurately, to permit +* 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 ); +#else + printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); +#endif + +return 0 ; +} + +static int __init acpi_parse_lapic (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic *processor =NULL ;@@ -289,6 +318,24 @@ acpi_parse_lapic_addr_ovr(struct acpi_su }static int __init +acpi_parse_x2apic_nmi (struct acpi_subtable_header * header,const unsigned long end) +{ +struct acpi_madt_local_x2apic_nmi *x2apic_nmi =NULL ; + + x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header; + +if (BAD_MADT_ENTRY (x2apic_nmi, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +if (x2apic_nmi->lint !=1 ) + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); + +return 0 ; +} + +static int __init acpi_parse_lapic_nmi (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic_nmi *lapic_nmi =NULL ;
arch/x86/kernel/acpi/boot.c static int __init acpi_parse_madt_lapic_ · line 870
Quoted 9 lines
arch/x86/kernel/acpi/boot.c +3
-1@@ -816,9 +863,12 @@ static int __init acpi_parse_madt_lapic_ count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_SAPIC , acpi_parse_sapic,MAX_APICS ); -if (!count) +if (!count) { + count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_X2APIC , + acpi_parse_x2apic,MAX_APICS ); count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC , acpi_parse_lapic,MAX_APICS );
I'm not fond of the idiom
count = a();
count = b();
if (count)...
here and below.
if we really don't care if the x2apic parse routines return, and we always care what the traditional apic parse routines return, we should have
a();
count = b();
...
Ingo, this one is probably more ACPI than it is x86 -- shall I handle it?
thanks,
-Len
Quoted 110 lines · Len Brown
Quoted 84 lines · Suresh Siddha
All logical processors with APIC ID values of 255 and greater will have their APIC reported through Processor X2APIC structure (type-9 entry type) and all logical processors with APIC ID less than 255 will have their APIC reported through legacy Processor Local APIC (type-0 entry type) only. This is the same case even for NMI structure reporting.
The Processor X2APIC Affinity structure provides the association between the X2APIC ID of a logical processor and the proximity domain to which the logical processor belongs.
For OSPM, Procssor IDs outside the 0-254 range are to be declared as
Device()objects in the ACPI namespace.Add support for these x2apic ACPI extensions.
Signed-off-by Suresh Siddha <[email protected]>---
Index:
tip/arch/x86/kernel/acpi/boot.c
===================================================================arch/x86/kernel/acpi/boot.c +47
-0@@ -230,6 +230,35 @@ static void __cpuinit acpi_register_lapi }static int __init +acpi_parse_x2apic (struct acpi_subtable_header * header,const unsigned long end) +{ +struct acpi_madt_local_x2apic *processor =NULL ; + + processor = (struct acpi_madt_local_x2apic *)header; + +if (BAD_MADT_ENTRY (processor, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +#ifdef CONFIG_X86_X2APIC +/* +* We need to register disabled CPU as well to permit +* counting disabled CPUs. This allows us to size +* cpus_possible_map more accurately, to permit +* 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 ); +#else + printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); +#endif + +return 0 ; +} + +static int __init acpi_parse_lapic (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic *processor =NULL ;@@ -289,6 +318,24 @@ acpi_parse_lapic_addr_ovr(struct acpi_su }static int __init +acpi_parse_x2apic_nmi (struct acpi_subtable_header * header,const unsigned long end) +{ +struct acpi_madt_local_x2apic_nmi *x2apic_nmi =NULL ; + + x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header; + +if (BAD_MADT_ENTRY (x2apic_nmi, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +if (x2apic_nmi->lint !=1 ) + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); + +return 0 ; +} + +static int __init acpi_parse_lapic_nmi (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic_nmi *lapic_nmi =NULL ;arch/x86/kernel/acpi/boot.c static int __init acpi_parse_madt_lapic_ · line 870
Quoted 9 lines
arch/x86/kernel/acpi/boot.c +3
-1@@ -816,9 +863,12 @@ static int __init acpi_parse_madt_lapic_ count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_SAPIC , acpi_parse_sapic,MAX_APICS ); -if (!count) +if (!count) { + count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_X2APIC , + acpi_parse_x2apic,MAX_APICS ); count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC , acpi_parse_lapic,MAX_APICS );I'm not fond of the idiom
count =
a();
count =b();if (count)...
here and below.
if we really don't care if the x2apic parse routines return, and we always care what the traditional apic parse routines return, we should have
Quoted 5 lines
a();
count =b();
...Ingo, this one is probably more ACPI than it is x86 -- shall I handle it?
Sure, please do.
Ingo
Len Brown
reviewerscripts/checkpatch.pl
ERROR: "foo * bar" should be "foo *bar"
#34: FILE: arch/x86/kernel/acpi/boot.c:233:
+acpi_parse_x2apic(struct acpi_subtable_header * header, const unsigned long end)
WARNING: line over 80 characters
#70: FILE: arch/x86/kernel/acpi/boot.c:321:
+acpi_parse_x2apic_nmi(struct acpi_subtable_header * header, const unsigned long end)
ERROR: "foo * bar" should be "foo *bar"
#70: FILE: arch/x86/kernel/acpi/boot.c:321:
+acpi_parse_x2apic_nmi(struct acpi_subtable_header * header, const unsigned long end)
WARNING: line over 80 characters
#109: FILE: arch/x86/kernel/acpi/boot.c:883:
+ acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,acpi_parse_x2apic_nmi, 0);
WARNING: line over 80 characters
#169: FILE: drivers/acpi/numa.c:140:
+ "SRAT Processor
(x2apicid[0x%08x]) in proximity domain %d %s\n",
ERROR: spaces required around that '?' (ctx:VxE)
#172: FILE: drivers/acpi/numa.c:143:
+ (p->flags &ACPI_SRAT_CPU_ENABLED)?
^
ERROR: "foo * bar" should be "foo *bar"
#194: FILE: drivers/acpi/numa.c:207:
+acpi_parse_x2apic_affinity(struct acpi_subtable_header * header,
WARNING: usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc
#220: FILE: drivers/acpi/numa.c:287:
+ NR_CPUS);
WARNING: space prohibited between function name and open parenthesis '(' #232: FILE: include/linux/acpi.h:100:
+void acpi_numa_x2apic_affinity_init (struct acpi_srat_x2apic_cpu_affinity *pa);
WARNING: line over 80 characters
#295: FILE: drivers/acpi/tables.c:72:
+ (p->lapic_flags & ACPI_MADT_ENABLED) ?
"enabled" : "disabled");
WARNING: line over 80 characters
#313: FILE: drivers/acpi/tables.c:137:
+ mps_inti_flags_polarity[p->inti_flags &ACPI_MADT_POLARITY_MASK ],
ERROR: space prohibited before that close square bracket ']' #313: FILE: drivers/acpi/tables.c:137:
+ mps_inti_flags_polarity[p->inti_flags &ACPI_MADT_POLARITY_MASK ],
WARNING: line over 80 characters
#314: FILE: drivers/acpi/tables.c:138:
+ mps_inti_flags_trigger[(p->inti_flags &ACPI_MADT_TRIGGER_MASK) >> 2],
total: 5 errors, 8 warnings, 259 lines checked
--
Len Brown, Intel Open Source Technology Center
Quoted 1 line · Len Brown
scripts/checkpatch.pl
Len, existing acpi code needs fixes then, as I just did cut & paste :(
I am appending a new patch which fixes all the issues in the new code except for one noted below.
Review
Quoted 4 lines
WARNING: usage of
NR_CPUSis often wrong - consider usingcpu_possible(),num_possible_cpus(),for_each_possible_cpu(), etc
#220: FILE:drivers/acpi/numa.c:287:(quoted diff) +1
-0+ NR_CPUS);
This warning can be ignored, as the cpu_possible_map is not yet setup at this point.
thanks,
suresh
---
Subject: [patch] x86, acpi: add support for x2apic ACPI extensions
All logical processors with APIC ID values of 255 and greater will have their APIC reported through Processor X2APIC structure (type-9 entry type) and all logical processors with APIC ID less than 255 will have their APIC reported through legacy Processor Local APIC (type-0 entry type) only. This is the same case even for NMI structure reporting.
The Processor X2APIC Affinity structure provides the association between the X2APIC ID of a logical processor and the proximity domain to which the logical processor belongs.
For OSPM, Procssor IDs outside the 0-254 range must be declared as Device() objects in the ACPI namespace.
Add support for these x2apic ACPI extensions.
---
arch/x86/kernel/acpi/boot.c +59 -4
@@ -230,6 +230,35 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled) }static int __init +acpi_parse_x2apic (struct acpi_subtable_header *header,const unsigned long end) +{ +struct acpi_madt_local_x2apic *processor =NULL ; + + processor = (struct acpi_madt_local_x2apic *)header; + +if (BAD_MADT_ENTRY (processor, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +#ifdef CONFIG_X86_X2APIC +/* +* We need to register disabled CPU as well to permit +* counting disabled CPUs. This allows us to size +* cpus_possible_map more accurately, to permit +* 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 ); +#else + printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); +#endif + +return 0 ; +} + +static int __init acpi_parse_lapic (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic *processor =NULL ;
@@ -289,6 +318,25 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, }static int __init +acpi_parse_x2apic_nmi (struct acpi_subtable_header *header, +const unsigned long end) +{ +struct acpi_madt_local_x2apic_nmi *x2apic_nmi =NULL ; + + x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header; + +if (BAD_MADT_ENTRY (x2apic_nmi, end)) +return -EINVAL ; + +acpi_table_print_madt_entry (header); + +if (x2apic_nmi->lint !=1 ) + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); + +return 0 ; +} + +static int __init acpi_parse_lapic_nmi (struct acpi_subtable_header * header,const unsigned long end) {struct acpi_madt_local_apic_nmi *lapic_nmi =NULL ;
@@ -793,6 +841,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)static int __init acpi_parse_madt_lapic_entries (void ) {int count; +int x2count =0 ;if (!cpu_has_apic)return -ENODEV ;
@@ -816,22 +865,28 @@ static int __init acpi_parse_madt_lapic_entries(void) count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_SAPIC , acpi_parse_sapic,MAX_APICS ); -if (!count) +if (!count) { + x2count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_X2APIC , + acpi_parse_x2apic,MAX_APICS ); count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC , acpi_parse_lapic,MAX_APICS ); -if (!count) { + } +if (!count && !x2count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n");/* TBD: Cleanup to allow fallback to MPS */ return -ENODEV ; - }else if (count <0 ) { + }else if (count <0 || x2count <0 ) { printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");/* TBD: Cleanup to allow fallback to MPS */ return count; } + x2count = +acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_X2APIC_NMI , + acpi_parse_x2apic_nmi,0 ); count =acpi_table_parse_madt (ACPI_MADT_TYPE_LOCAL_APIC_NMI , acpi_parse_lapic_nmi,0 ); -if (count <0 ) { +if (count <0 || x2count <0 ) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");/* TBD: Cleanup to allow fallback to MPS */ return count;
arch/x86/mm/srat_64.c +30 -0
@@ -116,6 +116,36 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)reserve_early (phys, phys + length,"ACPI SLIT" ); } +/* Callback for Proximity Domain -> x2APIC mapping */ +void __init +acpi_numa_x2apic_affinity_init (struct acpi_srat_x2apic_cpu_affinity *pa) +{ +int pxm, node; +int apic_id; + +if (srat_disabled ()) +return ; +if (pa->header.length <sizeof (struct acpi_srat_x2apic_cpu_affinity )) { +bad_srat (); +return ; + } +if ((pa->flags &ACPI_SRAT_CPU_ENABLED ) ==0 ) +return ; + pxm = pa->proximity_domain; + node =setup_node (pxm); +if (node <0 ) { +printk (KERN_ERR "SRAT: Too many proximity domains %x\n" , pxm); +bad_srat (); +return ; + } + + apic_id = pa->apic_id; + apicid_to_node[apic_id] = node; + acpi_numa =1 ; +printk (KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n" , + pxm, apic_id, node); +} +/* Callback for Proximity Domain -> LAPIC mapping */ void __init acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa)
drivers/acpi/numa.c +45 -1
65 lines not on this page · raw message
drivers/acpi/processor_core.c +26 -0
@@ -427,6 +427,29 @@ static int map_lapic_id(struct acpi_subtable_header *entry,return 0 ; } +static int map_x2apic_id (struct acpi_subtable_header *entry, +int device_declaration,u32 acpi_id,int *apic_id) +{ +struct acpi_madt_local_x2apic *apic = + (struct acpi_madt_local_x2apic *)entry; +u32 tmp = apic->local_apic_id; + +/* Only check enabled APICs*/ +if (!(apic->lapic_flags &ACPI_MADT_ENABLED )) +return 0 ; + +/* Device statement declaration type */ +if (device_declaration) { +if (apic->uid == acpi_id) + goto found; + } + +return 0 ; +found: + *apic_id = tmp; +return 1 ; +} +static int map_lsapic_id (struct acpi_subtable_header *entry,int device_declaration,u32 acpi_id,int *apic_id) {
@@ -476,6 +499,9 @@ static int map_madt_entry(int type, u32 acpi_id)if (header->type ==ACPI_MADT_TYPE_LOCAL_APIC ) {if (map_lapic_id (header, acpi_id, &apic_id))break ; + }else if (header->type ==ACPI_MADT_TYPE_LOCAL_X2APIC ) { +if (map_x2apic_id (header, type, acpi_id, &apic_id)) +break ; }else if (header->type ==ACPI_MADT_TYPE_LOCAL_SAPIC ) {if (map_lsapic_id (header, type, acpi_id, &apic_id))break ;
drivers/acpi/tables.c +30 -0
@@ -62,6 +62,18 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) }break ; +case ACPI_MADT_TYPE_LOCAL_X2APIC : + { +struct acpi_madt_local_x2apic *p = + (struct acpi_madt_local_x2apic *)header; + printk(KERN_INFO PREFIX +"X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n" , + p->local_apic_id, p->uid, + (p->lapic_flags &ACPI_MADT_ENABLED ) ? + "enabled" : "disabled"); + } +break ; +case ACPI_MADT_TYPE_IO_APIC : { struct acpi_madt_io_apic *p =
@@ -116,6 +128,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) }break ; +case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI : + { +u16 polarity, trigger; +struct acpi_madt_local_x2apic_nmi *p = + (struct acpi_madt_local_x2apic_nmi *)header; + + polarity = p->inti_flags &ACPI_MADT_POLARITY_MASK ; + trigger = (p->inti_flags &ACPI_MADT_TRIGGER_MASK ) >>2 ; + + printk(KERN_INFO PREFIX +"X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n" , + p->uid, + mps_inti_flags_polarity[polarity], + mps_inti_flags_trigger[trigger], + p->lint); + } +break ; +case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE : { struct acpi_madt_local_apic_override *p =
include/linux/acpi.h +1 -0
@@ -97,6 +97,7 @@ void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);/* the following four functions are architecture-dependent */ void acpi_numa_slit_init (struct acpi_table_slit *slit);void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); +void acpi_numa_x2apic_affinity_init (struct acpi_srat_x2apic_cpu_affinity *pa);void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);void acpi_numa_arch_fixup (void );
Len Brown
reviewerQuoted 2 lines
I am appending a new patch which fixes all the issues in the new code except for one noted below.
old patch replaced with new, staged for 2.6.30.
thanks,
Len Brown, Intel Open Source Technology Center