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
| ||
|
Date: Thu, 19 Nov 2020 12:59:01 -0500 From: Andrea Arcangeli <aarcange@...hat.com> To: Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...nel.org> Cc: Andi Kleen <ak@...ux.intel.com>, Rafael Aquini <aquini@...hat.com>, Waiman Long <longman@...hat.com>, linux-kernel@...r.kernel.org Subject: [PATCH 0/1] x86: restore the write back cache of reserved RAM in iounmap() Hello everyone, We identified some PCD set on the direct mapping causing hardly reproducible performance issues and this patch fixes the ultimate root cause. The caller for now has been tweaked to avoid triggering this case (now that we know about it) however if the observations on the proposed fix aren't correct, it'd be great if we could still do some other change to ioremap/iounmap and perhaps the other memtype APIs, to be sure those PCD/PWT leftovers won't happen again a few years from now in another place. For example one more complex alternative would be to use the page_mapcount of reserved pages (currently unused) to do proper refcounting on the overlapping ioremap so you can resync the kernel direct mapping to write back only at the very last iounmap. Or a much simpler alternative that would remain fully neutral for overlapping ioremaps, would be to overwrite all page_count of reserved RAM in a way that if they're ever freed later it'll trigger a crash during __free_pages. == // SPDX-License-Identifier: GPL-2.0-only /* * ioremap.c * * Copyright (C) 2020 Red Hat, Inc. * * Reproducer for bug io iounmap. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/mm.h> #include <asm/io.h> #define NR_PAGES 512 #define REPRODUCE static struct page *pages[NR_PAGES]; static void __iomem *map[NR_PAGES]; int init_module(void) { int i; for (i = 0; i < NR_PAGES; i++) { pages[i] = alloc_pages(GFP_KERNEL|__GFP_NOWARN, MAX_ORDER-1); if (!pages[i]) break; __SetPageReserved(pages[i]); #ifdef REPRODUCE map[i] = ioremap(page_to_phys(pages[i]), 1L<<(MAX_ORDER-1)); WARN_ON_ONCE(!map[i]); #endif } return 0; } void cleanup_module(void) { int i; for (i = 0; i < NR_PAGES; i++) { if (map[i]) iounmap(map[i]); if (!pages[i]) break; __ClearPageReserved(pages[i]); __free_pages(pages[i], MAX_ORDER-1); } } MODULE_LICENSE("GPL"); == Andrea Arcangeli (1): x86: restore the write back cache of reserved RAM in iounmap() arch/x86/mm/ioremap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
Powered by blists - more mailing lists