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: <1219822159-17245-1-git-send-email-yhlu.kernel@gmail.com>
Date:	Wed, 27 Aug 2008 00:29:19 -0700
From:	Yinghai Lu <yhlu.kernel@...il.com>
To:	Ingo Molnar <mingo@...e.hu>, Thomas Gleixner <tglx@...utronix.de>,
	"H. Peter Anvin" <hpa@...or.com>,
	Andrew Morton <akpm@...ux-foundation.org>
Cc:	linux-kernel@...r.kernel.org, Yinghai Lu <yhlu.kernel@...il.com>,
	Pavel Machek <pavel@...e.cz>,
	Benjamin Herrenschmidt <benh@...nel.crashing.org>,
	Jesse Barnes <jbarnes@...tuousgeek.org>
Subject: RFC [PATCH] x86/pci: reserve extra page to avoid error caused by P2P pref DMA reads

Diag guys, found one system when loading is high, will have gart wark error.
root cause is P2P bridge try to prefetch for several intel e1000 under
it. and that skb is near GART iommu area.

try to reserve page in the boundary at first.
last page near TOM2, and last page near MMIO
also gart first and last page.

need one better way for all arch support PCI and memory with a lot of holes etc.

Signed-off-by: Yinghai Lu <yhlu.kernel@...il.com>
Cc: Pavel Machek <pavel@...e.cz>
Cc: Benjamin Herrenschmidt <benh@...nel.crashing.org>
Cc: Jesse Barnes<jbarnes@...tuousgeek.org>

---
 arch/x86/kernel/pci-dma.c     |   28 ++++++++++++++++++++++++++++
 arch/x86/kernel/pci-gart_64.c |    6 ++++++
 2 files changed, 34 insertions(+)

Index: linux-2.6/arch/x86/kernel/pci-dma.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/pci-dma.c
+++ linux-2.6/arch/x86/kernel/pci-dma.c
@@ -72,12 +72,40 @@ static int __init parse_dma32_size_opt(c
 }
 early_param("dma32_size", parse_dma32_size_opt);
 
+static void __init reserve_last_page(unsigned long pfn)
+{
+	unsigned long phys;
+	void *ptr;
+
+	phys = (pfn - 1)<<PAGE_SHIFT;
+	ptr = __alloc_bootmem_nopanic(PAGE_SIZE, PAGE_SIZE, phys);
+
+	if (!ptr || virt_to_phys(ptr) != phys)
+		printk(KERN_WARNING "Can not hold last page near %lx for workaround P2P pref DMA reads!\n", phys);
+	else
+		printk(KERN_WARNING "Last page is reserved near %lx for workaround P2P pref DMA reads!\n", phys);
+}
 void __init dma32_reserve_bootmem(void)
 {
 	unsigned long size, align;
+
+	/*
+	 * try to reserve last page to workaround P2P bridge pref DMA reads
+	 * normally don't need to reserve the page near mmio,
+	 * because always has acpi etc sit there.
+	 * but some system has that acpi in the middle of ram below 4g
+	 * so just reserve it.
+	 */
+	if (max_low_pfn_mapped < max_pfn_mapped)
+		reserve_last_page(max_low_pfn_mapped);
+
+	/* less than 4G, don't need iommu */
 	if (max_pfn <= MAX_DMA32_PFN)
 		return;
 
+	/* try to reserve last page to workaround P2P bridge pref DMA reads */
+	reserve_last_page(max_pfn);
+
 	/*
 	 * check aperture_64.c allocate_aperture() for reason about
 	 * using 512M as goal
Index: linux-2.6/arch/x86/kernel/pci-gart_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/pci-gart_64.c
+++ linux-2.6/arch/x86/kernel/pci-gart_64.c
@@ -826,6 +826,9 @@ void __init gart_iommu_init(void)
 	 */
 	set_bit_string(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
 
+	/* reserve one page at tail, for P2P bridge pref DMA reads */
+	set_bit_string(iommu_gart_bitmap, iommu_pages - 1, 1);
+
 	agp_memory_reserved = iommu_size;
 	printk(KERN_INFO
 	       "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
@@ -870,6 +873,9 @@ void __init gart_iommu_init(void)
 	for (i = EMERGENCY_PAGES; i < iommu_pages; i++)
 		iommu_gatt_base[i] = gart_unmapped_entry;
 
+	/* we need set unmapped on head too, for P2P bridge pref DMA reads */
+	iommu_gatt_base[0] = gart_unmapped_entry;
+
 	flush_gart();
 	dma_ops = &gart_dma_ops;
 }
--
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