[Midnightbsd-cvs] src [9534] trunk: Ryzen workaround #1

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Aug 19 20:04:01 EDT 2017


Revision: 9534
          http://svnweb.midnightbsd.org/src/?rev=9534
Author:   laffer1
Date:     2017-08-19 20:04:01 -0400 (Sat, 19 Aug 2017)
Log Message:
-----------
Ryzen workaround #1

Modified Paths:
--------------
    trunk/UPDATING
    trunk/sys/amd64/amd64/elf_machdep.c
    trunk/sys/amd64/amd64/initcpu.c
    trunk/sys/amd64/include/md_var.h

Modified: trunk/UPDATING
===================================================================
--- trunk/UPDATING	2017-08-20 00:03:22 UTC (rev 9533)
+++ trunk/UPDATING	2017-08-20 00:04:01 UTC (rev 9534)
@@ -3,6 +3,9 @@
 20170819:
 	Heimdal KDC-REP service name validation vulerability patched.
 
+        Introduce a partial fix for AMD Ryzen issues. On Ryzen, move
+        the lower shared page by one.
+
 20170326:
 	sudo removed from base. Use doas(1) or install sudo from mports
 

Modified: trunk/sys/amd64/amd64/elf_machdep.c
===================================================================
--- trunk/sys/amd64/amd64/elf_machdep.c	2017-08-20 00:03:22 UTC (rev 9533)
+++ trunk/sys/amd64/amd64/elf_machdep.c	2017-08-20 00:04:01 UTC (rev 9534)
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD: src/sys/amd64/amd64/elf_machdep.c,v 1.5 2012/11/23 06:02:40 laffer1 Exp $");
+__MBSDID("$MidnightBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -85,6 +85,25 @@
 };
 INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
 
+void
+amd64_lower_shared_page(struct sysentvec *sv)
+{
+	if (hw_lower_amd64_sharedpage != 0) {
+		sv->sv_maxuser -= PAGE_SIZE;
+		sv->sv_shared_page_base -= PAGE_SIZE;
+		sv->sv_usrstack -= PAGE_SIZE;
+		sv->sv_psstrings -= PAGE_SIZE;
+	}
+}
+
+/*
+ * Do this fixup before INIT_SYSENTVEC (SI_ORDER_ANY) because the latter
+ * uses the value of sv_shared_page_base.
+ */
+SYSINIT(elf64_sysvec_fixup, SI_SUB_EXEC, SI_ORDER_FIRST,
+	(sysinit_cfunc_t) amd64_lower_shared_page,
+	&elf64_freebsd_sysvec);
+
 static Elf64_Brandinfo freebsd_brand_info = {
 	.brand		= ELFOSABI_FREEBSD,
 	.machine	= EM_X86_64,

Modified: trunk/sys/amd64/amd64/initcpu.c
===================================================================
--- trunk/sys/amd64/amd64/initcpu.c	2017-08-20 00:03:22 UTC (rev 9533)
+++ trunk/sys/amd64/amd64/initcpu.c	2017-08-20 00:04:01 UTC (rev 9534)
@@ -48,6 +48,11 @@
 static int	hw_instruction_sse;
 SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
     &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU");
+static int	lower_sharedpage_init;
+int		hw_lower_amd64_sharedpage;
+SYSCTL_INT(_hw, OID_AUTO, lower_amd64_sharedpage, CTLFLAG_RDTUN,
+    &hw_lower_amd64_sharedpage, 0,
+   "Lower sharedpage to work around Ryzen issue with executing code near the top of user memory");
 /*
  * -1: automatic (default)
  *  0: keep enable CLFLUSH
@@ -106,6 +111,28 @@
 			wrmsr(0xc0011029, rdmsr(0xc0011029) | 1);
 		break;
 	}
+
+	/*
+	 * Work around a problem on Ryzen that is triggered by executing
+	 * code near the top of user memory, in our case the signal
+	 * trampoline code in the shared page on amd64.
+	 *
+	 * This function is executed once for the BSP before tunables take
+	 * effect so the value determined here can be overridden by the
+	 * tunable.  This function is then executed again for each AP and
+	 * also on resume.  Set a flag the first time so that value set by
+	 * the tunable is not overwritten.
+	 *
+	 * The stepping and/or microcode versions should be checked after
+	 * this issue is fixed by AMD so that we don't use this mode if not
+	 * needed.
+	 */
+	if (lower_sharedpage_init == 0) {
+		lower_sharedpage_init = 1;
+		if (CPUID_TO_FAMILY(cpu_id) == 0x17) {
+			hw_lower_amd64_sharedpage = 1;
+		}
+	}
 }
 
 /*

Modified: trunk/sys/amd64/include/md_var.h
===================================================================
--- trunk/sys/amd64/include/md_var.h	2017-08-20 00:03:22 UTC (rev 9533)
+++ trunk/sys/amd64/include/md_var.h	2017-08-20 00:04:01 UTC (rev 9534)
@@ -63,6 +63,7 @@
 extern	char	sigcode[];
 extern	int	szsigcode;
 extern	uint64_t *vm_page_dump;
+extern	int	hw_lower_amd64_sharedpage;
 extern	int	vm_page_dump_size;
 extern	int	workaround_erratum383;
 extern	int	_udatasel;
@@ -76,6 +77,7 @@
 typedef void alias_for_inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
 struct	pcb;
 struct	savefpu;
+struct	sysentvec;
 struct	thread;
 struct	reg;
 struct	fpreg;
@@ -118,5 +120,6 @@
 struct savefpu *get_pcb_user_save_pcb(struct pcb *pcb);
 struct pcb *get_pcb_td(struct thread *td);
 void	amd64_db_resume_dbreg(void);
+void	amd64_lower_shared_page(struct sysentvec *);
 
 #endif /* !_MACHINE_MD_VAR_H_ */



More information about the Midnightbsd-cvs mailing list