|
@@ -30,6 +30,7 @@
|
|
|
#include <asm/dma.h>
|
|
|
#include <asm/amd_nb.h>
|
|
|
#include <asm/x86_init.h>
|
|
|
+#include <linux/crash_dump.h>
|
|
|
|
|
|
/*
|
|
|
* Using 512M as goal, in case kexec will load kernel_big
|
|
@@ -56,6 +57,33 @@ int fallback_aper_force __initdata;
|
|
|
|
|
|
int fix_aperture __initdata = 1;
|
|
|
|
|
|
+#ifdef CONFIG_PROC_VMCORE
|
|
|
+/*
|
|
|
+ * If the first kernel maps the aperture over e820 RAM, the kdump kernel will
|
|
|
+ * use the same range because it will remain configured in the northbridge.
|
|
|
+ * Trying to dump this area via /proc/vmcore may crash the machine, so exclude
|
|
|
+ * it from vmcore.
|
|
|
+ */
|
|
|
+static unsigned long aperture_pfn_start, aperture_page_count;
|
|
|
+
|
|
|
+static int gart_oldmem_pfn_is_ram(unsigned long pfn)
|
|
|
+{
|
|
|
+ return likely((pfn < aperture_pfn_start) ||
|
|
|
+ (pfn >= aperture_pfn_start + aperture_page_count));
|
|
|
+}
|
|
|
+
|
|
|
+static void exclude_from_vmcore(u64 aper_base, u32 aper_order)
|
|
|
+{
|
|
|
+ aperture_pfn_start = aper_base >> PAGE_SHIFT;
|
|
|
+ aperture_page_count = (32 * 1024 * 1024) << aper_order >> PAGE_SHIFT;
|
|
|
+ WARN_ON(register_oldmem_pfn_is_ram(&gart_oldmem_pfn_is_ram));
|
|
|
+}
|
|
|
+#else
|
|
|
+static void exclude_from_vmcore(u64 aper_base, u32 aper_order)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/* This code runs before the PCI subsystem is initialized, so just
|
|
|
access the northbridge directly. */
|
|
|
|
|
@@ -435,8 +463,16 @@ int __init gart_iommu_hole_init(void)
|
|
|
|
|
|
out:
|
|
|
if (!fix && !fallback_aper_force) {
|
|
|
- if (last_aper_base)
|
|
|
+ if (last_aper_base) {
|
|
|
+ /*
|
|
|
+ * If this is the kdump kernel, the first kernel
|
|
|
+ * may have allocated the range over its e820 RAM
|
|
|
+ * and fixed up the northbridge
|
|
|
+ */
|
|
|
+ exclude_from_vmcore(last_aper_base, last_aper_order);
|
|
|
+
|
|
|
return 1;
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -473,6 +509,14 @@ out:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * If this is the kdump kernel _and_ the first kernel did not
|
|
|
+ * configure the aperture in the northbridge, this range may
|
|
|
+ * overlap with the first kernel's memory. We can't access the
|
|
|
+ * range through vmcore even though it should be part of the dump.
|
|
|
+ */
|
|
|
+ exclude_from_vmcore(aper_alloc, aper_order);
|
|
|
+
|
|
|
/* Fix up the north bridges */
|
|
|
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
|
|
|
int bus, dev_base, dev_limit;
|