Date: Sat, 7 Apr 2018 17:06:13 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332182 - in head/sys: amd64/amd64 vm Message-ID: <201804071706.w37H6Da7084181@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sat Apr 7 17:06:13 2018 New Revision: 332182 URL: https://svnweb.freebsd.org/changeset/base/332182 Log: Handle Skylake-X errata SKZ63. SKZ63 Processor May Hang When Executing Code In an HLE Transaction Region Problem: Under certain conditions, if the processor acquires an HLE (Hardware Lock Elision) lock via the XACQUIRE instruction in the Host Physical Address range between 40000000H and 403FFFFFH, it may hang with an internal timeout error (MCACOD 0400H) logged into IA32_MCi_STATUS. Move the pages from the range into the blacklist. Add a tunable to not waste 4M if local DoS is not the issue. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D15001 Modified: head/sys/amd64/amd64/pmap.c head/sys/vm/vm_page.c head/sys/vm/vm_page.h Modified: head/sys/amd64/amd64/pmap.c ============================================================================== --- head/sys/amd64/amd64/pmap.c Sat Apr 7 15:40:00 2018 (r332181) +++ head/sys/amd64/amd64/pmap.c Sat Apr 7 17:06:13 2018 (r332182) @@ -1290,7 +1290,35 @@ pmap_init(void) struct pmap_preinit_mapping *ppim; vm_page_t mpte; vm_size_t s; - int error, i, pv_npg; + int error, i, pv_npg, ret, skz63; + + /* Detect bare-metal Skylake Server and Skylake-X. */ + if (vm_guest == VM_GUEST_NO && cpu_vendor_id == CPU_VENDOR_INTEL && + CPUID_TO_FAMILY(cpu_id) == 0x6 && CPUID_TO_MODEL(cpu_id) == 0x55) { + /* + * Skylake-X errata SKZ63. Processor May Hang When + * Executing Code In an HLE Transaction Region between + * 40000000H and 403FFFFFH. + * + * Mark the pages in the range as preallocated. It + * seems to be impossible to distinguish between + * Skylake Server and Skylake X. + */ + skz63 = 1; + TUNABLE_INT_FETCH("hw.skz63_enable", &skz63); + if (skz63 != 0) { + if (bootverbose) + printf("SKZ63: skipping 4M RAM starting " + "at physical 1G\n"); + for (i = 0; i < atop(0x400000); i++) { + ret = vm_page_blacklist_add(0x40000000 + + ptoa(i), FALSE); + if (!ret && bootverbose) + printf("page at %#lx already used\n", + 0x40000000 + ptoa(i)); + } + } + } /* * Initialize the vm page array entries for the kernel pmap's Modified: head/sys/vm/vm_page.c ============================================================================== --- head/sys/vm/vm_page.c Sat Apr 7 15:40:00 2018 (r332181) +++ head/sys/vm/vm_page.c Sat Apr 7 17:06:13 2018 (r332182) @@ -341,6 +341,29 @@ vm_page_blacklist_next(char **list, char *end) return (0); } +bool +vm_page_blacklist_add(vm_paddr_t pa, bool verbose) +{ + struct vm_domain *vmd; + vm_page_t m; + int ret; + + m = vm_phys_paddr_to_vm_page(pa); + if (m == NULL) + return (true); /* page does not exist, no failure */ + + vmd = vm_pagequeue_domain(m); + vm_domain_free_lock(vmd); + ret = vm_phys_unfree_page(m); + vm_domain_free_unlock(vmd); + if (ret) { + TAILQ_INSERT_TAIL(&blacklist_head, m, listq); + if (verbose) + printf("Skipping page with pa 0x%jx\n", (uintmax_t)pa); + } + return (ret); +} + /* * vm_page_blacklist_check: * @@ -351,29 +374,14 @@ vm_page_blacklist_next(char **list, char *end) static void vm_page_blacklist_check(char *list, char *end) { - struct vm_domain *vmd; vm_paddr_t pa; - vm_page_t m; char *next; - int ret; next = list; while (next != NULL) { if ((pa = vm_page_blacklist_next(&next, end)) == 0) continue; - m = vm_phys_paddr_to_vm_page(pa); - if (m == NULL) - continue; - vmd = vm_pagequeue_domain(m); - vm_domain_free_lock(vmd); - ret = vm_phys_unfree_page(m); - vm_domain_free_unlock(vmd); - if (ret == TRUE) { - TAILQ_INSERT_TAIL(&blacklist_head, m, listq); - if (bootverbose) - printf("Skipping page with pa 0x%jx\n", - (uintmax_t)pa); - } + vm_page_blacklist_add(pa, bootverbose); } } Modified: head/sys/vm/vm_page.h ============================================================================== --- head/sys/vm/vm_page.h Sat Apr 7 15:40:00 2018 (r332181) +++ head/sys/vm/vm_page.h Sat Apr 7 17:06:13 2018 (r332182) @@ -476,6 +476,7 @@ vm_page_t vm_page_alloc_contig_domain(vm_object_t obje vm_memattr_t memattr); vm_page_t vm_page_alloc_freelist(int, int); vm_page_t vm_page_alloc_freelist_domain(int, int, int); +bool vm_page_blacklist_add(vm_paddr_t pa, bool verbose); void vm_page_change_lock(vm_page_t m, struct mtx **mtx); vm_page_t vm_page_grab (vm_object_t, vm_pindex_t, int); int vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804071706.w37H6Da7084181>