lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1318370975-10817-1-git-send-email-jacob.shin@amd.com>
Date:	Tue, 11 Oct 2011 17:09:35 -0500
From:	Jacob Shin <jacob.shin@....com>
To:	Thomas Gleixner <tglx@...utronix.de>,
	Ingo Molnar <mingo@...hat.com>,
	"H. Peter Anvin" <hpa@...or.com>
CC:	<linux-kernel@...r.kernel.org>, <x86@...nel.org>,
	Yinghai Lu <yinghai@...nel.org>,
	Jacob Shin <jacob.shin@....com>
Subject: [PATCH 1/1] x86, e820: Remove direct mapping of reserved space for HT hole around 1TB

The entire HT hole and also the unused address range before that hole
need to be excluded from direct mapping. Otherwise speculative
accesses to that reserved region can happen which cause machine
checks.

Cc: stable@...nel.org   # > 2.6.32
Signed-off-by: Jacob Shin <jacob.shin@....com>
---
 arch/x86/include/asm/e820.h           |    1 +
 arch/x86/include/asm/hypertransport.h |    7 +++++
 arch/x86/include/asm/processor.h      |   16 +++++++++++++
 arch/x86/kernel/cpu/amd.c             |   40 +++++++++++++++++++++++++++++++++
 arch/x86/kernel/e820.c                |    6 +++++
 arch/x86/kernel/setup.c               |    8 +++++-
 6 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 908b969..7e4d417 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -117,6 +117,7 @@ static inline void early_memtest(unsigned long start, unsigned long end)
 
 extern unsigned long e820_end_of_ram_pfn(void);
 extern unsigned long e820_end_of_low_ram_pfn(void);
+extern unsigned long e820_end_of_ram_under_ht_pfn(void);
 extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
 
 void memblock_x86_fill(void);
diff --git a/arch/x86/include/asm/hypertransport.h b/arch/x86/include/asm/hypertransport.h
index 334b1a8..c1d5a08 100644
--- a/arch/x86/include/asm/hypertransport.h
+++ b/arch/x86/include/asm/hypertransport.h
@@ -42,4 +42,11 @@
 #define HT_IRQ_HIGH_DEST_ID(v)						\
 	((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
 
+/*
+ * Memory Region Reserved for HyperTransport
+ */
+
+#define HT_RESERVED_MEM_START           0xfd00000000ULL
+#define HT_RESERVED_MEM_END             0x10000000000ULL
+
 #endif /* _ASM_X86_HYPERTRANSPORT_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 0d1171c..73ae54f 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -970,6 +970,22 @@ extern int set_tsc_mode(unsigned int val);
 
 extern int amd_get_nb_id(int cpu);
 
+#if defined(CONFIG_CPU_SUP_AMD) && defined(CONFIG_X86_64)
+extern int amd_with_ram_above_ht(void);
+extern unsigned long amd_init_high_memory_mapping(void);
+#else
+static inline int amd_with_ram_above_ht(void)
+{
+	return 0;
+}
+
+static inline unsigned long amd_init_high_memory_mapping(void)
+{
+	BUG();
+	return 0;
+}
+#endif
+
 struct aperfmperf {
 	u64 aperf, mperf;
 };
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index b13ed39..a57b010 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -7,6 +7,7 @@
 #include <asm/apic.h>
 #include <asm/cpu.h>
 #include <asm/pci-direct.h>
+#include <asm/hypertransport.h>
 
 #ifdef CONFIG_X86_64
 # include <asm/numa_64.h>
@@ -755,3 +756,42 @@ bool cpu_has_amd_erratum(const int *erratum)
 }
 
 EXPORT_SYMBOL_GPL(cpu_has_amd_erratum);
+
+#if defined(CONFIG_CPU_SUP_AMD) && defined(CONFIG_X86_64)
+int __cpuinit amd_with_ram_above_ht(void)
+{
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+	    max_pfn << PAGE_SHIFT >= HT_RESERVED_MEM_START)
+		return 1;
+
+	return 0;
+}
+
+/*
+ * On AMD systems, memory region 0xfd_0000_0000 ~ 0xff_ffff_ffff is reserved by
+ * HyperTransport and cannot be used by the processor. On systems with more than
+ * 1TB of RAM, BIOS may take memory immediately below the HT region and "hoist"
+ * it up above the HT region, leaving a hole.
+ */
+unsigned long __cpuinit amd_init_high_memory_mapping(void)
+{
+	unsigned long ret;
+
+	/* remove HT region from the e820 map, if it's declared as usable */
+	e820_remove_range(HT_RESERVED_MEM_START,
+			  HT_RESERVED_MEM_END - HT_RESERVED_MEM_START,
+			  E820_RAM, 1);
+	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+
+	/* direct mapping of high memory under HT */
+	ret = init_memory_mapping(1UL << 32,
+		e820_end_of_ram_under_ht_pfn() << PAGE_SHIFT);
+
+	/* skip HT region, direct mapping of high memory above HT */
+	if (max_pfn << PAGE_SHIFT >= HT_RESERVED_MEM_END)
+		ret = init_memory_mapping(HT_RESERVED_MEM_END,
+					  max_pfn << PAGE_SHIFT);
+
+	return ret;
+}
+#endif
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 3e2ef84..c0ba036 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -22,6 +22,7 @@
 #include <asm/e820.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
+#include <asm/hypertransport.h>
 
 /*
  * The e820 map is the map that gets modified e.g. with command line parameters
@@ -826,6 +827,11 @@ unsigned long __init e820_end_of_low_ram_pfn(void)
 	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
 }
 
+unsigned long __init e820_end_of_ram_under_ht_pfn(void)
+{
+	return e820_end_pfn(HT_RESERVED_MEM_START >> PAGE_SHIFT, E820_RAM);
+}
+
 static void early_panic(char *msg)
 {
 	early_printk(msg);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index afaf384..84d0968 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -937,8 +937,12 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_X86_64
 	if (max_pfn > max_low_pfn) {
-		max_pfn_mapped = init_memory_mapping(1UL<<32,
-						     max_pfn<<PAGE_SHIFT);
+		if (amd_with_ram_above_ht())
+			max_pfn_mapped = amd_init_high_memory_mapping();
+		else
+			max_pfn_mapped = init_memory_mapping(1UL << 32,
+				max_pfn << PAGE_SHIFT);
+
 		/* can we preseve max_low_pfn ?*/
 		max_low_pfn = max_pfn;
 	}
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ