Module Name: src
Committed By: maxv
Date: Thu Jul 26 09:29:08 UTC 2018
Modified Files:
src/sys/arch/amd64/amd64: locore.S machdep.c netbsd32_machdep.c trap.c
src/sys/arch/amd64/include: pcb.h userret.h
src/sys/arch/i386/i386: locore.S machdep.c trap.c
src/sys/arch/i386/include: pcb.h userret.h
src/sys/arch/x86/include: dbregs.h
src/sys/arch/x86/x86: dbregs.c vm_machdep.c
Log Message:
Rework dbregs, to switch the registers during context switches, and not on
each user->kernel transition via userret. Reloads of DR6/DR7 are expensive
on both native and xen.
To generate a diff of this commit:
cvs rdiff -u -r1.172 -r1.173 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.308 -r1.309 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.115 -r1.116 src/sys/arch/amd64/amd64/netbsd32_machdep.c
cvs rdiff -u -r1.113 -r1.114 src/sys/arch/amd64/amd64/trap.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/amd64/include/pcb.h
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/amd64/include/userret.h
cvs rdiff -u -r1.159 -r1.160 src/sys/arch/i386/i386/locore.S
cvs rdiff -u -r1.807 -r1.808 src/sys/arch/i386/i386/machdep.c
cvs rdiff -u -r1.295 -r1.296 src/sys/arch/i386/i386/trap.c
cvs rdiff -u -r1.57 -r1.58 src/sys/arch/i386/include/pcb.h
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/i386/include/userret.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x86/include/dbregs.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/x86/x86/dbregs.c
cvs rdiff -u -r1.35 -r1.36 src/sys/arch/x86/x86/vm_machdep.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/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.172 src/sys/arch/amd64/amd64/locore.S:1.173
--- src/sys/arch/amd64/amd64/locore.S:1.172 Sat Jul 21 06:09:13 2018
+++ src/sys/arch/amd64/amd64/locore.S Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.172 2018/07/21 06:09:13 maxv Exp $ */
+/* $NetBSD: locore.S,v 1.173 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright-o-rama!
@@ -1143,6 +1143,11 @@ ENTRY(cpu_switchto)
#endif
.Lring0_switched:
+ /* Switch the dbregs. */
+ movq %r13,%rdi
+ movq %r12,%rsi
+ callq _C_LABEL(x86_dbregs_switch)
+
#ifndef XEN
movb _C_LABEL(x86_fpu_eager),%dl
testb %dl,%dl
Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.308 src/sys/arch/amd64/amd64/machdep.c:1.309
--- src/sys/arch/amd64/amd64/machdep.c:1.308 Sun Jul 22 15:02:51 2018
+++ src/sys/arch/amd64/amd64/machdep.c Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.308 2018/07/22 15:02:51 maxv Exp $ */
+/* $NetBSD: machdep.c,v 1.309 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.308 2018/07/22 15:02:51 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.309 2018/07/26 09:29:08 maxv Exp $");
#include "opt_modular.h"
#include "opt_user_ldt.h"
@@ -280,8 +280,6 @@ void (*delay_func)(unsigned int) = xen_d
void (*initclock_func)(void) = xen_initclocks;
#endif
-extern struct pool x86_dbregspl;
-
struct nmistore {
uint64_t cr3;
uint64_t scratch;
@@ -1367,10 +1365,7 @@ setregs(struct lwp *l, struct exec_packa
fpu_save_area_clear(l, pack->ep_osversion >= 699002600
? __NetBSD_NPXCW__ : __NetBSD_COMPAT_NPXCW__);
pcb->pcb_flags = 0;
- if (pcb->pcb_dbregs != NULL) {
- pool_put(&x86_dbregspl, pcb->pcb_dbregs);
- pcb->pcb_dbregs = NULL;
- }
+ x86_dbregs_clear(l);
l->l_proc->p_flag &= ~PK_32;
Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c
diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.115 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.116
--- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.115 Thu Dec 7 23:11:50 2017
+++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.c,v 1.115 2017/12/07 23:11:50 christos Exp $ */
+/* $NetBSD: netbsd32_machdep.c,v 1.116 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.115 2017/12/07 23:11:50 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.116 2018/07/26 09:29:08 maxv Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -63,6 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_mac
#include <sys/kauth.h>
#include <x86/fpu.h>
+#include <x86/dbregs.h>
#include <machine/frame.h>
#include <machine/reg.h>
#include <machine/vmparam.h>
@@ -80,8 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_mac
#include <compat/sys/signal.h>
#include <compat/sys/signalvar.h>
-extern struct pool x86_dbregspl;
-
/* Provide a the name of the architecture we're emulating */
const char machine32[] = "i386";
const char machine_arch32[] = "i386";
@@ -138,10 +137,7 @@ netbsd32_setregs(struct lwp *l, struct e
fpu_save_area_clear(l, pack->ep_osversion >= 699002600
? __NetBSD_NPXCW__ : __NetBSD_COMPAT_NPXCW__);
- if (pcb->pcb_dbregs != NULL) {
- pool_put(&x86_dbregspl, pcb->pcb_dbregs);
- pcb->pcb_dbregs = NULL;
- }
+ x86_dbregs_clear(l);
p->p_flag |= PK_32;
Index: src/sys/arch/amd64/amd64/trap.c
diff -u src/sys/arch/amd64/amd64/trap.c:1.113 src/sys/arch/amd64/amd64/trap.c:1.114
--- src/sys/arch/amd64/amd64/trap.c:1.113 Sun Feb 25 13:09:33 2018
+++ src/sys/arch/amd64/amd64/trap.c Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.113 2018/02/25 13:09:33 maxv Exp $ */
+/* $NetBSD: trap.c,v 1.114 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.113 2018/02/25 13:09:33 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.114 2018/07/26 09:29:08 maxv Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -93,6 +93,7 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.1
#include <machine/cpufunc.h>
#include <x86/fpu.h>
+#include <x86/dbregs.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <machine/trap.h>
Index: src/sys/arch/amd64/include/pcb.h
diff -u src/sys/arch/amd64/include/pcb.h:1.28 src/sys/arch/amd64/include/pcb.h:1.29
--- src/sys/arch/amd64/include/pcb.h:1.28 Sun Dec 31 07:23:09 2017
+++ src/sys/arch/amd64/include/pcb.h Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: pcb.h,v 1.28 2017/12/31 07:23:09 maxv Exp $ */
+/* $NetBSD: pcb.h,v 1.29 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -80,6 +80,7 @@
struct pcb {
int pcb_flags;
#define PCB_COMPAT32 0x01
+#define PCB_DBREGS 0x02
u_int pcb_cr0; /* saved image of CR0 */
uint64_t pcb_rsp0;
uint64_t pcb_cr2; /* page fault address (CR2) */
Index: src/sys/arch/amd64/include/userret.h
diff -u src/sys/arch/amd64/include/userret.h:1.12 src/sys/arch/amd64/include/userret.h:1.13
--- src/sys/arch/amd64/include/userret.h:1.12 Thu Feb 23 03:34:22 2017
+++ src/sys/arch/amd64/include/userret.h Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: userret.h,v 1.12 2017/02/23 03:34:22 kamil Exp $ */
+/* $NetBSD: userret.h,v 1.13 2018/07/26 09:29:08 maxv Exp $ */
/*
* XXXfvdl same as i386 counterpart, but should probably be independent.
@@ -67,7 +67,6 @@
*/
#include <sys/userret.h>
-#include <x86/dbregs.h>
static __inline void userret(struct lwp *);
@@ -78,13 +77,6 @@ static __inline void userret(struct lwp
static __inline void
userret(struct lwp *l)
{
- struct pcb *pcb = lwp_getpcb(l);
-
/* Invoke MI userret code */
mi_userret(l);
-
- if (pcb->pcb_dbregs)
- x86_dbregs_set(l);
- else
- x86_dbregs_clear(l);
}
Index: src/sys/arch/i386/i386/locore.S
diff -u src/sys/arch/i386/i386/locore.S:1.159 src/sys/arch/i386/i386/locore.S:1.160
--- src/sys/arch/i386/i386/locore.S:1.159 Sat Jul 14 14:29:40 2018
+++ src/sys/arch/i386/i386/locore.S Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.159 2018/07/14 14:29:40 maxv Exp $ */
+/* $NetBSD: locore.S,v 1.160 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright-o-rama!
@@ -128,7 +128,7 @@
*/
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.159 2018/07/14 14:29:40 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.160 2018/07/26 09:29:08 maxv Exp $");
#include "opt_copy_symtab.h"
#include "opt_ddb.h"
@@ -1116,6 +1116,12 @@ skip_save:
movl %eax,TSS_ESP0(%ecx)
#endif
+ /* Switch the dbregs. */
+ pushl %edi
+ pushl %esi
+ call _C_LABEL(x86_dbregs_switch)
+ addl $8,%esp
+
#ifndef XEN
pushl %edx
movb _C_LABEL(x86_fpu_eager),%dl
Index: src/sys/arch/i386/i386/machdep.c
diff -u src/sys/arch/i386/i386/machdep.c:1.807 src/sys/arch/i386/i386/machdep.c:1.808
--- src/sys/arch/i386/i386/machdep.c:1.807 Sun Jul 22 15:02:51 2018
+++ src/sys/arch/i386/i386/machdep.c Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.807 2018/07/22 15:02:51 maxv Exp $ */
+/* $NetBSD: machdep.c,v 1.808 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009, 2017
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.807 2018/07/22 15:02:51 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.808 2018/07/26 09:29:08 maxv Exp $");
#include "opt_beep.h"
#include "opt_compat_freebsd.h"
@@ -213,8 +213,6 @@ int i386_use_fxsave;
int i386_has_sse;
int i386_has_sse2;
-extern struct pool x86_dbregspl;
-
vaddr_t idt_vaddr;
paddr_t idt_paddr;
vaddr_t gdt_vaddr;
@@ -874,10 +872,8 @@ setregs(struct lwp *l, struct exec_packa
memcpy(&pcb->pcb_fsd, &gdtstore[GUDATA_SEL], sizeof(pcb->pcb_fsd));
memcpy(&pcb->pcb_gsd, &gdtstore[GUDATA_SEL], sizeof(pcb->pcb_gsd));
- if (pcb->pcb_dbregs != NULL) {
- pool_put(&x86_dbregspl, pcb->pcb_dbregs);
- pcb->pcb_dbregs = NULL;
- }
+
+ x86_dbregs_clear(l);
tf = l->l_md.md_regs;
tf->tf_gs = GSEL(GUGS_SEL, SEL_UPL);
Index: src/sys/arch/i386/i386/trap.c
diff -u src/sys/arch/i386/i386/trap.c:1.295 src/sys/arch/i386/i386/trap.c:1.296
--- src/sys/arch/i386/i386/trap.c:1.295 Wed May 16 16:33:23 2018
+++ src/sys/arch/i386/i386/trap.c Thu Jul 26 09:29:08 2018
@@ -1,5 +1,5 @@
-/* $NetBSD: trap.c,v 1.295 2018/05/16 16:33:23 maxv Exp $ */
+/* $NetBSD: trap.c,v 1.296 2018/07/26 09:29:08 maxv Exp $ */
/*-
* Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.295 2018/05/16 16:33:23 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.296 2018/07/26 09:29:08 maxv Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -106,6 +106,7 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.2
#include <machine/mca_machdep.h>
#endif
+#include <x86/dbregs.h>
#include <x86/nmi.h>
#include "isa.h"
Index: src/sys/arch/i386/include/pcb.h
diff -u src/sys/arch/i386/include/pcb.h:1.57 src/sys/arch/i386/include/pcb.h:1.58
--- src/sys/arch/i386/include/pcb.h:1.57 Tue Oct 31 12:02:20 2017
+++ src/sys/arch/i386/include/pcb.h Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: pcb.h,v 1.57 2017/10/31 12:02:20 maxv Exp $ */
+/* $NetBSD: pcb.h,v 1.58 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 1998, 2009 The NetBSD Foundation, Inc.
@@ -93,7 +93,10 @@ struct pcb {
struct dbreg *pcb_dbregs; /* CPU Debug Registers */
uint16_t pcb_fpu_dflt_cw;
- int not_used[16];
+#define PCB_DBREGS 0x01
+ int pcb_flags;
+
+ int not_used[15];
/* floating point state */
struct cpu_info *pcb_fpcpu; /* cpu holding our fp state. */
Index: src/sys/arch/i386/include/userret.h
diff -u src/sys/arch/i386/include/userret.h:1.14 src/sys/arch/i386/include/userret.h:1.15
--- src/sys/arch/i386/include/userret.h:1.14 Thu Feb 23 03:34:22 2017
+++ src/sys/arch/i386/include/userret.h Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: userret.h,v 1.14 2017/02/23 03:34:22 kamil Exp $ */
+/* $NetBSD: userret.h,v 1.15 2018/07/26 09:29:08 maxv Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -63,7 +63,6 @@
*/
#include <sys/userret.h>
-#include <x86/dbregs.h>
static __inline void userret(struct lwp *);
@@ -74,13 +73,6 @@ static __inline void userret(struct lwp
static __inline void
userret(struct lwp *l)
{
- struct pcb *pcb = lwp_getpcb(l);
-
/* Invoke MI userret code */
mi_userret(l);
-
- if (pcb->pcb_dbregs)
- x86_dbregs_set(l);
- else
- x86_dbregs_clear(l);
}
Index: src/sys/arch/x86/include/dbregs.h
diff -u src/sys/arch/x86/include/dbregs.h:1.5 src/sys/arch/x86/include/dbregs.h:1.6
--- src/sys/arch/x86/include/dbregs.h:1.5 Sun Jul 22 15:02:51 2018
+++ src/sys/arch/x86/include/dbregs.h Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: dbregs.h,v 1.5 2018/07/22 15:02:51 maxv Exp $ */
+/* $NetBSD: dbregs.h,v 1.6 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -108,11 +108,12 @@ enum x86_dr7_length {
void x86_dbregs_init(void);
void x86_dbregs_clear(struct lwp *);
+void x86_dbregs_abandon(struct lwp *);
void x86_dbregs_read(struct lwp *, struct dbreg *);
-void x86_dbregs_set(struct lwp *);
void x86_dbregs_store_dr6(struct lwp *);
int x86_dbregs_user_trap(void);
int x86_dbregs_validate(const struct dbreg *);
void x86_dbregs_write(struct lwp *, const struct dbreg *);
+void x86_dbregs_switch(struct lwp *, struct lwp *);
#endif /* !_X86_DBREGS_H_ */
Index: src/sys/arch/x86/x86/dbregs.c
diff -u src/sys/arch/x86/x86/dbregs.c:1.10 src/sys/arch/x86/x86/dbregs.c:1.11
--- src/sys/arch/x86/x86/dbregs.c:1.10 Sun Jul 22 15:02:51 2018
+++ src/sys/arch/x86/x86/dbregs.c Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: dbregs.c,v 1.10 2018/07/22 15:02:51 maxv Exp $ */
+/* $NetBSD: dbregs.c,v 1.11 2018/07/26 09:29:08 maxv Exp $ */
/*
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -39,7 +39,6 @@
#include <machine/pmap.h>
struct pool x86_dbregspl;
-
static struct dbreg initdbstate;
#define X86_BREAKPOINT_CONDITION_DETECTED ( \
@@ -79,13 +78,9 @@ x86_dbregs_init(void)
NULL, IPL_NONE);
}
-void
-x86_dbregs_clear(struct lwp *l)
+static void
+x86_dbregs_reset(void)
{
- struct pcb *pcb __diagused = lwp_getpcb(l);
-
- KASSERT(pcb->pcb_dbregs == NULL);
-
/*
* It's sufficient to just disable Debug Control Register (DR7).
* It will deactivate hardware watchpoints.
@@ -102,6 +97,41 @@ x86_dbregs_clear(struct lwp *l)
}
void
+x86_dbregs_clear(struct lwp *l)
+{
+ struct pcb *pcb = lwp_getpcb(l);
+ struct dbreg *dbregs;
+
+ KASSERT(l == curlwp);
+
+ if (__predict_true(pcb->pcb_dbregs == NULL)) {
+ KASSERT((pcb->pcb_flags & PCB_DBREGS) == 0);
+ return;
+ }
+
+ dbregs = pcb->pcb_dbregs;
+
+ kpreempt_disable();
+ pcb->pcb_dbregs = NULL;
+ pcb->pcb_flags &= ~PCB_DBREGS;
+ x86_dbregs_reset();
+ kpreempt_enable();
+
+ pool_put(&x86_dbregspl, dbregs);
+}
+
+void
+x86_dbregs_abandon(struct lwp *l)
+{
+ struct pcb *pcb = lwp_getpcb(l);
+
+ kpreempt_disable();
+ pcb->pcb_flags &= ~PCB_DBREGS;
+ x86_dbregs_reset();
+ kpreempt_enable();
+}
+
+void
x86_dbregs_read(struct lwp *l, struct dbreg *regs)
{
struct pcb *pcb = lwp_getpcb(l);
@@ -109,12 +139,29 @@ x86_dbregs_read(struct lwp *l, struct db
if (pcb->pcb_dbregs == NULL) {
pcb->pcb_dbregs = pool_get(&x86_dbregspl, PR_WAITOK);
memcpy(pcb->pcb_dbregs, &initdbstate, sizeof(initdbstate));
+ pcb->pcb_flags |= PCB_DBREGS;
}
memcpy(regs, pcb->pcb_dbregs, sizeof(*regs));
}
-void
-x86_dbregs_set(struct lwp *l)
+static void
+x86_dbregs_save(struct lwp *l)
+{
+ struct pcb *pcb = lwp_getpcb(l);
+
+ KASSERT(pcb->pcb_dbregs != NULL);
+
+ pcb->pcb_dbregs->dr[0] = rdr0();
+ pcb->pcb_dbregs->dr[1] = rdr1();
+ pcb->pcb_dbregs->dr[2] = rdr2();
+ pcb->pcb_dbregs->dr[3] = rdr3();
+
+ pcb->pcb_dbregs->dr[6] = rdr6();
+ pcb->pcb_dbregs->dr[7] = rdr7();
+}
+
+static void
+x86_dbregs_restore(struct lwp *l)
{
struct pcb *pcb = lwp_getpcb(l);
@@ -222,4 +269,38 @@ x86_dbregs_write(struct lwp *l, const st
}
memcpy(pcb->pcb_dbregs, regs, sizeof(*regs));
+ pcb->pcb_flags |= PCB_DBREGS;
+}
+
+/*
+ * Called with preemption disabled.
+ */
+void
+x86_dbregs_switch(struct lwp *oldlwp, struct lwp *newlwp)
+{
+ struct pcb *oldpcb, *newpcb;
+ bool olddb, newdb;
+
+ oldpcb = (oldlwp != NULL) ? lwp_getpcb(oldlwp) : NULL;
+ newpcb = lwp_getpcb(newlwp);
+
+ olddb = false;
+ if (oldpcb) {
+ olddb = (oldpcb->pcb_flags & PCB_DBREGS) != 0;
+ }
+ newdb = (newpcb->pcb_flags & PCB_DBREGS) != 0;
+
+ if (__predict_true(!olddb && !newdb)) {
+ /* fast path */
+ return;
+ }
+
+ if (olddb) {
+ x86_dbregs_save(oldlwp);
+ }
+ if (newdb) {
+ x86_dbregs_restore(newlwp);
+ } else if (olddb) {
+ x86_dbregs_reset();
+ }
}
Index: src/sys/arch/x86/x86/vm_machdep.c
diff -u src/sys/arch/x86/x86/vm_machdep.c:1.35 src/sys/arch/x86/x86/vm_machdep.c:1.36
--- src/sys/arch/x86/x86/vm_machdep.c:1.35 Sun Jul 1 08:32:41 2018
+++ src/sys/arch/x86/x86/vm_machdep.c Thu Jul 26 09:29:08 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.35 2018/07/01 08:32:41 maxv Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.36 2018/07/26 09:29:08 maxv Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.35 2018/07/01 08:32:41 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.36 2018/07/26 09:29:08 maxv Exp $");
#include "opt_mtrr.h"
@@ -166,6 +166,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
/* Never inherit CPU Debug Registers */
pcb2->pcb_dbregs = NULL;
+ pcb2->pcb_flags &= ~PCB_DBREGS;
#if defined(XEN)
pcb2->pcb_iopl = IOPL_KPL;
@@ -262,6 +263,9 @@ cpu_lwp_free(struct lwp *l, int proc)
/* If we were using the FPU, forget about it. */
fpusave_lwp(l, false);
+ /* Abandon the dbregs state. */
+ x86_dbregs_abandon(l);
+
#ifdef MTRR
if (proc && l->l_proc->p_md.md_flags & MDP_USEDMTRR)
mtrr_clean(l->l_proc);
@@ -287,7 +291,7 @@ cpu_lwp_free2(struct lwp *l)
KASSERT(l->l_md.md_gc_pmap == NULL);
pcb = lwp_getpcb(l);
-
+ KASSERT((pcb->pcb_flags & PCB_DBREGS) == 0);
if (pcb->pcb_dbregs) {
pool_put(&x86_dbregspl, pcb->pcb_dbregs);
pcb->pcb_dbregs = NULL;