Module Name:    src
Committed By:   martin
Date:           Tue Mar  6 10:17:12 UTC 2018

Modified Files:
        src/sys/arch/amd64/conf [netbsd-8]: kern.ldscript kern.ldscript.Xen
        src/sys/arch/i386/conf [netbsd-8]: kern.ldscript kern.ldscript.Xen
        src/sys/arch/x86/include [netbsd-8]: cpufunc.h
        src/sys/arch/x86/x86 [netbsd-8]: patch.c

Log Message:
Pull up the following revisions, requested by maxv in ticket #603:

        amd64/conf/kern.ldscript      1.25 (patch)
        amd64/conf/kern.ldscript.Xen  1.14 (patch)
        i386/conf/kern.ldscript       1.21 (patch)
        i386/conf/kern.ldscript.Xen   1.15 (patch)
        x86/include/cpufunc.h         1.24 (patch)
        x86/x86/patch.c               1.25 (partial) 1.26 (partial)

Backport x86_hotpatch.


To generate a diff of this commit:
cvs rdiff -u -r1.22.6.1 -r1.22.6.2 src/sys/arch/amd64/conf/kern.ldscript
cvs rdiff -u -r1.13 -r1.13.8.1 src/sys/arch/amd64/conf/kern.ldscript.Xen
cvs rdiff -u -r1.19 -r1.19.10.1 src/sys/arch/i386/conf/kern.ldscript
cvs rdiff -u -r1.13.8.1 -r1.13.8.2 src/sys/arch/i386/conf/kern.ldscript.Xen
cvs rdiff -u -r1.22 -r1.22.8.1 src/sys/arch/x86/include/cpufunc.h
cvs rdiff -u -r1.22 -r1.22.22.1 src/sys/arch/x86/x86/patch.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/conf/kern.ldscript
diff -u src/sys/arch/amd64/conf/kern.ldscript:1.22.6.1 src/sys/arch/amd64/conf/kern.ldscript:1.22.6.2
--- src/sys/arch/amd64/conf/kern.ldscript:1.22.6.1	Wed Jun 21 17:41:50 2017
+++ src/sys/arch/amd64/conf/kern.ldscript	Tue Mar  6 10:17:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern.ldscript,v 1.22.6.1 2017/06/21 17:41:50 snj Exp $	*/
+/*	$NetBSD: kern.ldscript,v 1.22.6.2 2018/03/06 10:17:11 martin Exp $	*/
 
 #include "assym.h"
 
@@ -29,6 +29,14 @@ SECTIONS
 	. = ALIGN(__LARGE_PAGE_SIZE);
 
 	__rodata_start = . ;
+
+	.rodata.hotpatch :
+	{
+		__rodata_hotpatch_start = . ;
+		*(.rodata.hotpatch)
+		__rodata_hotpatch_end = . ;
+	}
+
 	.rodata :
 	{
 		*(.rodata)

Index: src/sys/arch/amd64/conf/kern.ldscript.Xen
diff -u src/sys/arch/amd64/conf/kern.ldscript.Xen:1.13 src/sys/arch/amd64/conf/kern.ldscript.Xen:1.13.8.1
--- src/sys/arch/amd64/conf/kern.ldscript.Xen:1.13	Tue Aug  2 14:03:34 2016
+++ src/sys/arch/amd64/conf/kern.ldscript.Xen	Tue Mar  6 10:17:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern.ldscript.Xen,v 1.13 2016/08/02 14:03:34 maxv Exp $	*/
+/*	$NetBSD: kern.ldscript.Xen,v 1.13.8.1 2018/03/06 10:17:11 martin Exp $	*/
 
 #include "assym.h"
 
@@ -19,6 +19,14 @@ SECTIONS
 	. = ALIGN(__PAGE_SIZE);
 
 	__rodata_start = . ;
+
+	.rodata.hotpatch :
+	{
+		__rodata_hotpatch_start = . ;
+		*(.rodata.hotpatch)
+		__rodata_hotpatch_end = . ;
+	}
+
 	.rodata :
 	{
 		*(.rodata)

Index: src/sys/arch/i386/conf/kern.ldscript
diff -u src/sys/arch/i386/conf/kern.ldscript:1.19 src/sys/arch/i386/conf/kern.ldscript:1.19.10.1
--- src/sys/arch/i386/conf/kern.ldscript:1.19	Sat May 14 08:19:42 2016
+++ src/sys/arch/i386/conf/kern.ldscript	Tue Mar  6 10:17:12 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern.ldscript,v 1.19 2016/05/14 08:19:42 maxv Exp $	*/
+/*	$NetBSD: kern.ldscript,v 1.19.10.1 2018/03/06 10:17:12 martin Exp $	*/
 
 #include "assym.h"
 
@@ -19,6 +19,14 @@ SECTIONS
 	. = ALIGN(__PAGE_SIZE);
 
 	__rodata_start = . ;
+
+	.rodata.hotpatch :
+	{
+		__rodata_hotpatch_start = . ;
+		*(.rodata.hotpatch)
+		__rodata_hotpatch_end = . ;
+	}
+
 	.rodata :
 	{
 		*(.rodata)

Index: src/sys/arch/i386/conf/kern.ldscript.Xen
diff -u src/sys/arch/i386/conf/kern.ldscript.Xen:1.13.8.1 src/sys/arch/i386/conf/kern.ldscript.Xen:1.13.8.2
--- src/sys/arch/i386/conf/kern.ldscript.Xen:1.13.8.1	Wed Jul  5 20:02:27 2017
+++ src/sys/arch/i386/conf/kern.ldscript.Xen	Tue Mar  6 10:17:12 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern.ldscript.Xen,v 1.13.8.1 2017/07/05 20:02:27 snj Exp $	*/
+/*	$NetBSD: kern.ldscript.Xen,v 1.13.8.2 2018/03/06 10:17:12 martin Exp $	*/
 
 #include "assym.h"
 
@@ -18,6 +18,14 @@ SECTIONS
 	. = ALIGN(__PAGE_SIZE);
 
 	__rodata_start = . ;
+
+	.rodata.hotpatch :
+	{
+		__rodata_hotpatch_start = . ;
+		*(.rodata.hotpatch)
+		__rodata_hotpatch_end = . ;
+	}
+
 	.rodata :
 	{
 		*(.rodata)

Index: src/sys/arch/x86/include/cpufunc.h
diff -u src/sys/arch/x86/include/cpufunc.h:1.22 src/sys/arch/x86/include/cpufunc.h:1.22.8.1
--- src/sys/arch/x86/include/cpufunc.h:1.22	Tue Dec 13 10:54:27 2016
+++ src/sys/arch/x86/include/cpufunc.h	Tue Mar  6 10:17:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpufunc.h,v 1.22 2016/12/13 10:54:27 kamil Exp $	*/
+/*	$NetBSD: cpufunc.h,v 1.22.8.1 2018/03/06 10:17:11 martin Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2007 The NetBSD Foundation, Inc.
@@ -50,6 +50,9 @@ void	x86_sfence(void);
 void	x86_mfence(void);
 void	x86_flush(void);
 #ifndef XEN
+void	x86_hotpatch(uint32_t, const uint8_t *, size_t);
+void	x86_patch_window_open(u_long *, u_long *);
+void	x86_patch_window_close(u_long, u_long);
 void	x86_patch(bool);
 #endif
 void	invlpg(vaddr_t);

Index: src/sys/arch/x86/x86/patch.c
diff -u src/sys/arch/x86/x86/patch.c:1.22 src/sys/arch/x86/x86/patch.c:1.22.22.1
--- src/sys/arch/x86/x86/patch.c:1.22	Fri Nov 15 08:47:55 2013
+++ src/sys/arch/x86/x86/patch.c	Tue Mar  6 10:17:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: patch.c,v 1.22 2013/11/15 08:47:55 msaitoh Exp $	*/
+/*	$NetBSD: patch.c,v 1.22.22.1 2018/03/06 10:17:11 martin Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.22 2013/11/15 08:47:55 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.22.22.1 2018/03/06 10:17:11 martin Exp $");
 
 #include "opt_lockdebug.h"
 #ifdef i386
@@ -47,10 +47,17 @@ __KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.
 #include <machine/cpu.h>
 #include <machine/cpufunc.h>
 #include <machine/specialreg.h>
+#include <machine/frameasm.h>
 
 #include <x86/cpuvar.h>
 #include <x86/cputypes.h>
 
+struct hotpatch {
+	uint8_t name;
+	uint8_t size;
+	void *addr;
+} __packed;
+
 void	spllower(int);
 void	spllower_end(void);
 void	cx8_spllower(int);
@@ -128,14 +135,59 @@ patchfunc(void *from_s, void *from_e, vo
 }
 
 static inline void __unused
-patchbytes(void *addr, const int byte1, const int byte2, const int byte3)
+patchbytes(void *addr, const uint8_t *bytes, size_t size)
 {
+	uint8_t *ptr = (uint8_t *)addr;
+	size_t i;
 
-	((uint8_t *)addr)[0] = (uint8_t)byte1;
-	if (byte2 != -1)
-		((uint8_t *)addr)[1] = (uint8_t)byte2;
-	if (byte3 != -1)
-		((uint8_t *)addr)[2] = (uint8_t)byte3;
+	for (i = 0; i < size; i++) {
+		ptr[i] = bytes[i];
+	}
+}
+
+void
+x86_hotpatch(uint32_t name, const uint8_t *bytes, size_t size)
+{
+	extern char __rodata_hotpatch_start;
+	extern char __rodata_hotpatch_end;
+	struct hotpatch *hps, *hpe, *hp;
+
+	hps = (struct hotpatch *)&__rodata_hotpatch_start;
+	hpe = (struct hotpatch *)&__rodata_hotpatch_end;
+
+	for (hp = hps; hp < hpe; hp++) {
+		if (hp->name != name) {
+			continue;
+		}
+		if (hp->size != size) {
+			panic("x86_hotpatch: incorrect size");
+		}
+		patchbytes(hp->addr, bytes, size);
+	}
+}
+
+void
+x86_patch_window_open(u_long *psl, u_long *cr0)
+{
+	/* Disable interrupts. */
+	*psl = x86_read_psl();
+	x86_disable_intr();
+
+	/* Disable write protection in supervisor mode. */
+	*cr0 = rcr0();
+	lcr0(*cr0 & ~CR0_WP);
+}
+
+void
+x86_patch_window_close(u_long psl, u_long cr0)
+{
+	/* Write back and invalidate cache, flush pipelines. */
+	wbinvd();
+	x86_flush();
+	x86_write_psl(psl);
+
+	/* Re-enable write protection. */
+	lcr0(cr0);
 }
 
 void
@@ -156,22 +208,23 @@ x86_patch(bool early)
 		second = true;
 	}
 
-	/* Disable interrupts. */
-	psl = x86_read_psl();
-	x86_disable_intr();
-
-	/* Disable write protection in supervisor mode. */
-	cr0 = rcr0();
-	lcr0(cr0 & ~CR0_WP);
+	x86_patch_window_open(&psl, &cr0);
 
 #if !defined(GPROF)
 	if (!early && ncpu == 1) {
 #ifndef LOCKDEBUG
+		/*
+		 * Uniprocessor: kill LOCK prefixes.
+		 */
+		const uint8_t bytes[] = {
+			X86_NOP
+		};
+
 		/* Uniprocessor: kill LOCK prefixes. */
 		for (i = 0; x86_lockpatch[i] != 0; i++)
-			patchbytes(x86_lockpatch[i], X86_NOP, -1, -1);
+			patchbytes(x86_lockpatch[i], bytes, sizeof(bytes));
 		for (i = 0; atomic_lockpatch[i] != 0; i++)
-			patchbytes(atomic_lockpatch[i], X86_NOP, -1, -1);
+			patchbytes(atomic_lockpatch[i], bytes, sizeof(bytes));
 #endif	/* !LOCKDEBUG */
 	}
 	if (!early && (cpu_feature[0] & CPUID_SSE2) != 0) {
@@ -230,17 +283,15 @@ x86_patch(bool early)
 	    (CPUID_TO_FAMILY(cpu_info_primary.ci_signature) == 0xe ||
 	    (CPUID_TO_FAMILY(cpu_info_primary.ci_signature) == 0xf &&
 	    CPUID_TO_EXTMODEL(cpu_info_primary.ci_signature) < 0x4))) {
+		const uint8_t bytes[] = {
+			0x0F, 0xAE, 0xE8 /* lfence */
+		};
+
 		for (i = 0; x86_retpatch[i] != 0; i++) {
 			/* ret,nop,nop,ret -> lfence,ret */
-			patchbytes(x86_retpatch[i], 0x0f, 0xae, 0xe8);
+			patchbytes(x86_retpatch[i], bytes, sizeof(bytes));
 		}
 	}
 
-	/* Write back and invalidate cache, flush pipelines. */
-	wbinvd();
-	x86_flush();
-	x86_write_psl(psl);
-
-	/* Re-enable write protection. */
-	lcr0(cr0);
+	x86_patch_window_close(psl, cr0);
 }

Reply via email to