This is to properly handle SRAT rev 2 extended proximity domain values. At ones, it is a first step to eliminate the redundant definitions of ACPI provided table structures (Linux eliminated all of the duplicates from include/linux/acpi.h in 2.6.21). Portions based on a Linux patch from Kurt Garloff and Alexey Starikovskiy . IA64 build tested only. Signed-off-by: Jan Beulich --- 2009-05-19.orig/xen/arch/ia64/linux-xen/acpi.c 2009-05-20 14:40:35.000000000 +0200 +++ 2009-05-19/xen/arch/ia64/linux-xen/acpi.c 2009-05-20 14:54:26.000000000 +0200 @@ -55,6 +55,7 @@ #include #ifdef XEN #include +#include extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES]; #endif @@ -484,22 +485,28 @@ static u32 __devinitdata pxm_flag[PXM_FL static struct acpi_table_slit __initdata *slit_table; cpumask_t early_cpu_possible_map = CPU_MASK_NONE; -static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa) +static int __init +get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa) { int pxm; pxm = pa->proximity_domain_lo; - if (ia64_platform_is("sn2")) + if (srat_rev >= 2) { + pxm += pa->proximity_domain_hi[0] << 8; + pxm += pa->proximity_domain_hi[1] << 16; + pxm += pa->proximity_domain_hi[2] << 24; + } else if (ia64_platform_is("sn2")) pxm += pa->proximity_domain_hi[0] << 8; return pxm; } -static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma) +static int __init +get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma) { int pxm; pxm = ma->proximity_domain; - if (!ia64_platform_is("sn2")) + if (!ia64_platform_is("sn2") && srat_rev < 2) pxm &= 0xff; return pxm; @@ -525,17 +532,9 @@ void __init acpi_numa_slit_init(struct a slit_table = slit; } -#ifndef XEN void __init acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) -#else -void __init -acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa__) -#endif { -#ifdef XEN - struct acpi_srat_cpu_affinity *pa = (struct acpi_srat_cpu_affinity *)pa__; -#endif int pxm; if (!(pa->flags & ACPI_SRAT_CPU_ENABLED)) @@ -554,18 +553,9 @@ acpi_numa_processor_affinity_init (struc srat_num_cpus++; } -#ifndef XEN void __init acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) -#else -void __init -acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma__) -#endif { -#ifdef XEN - struct acpi_srat_mem_affinity *ma = - (struct acpi_srat_mem_affinity *)ma__; -#endif unsigned long paddr, size; int pxm; struct node_memblk_s *p, *q, *pend; --- 2009-05-19.orig/xen/arch/x86/srat.c 2009-05-20 14:40:35.000000000 +0200 +++ 2009-05-19/xen/arch/x86/srat.c 2009-05-19 18:03:28.000000000 +0200 @@ -132,17 +132,23 @@ void __init acpi_numa_slit_init(struct a /* Callback for Proximity Domain -> LAPIC mapping */ void __init -acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) +acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) { int pxm, node; if (srat_disabled()) return; - if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) { bad_srat(); + if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) { + bad_srat(); return; } - if (pa->flags.enabled == 0) + if (!(pa->flags & ACPI_SRAT_CPU_ENABLED)) return; - pxm = pa->proximity_domain; + pxm = pa->proximity_domain_lo; + if (srat_rev >= 2) { + pxm |= pa->proximity_domain_hi[0] << 8; + pxm |= pa->proximity_domain_hi[1] << 16; + pxm |= pa->proximity_domain_hi[2] << 24; + } node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm); @@ -157,7 +163,7 @@ acpi_numa_processor_affinity_init(struct /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init -acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) +acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) { struct node *nd; u64 start, end; @@ -166,15 +172,17 @@ acpi_numa_memory_affinity_init(struct ac if (srat_disabled()) return; - if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) { + if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) { bad_srat(); return; } - if (ma->flags.enabled == 0) + if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) return; - start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); - end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); + start = ma->base_address; + end = start + ma->length; pxm = ma->proximity_domain; + if (srat_rev < 2) + pxm &= 0xff; node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains.\n"); @@ -182,7 +190,7 @@ acpi_numa_memory_affinity_init(struct ac return; } /* It is fine to add this area to the nodes data it will be used later*/ - if (ma->flags.hot_pluggable == 1) + if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) printk(KERN_INFO "SRAT: hot plug zone found %"PRIx64" - %"PRIx64" \n", start, end); i = conflicting_nodes(start, end); --- 2009-05-19.orig/xen/drivers/acpi/numa.c 2009-05-20 14:40:35.000000000 +0200 +++ 2009-05-19/xen/drivers/acpi/numa.c 2009-05-19 18:06:33.000000000 +0200 @@ -35,6 +35,8 @@ #define _COMPONENT ACPI_NUMA ACPI_MODULE_NAME("numa") +int __initdata srat_rev; + void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) { @@ -48,14 +50,21 @@ void __init acpi_table_print_srat_entry( case ACPI_SRAT_PROCESSOR_AFFINITY: #ifdef ACPI_DEBUG_OUTPUT { - struct acpi_table_processor_affinity *p = - (struct acpi_table_processor_affinity *)header; + struct acpi_srat_cpu_affinity *p = + container_of(header, struct acpi_srat_cpu_affinity, header); + u32 proximity_domain = p->proximity_domain_lo; + + if (srat_rev >= 2) { + proximity_domain |= p->proximity_domain_hi[0] << 8; + proximity_domain |= p->proximity_domain_hi[1] << 16; + proximity_domain |= p->proximity_domain_hi[2] << 24; + } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", - p->apic_id, p->lsapic_eid, - p->proximity_domain, - p->flags. - enabled ? "enabled" : "disabled")); + p->apic_id, p->local_sapic_eid, + proximity_domain, + p->flags & ACPI_SRAT_CPU_ENABLED + ? "enabled" : "disabled")); } #endif /* ACPI_DEBUG_OUTPUT */ break; @@ -63,18 +72,20 @@ void __init acpi_table_print_srat_entry( case ACPI_SRAT_MEMORY_AFFINITY: #ifdef ACPI_DEBUG_OUTPUT { - struct acpi_table_memory_affinity *p = - (struct acpi_table_memory_affinity *)header; + struct acpi_srat_mem_affinity *p = + container_of(header, struct acpi_srat_mem_affinity, header); + u32 proximity_domain = p->proximity_domain; + + if (srat_rev < 2) + proximity_domain &= 0xff; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n", - p->base_addr_hi, p->base_addr_lo, - p->length_hi, p->length_lo, - p->memory_type, p->proximity_domain, - p->flags. - enabled ? "enabled" : "disabled", - p->flags. - hot_pluggable ? " hot-pluggable" : - "")); + "SRAT Memory (0x%016"PRIx64" length 0x%016"PRIx64" type 0x%x) in proximity domain %d %s%s\n", + p->base_address, p->length, + p->memory_type, proximity_domain, + p->flags & ACPI_SRAT_MEM_ENABLED + ? "enabled" : "disabled", + p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE + ? " hot-pluggable" : "")); } #endif /* ACPI_DEBUG_OUTPUT */ break; @@ -98,9 +109,9 @@ static int __init acpi_parse_processor_affinity(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_processor_affinity *processor_affinity; + struct acpi_srat_cpu_affinity *processor_affinity + = container_of(header, struct acpi_srat_cpu_affinity, header); - processor_affinity = (struct acpi_table_processor_affinity *)header; if (!processor_affinity) return -EINVAL; @@ -116,9 +127,9 @@ static int __init acpi_parse_memory_affinity(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_memory_affinity *memory_affinity; + struct acpi_srat_mem_affinity *memory_affinity + = container_of(header, struct acpi_srat_mem_affinity, header); - memory_affinity = (struct acpi_table_memory_affinity *)header; if (!memory_affinity) return -EINVAL; @@ -132,6 +143,11 @@ acpi_parse_memory_affinity(struct acpi_s static int __init acpi_parse_srat(struct acpi_table_header *table) { + if (!table) + return -EINVAL; + + srat_rev = table->revision; + return 0; } --- 2009-05-19.orig/xen/include/asm-ia64/linux-xen/asm/numa.h 2009-05-20 14:40:35.000000000 +0200 +++ 2009-05-19/xen/include/asm-ia64/linux-xen/asm/numa.h 2009-05-19 17:50:24.000000000 +0200 @@ -25,6 +25,8 @@ #include +extern int srat_rev; + extern u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned; #ifndef XEN extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; --- 2009-05-19.orig/xen/include/asm-x86/numa.h 2009-05-20 14:40:35.000000000 +0200 +++ 2009-05-19/xen/include/asm-x86/numa.h 2009-05-19 17:50:58.000000000 +0200 @@ -5,6 +5,8 @@ #define NODES_SHIFT 6 +extern int srat_rev; + extern unsigned char cpu_to_node[]; extern cpumask_t node_to_cpumask[]; --- 2009-05-19.orig/xen/include/xen/acpi.h 2009-05-20 14:40:35.000000000 +0200 +++ 2009-05-19/xen/include/xen/acpi.h 2009-05-19 17:55:35.000000000 +0200 @@ -176,35 +176,6 @@ enum acpi_srat_entry_id { ACPI_SRAT_ENTRY_COUNT }; -struct acpi_table_processor_affinity { - struct acpi_subtable_header header; - u8 proximity_domain; - u8 apic_id; - struct { - u32 enabled:1; - u32 reserved:31; - } flags; - u8 lsapic_eid; - u8 reserved[7]; -} __attribute__ ((packed)); - -struct acpi_table_memory_affinity { - struct acpi_subtable_header header; - u8 proximity_domain; - u8 reserved1[5]; - u32 base_addr_lo; - u32 base_addr_hi; - u32 length_lo; - u32 length_hi; - u32 memory_type; /* See acpi_address_range_id */ - struct { - u32 enabled:1; - u32 hot_pluggable:1; - u32 reserved:30; - } flags; - u64 reserved2; -} __attribute__ ((packed)); - enum acpi_address_range_id { ACPI_ADDRESS_RANGE_MEMORY = 1, ACPI_ADDRESS_RANGE_RESERVED = 2, @@ -297,8 +268,8 @@ void acpi_table_print_srat_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_table_processor_affinity *pa); -void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma); +void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); +void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); void acpi_numa_arch_fixup(void); #ifdef CONFIG_ACPI_HOTPLUG_CPU