aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/srat.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-09-22 08:16:49 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-09-22 08:16:49 +0100
commitbac2000063ba239d33b631f6edda48cc6b57425b (patch)
tree1202e917a4903bdf3975f4ba018c8a4233c80973 /xen/arch/x86/srat.c
parent615588563e99a23aaf37037c3fee0c413b051f4d (diff)
downloadxen-bac2000063ba239d33b631f6edda48cc6b57425b.tar.gz
xen-bac2000063ba239d33b631f6edda48cc6b57425b.tar.bz2
xen-bac2000063ba239d33b631f6edda48cc6b57425b.zip
x86-64: reduce range spanned by 1:1 mapping and frame table indexes
Introduces a virtual space conserving transformation on the MFN thus far used to index 1:1 mapping and frame table, removing the largest range of contiguous bits (below the most significant one) which are zero for all valid MFNs from the MFN representation, to be used to index into those arrays, thereby cutting the virtual range these tables must cover approximately by half with each bit removed. Since this should account for hotpluggable memory (in order to not requiring a re-write when that gets supported), the determination of which bits are candidates for removal must not be based on the E820 information, but instead has to use the SRAT. That in turn requires a change to the ordering of steps done during early boot. Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/arch/x86/srat.c')
-rw-r--r--xen/arch/x86/srat.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c
index 1a6d2a10fb..9ee4f3106e 100644
--- a/xen/arch/x86/srat.c
+++ b/xen/arch/x86/srat.c
@@ -286,6 +286,70 @@ static void unparse_node(int node)
void __init acpi_numa_arch_fixup(void) {}
+#ifdef __x86_64__
+
+static u64 __initdata srat_region_mask;
+
+static u64 __init fill_mask(u64 mask)
+{
+ while (mask & (mask + 1))
+ mask |= mask + 1;
+ return mask;
+}
+
+static int __init srat_parse_region(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_srat_mem_affinity *ma;
+
+ if (!header)
+ return -EINVAL;
+
+ ma = container_of(header, struct acpi_srat_mem_affinity, header);
+
+ if (!ma->length ||
+ !(ma->flags & ACPI_SRAT_MEM_ENABLED) ||
+ (ma->flags & ACPI_SRAT_MEM_NON_VOLATILE))
+ return 0;
+
+ if (numa_off)
+ printk(KERN_INFO "SRAT: %013"PRIx64"-%013"PRIx64"\n",
+ ma->base_address, ma->base_address + ma->length - 1);
+
+ srat_region_mask |= ma->base_address |
+ fill_mask(ma->base_address ^
+ (ma->base_address + ma->length - 1));
+
+ return 0;
+}
+
+void __init srat_parse_regions(u64 addr)
+{
+ u64 mask;
+ unsigned int i;
+
+ if (acpi_disabled || acpi_numa < 0 ||
+ acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat))
+ return;
+
+ srat_region_mask = fill_mask(addr - 1);
+ acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, srat_parse_region, 0);
+
+ for (mask = srat_region_mask, i = 0; mask && i < e820.nr_map; i++) {
+ if (e820.map[i].type != E820_RAM)
+ continue;
+
+ if (~mask &
+ fill_mask(e820.map[i].addr ^
+ (e820.map[i].addr + e820.map[i].size - 1)))
+ mask = 0;
+ }
+
+ pfn_pdx_hole_setup(mask >> PAGE_SHIFT);
+}
+
+#endif /* __x86_64__ */
+
/* Use the information discovered above to actually set up the nodes. */
int __init acpi_scan_nodes(u64 start, u64 end)
{