Clean up dbregs; remove useless comments, remove arguments from prototypes,

style, add KASSERT and move x86_dbregspl into dbregs.c. No real functional
change.
This commit is contained in:
maxv 2018-07-22 15:02:51 +00:00
parent 1577172429
commit 2b85909210
4 changed files with 52 additions and 92 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.307 2018/07/21 06:09:13 maxv Exp $ */
/* $NetBSD: machdep.c,v 1.308 2018/07/22 15:02:51 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.307 2018/07/21 06:09:13 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.308 2018/07/22 15:02:51 maxv Exp $");
#include "opt_modular.h"
#include "opt_user_ldt.h"
@ -280,7 +280,7 @@ void (*delay_func)(unsigned int) = xen_delay;
void (*initclock_func)(void) = xen_initclocks;
#endif
struct pool x86_dbregspl;
extern struct pool x86_dbregspl;
struct nmistore {
uint64_t cr3;
@ -1929,11 +1929,7 @@ init_x86_64(paddr_t first_avail)
#endif
pcb->pcb_dbregs = NULL;
x86_dbregs_setup_initdbstate();
pool_init(&x86_dbregspl, sizeof(struct dbreg), 16, 0, 0, "dbregs",
NULL, IPL_NONE);
x86_dbregs_init();
}
void

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.806 2018/04/05 08:43:07 maxv Exp $ */
/* $NetBSD: machdep.c,v 1.807 2018/07/22 15:02:51 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.806 2018/04/05 08:43:07 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.807 2018/07/22 15:02:51 maxv Exp $");
#include "opt_beep.h"
#include "opt_compat_freebsd.h"
@ -213,7 +213,7 @@ int i386_use_fxsave;
int i386_has_sse;
int i386_has_sse2;
struct pool x86_dbregspl;
extern struct pool x86_dbregspl;
vaddr_t idt_vaddr;
paddr_t idt_paddr;
@ -1443,11 +1443,7 @@ init386(paddr_t first_avail)
}
pcb->pcb_dbregs = NULL;
x86_dbregs_setup_initdbstate();
pool_init(&x86_dbregspl, sizeof(struct dbreg), 16, 0, 0, "dbregs",
NULL, IPL_NONE);
x86_dbregs_init();
}
#include <dev/ic/mc146818reg.h> /* for NVRAM POST */

View File

@ -1,6 +1,6 @@
/* $NetBSD: dbregs.h,v 1.4 2017/02/23 03:34:22 kamil Exp $ */
/* $NetBSD: dbregs.h,v 1.5 2018/07/22 15:02:51 maxv Exp $ */
/*-
/*
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* All rights reserved.
*
@ -26,7 +26,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _X86_DBREGS_H_
#define _X86_DBREGS_H_
@ -50,11 +49,11 @@
/*
* CPU Debug Control Register (DR7)
*
* LOCAL_EXACT_BREAKPOINT and GLOBAL_EXACT_BREAKPOINT are no longer used since
* the P6 processor family - portable code should set these bits
* unconditionally in oder to get exact breakpoints
* LOCAL_EXACT_BREAKPOINT and GLOBAL_EXACT_BREAKPOINT are no longer used
* since the P6 processor family - portable code should set these bits
* unconditionally in order to get exact breakpoints.
*
* Reserved bits: 10, 12, 14-15 and on x86_64 32-64
* Reserved bits: 10, 12, 14-15 and on x86_64 32-64.
*/
#define X86_DR7_LOCAL_DR0_BREAKPOINT __BIT(0)
#define X86_DR7_GLOBAL_DR0_BREAKPOINT __BIT(1)
@ -79,9 +78,9 @@
#define X86_DR7_DR3_LENGTH_MASK __BITS(30, 31)
/*
* X86_DR7_CONDITION_IO_READWRITE is currently unused
* it requires DE (debug extension) flag in control register CR4 set
* not all CPUs support it
* X86_DR7_CONDITION_IO_READWRITE is currently unused. It requires DE
* (debug extension) flag in control register CR4 set, and not all CPUs
* support it.
*/
enum x86_dr7_condition {
X86_DR7_CONDITION_EXECUTION = 0x0,
@ -91,7 +90,7 @@ enum x86_dr7_condition {
};
/*
* 0x2 is currently unimplemented - it reflects 8 bytes on modern CPUs
* 0x2 is currently unimplemented - it reflects 8 bytes on modern CPUs.
*/
enum x86_dr7_length {
X86_DR7_LENGTH_BYTE = 0x0,
@ -107,46 +106,13 @@ enum x86_dr7_length {
*/
#define X86_DBREGS 4
/*
* Store the initial Debug Register state of CPU
* This copy will be used to initialize new debug register state
*/
void x86_dbregs_setup_initdbstate(void);
/*
* Reset CPU Debug Registers - to be used after returning to user context
*/
void x86_dbregs_clear(struct lwp *l);
/*
* Retrieve Debug Registers from LWP's PCB and save in regs
* In case of empty register set, initialize it
*/
void x86_dbregs_read(struct lwp *l, struct dbreg *regs);
/*
* Set CPU Debug Registers - to be used before entering user-land context
*/
void x86_dbregs_set(struct lwp *l);
/*
* Store DR6 in LWP - to be used in trap function
*/
void x86_dbregs_store_dr6(struct lwp *l);
/*
* Check if trap is triggered from user-land if so return nonzero value
*/
void x86_dbregs_init(void);
void x86_dbregs_clear(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);
/*
* Check if trap is triggered from user-land if so return nonzero value
*/
int x86_dbregs_validate(const struct dbreg *regs);
/*
* Write new Debug Registers from regs into LWP's PCB
*/
void x86_dbregs_write(struct lwp *l, const struct dbreg *regs);
int x86_dbregs_validate(const struct dbreg *);
void x86_dbregs_write(struct lwp *, const struct dbreg *);
#endif /* !_X86_DBREGS_H_ */

View File

@ -1,6 +1,6 @@
/* $NetBSD: dbregs.c,v 1.9 2018/04/08 14:21:23 kamil Exp $ */
/* $NetBSD: dbregs.c,v 1.10 2018/07/22 15:02:51 maxv Exp $ */
/*-
/*
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* All rights reserved.
*
@ -26,7 +26,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/lwp.h>
@ -39,7 +38,7 @@
#include <machine/pmap.h>
extern struct pool x86_dbregspl;
struct pool x86_dbregspl;
static struct dbreg initdbstate;
@ -56,7 +55,7 @@ static struct dbreg initdbstate;
X86_DR7_GLOBAL_DR3_BREAKPOINT )
void
x86_dbregs_setup_initdbstate(void)
x86_dbregs_init(void)
{
/* DR0-DR3 should always be 0 */
initdbstate.dr[0] = rdr0();
@ -70,14 +69,14 @@ x86_dbregs_setup_initdbstate(void)
/* DR8-DR15 are reserved - skip */
/*
* Paranoid case.
*
* Explicitly reset some bits just in case they could be
* set by brave software/hardware before the kernel boot.
*/
initdbstate.dr[6] &= ~X86_BREAKPOINT_CONDITION_DETECTED;
initdbstate.dr[7] &= ~X86_DR7_GENERAL_DETECT_ENABLE;
pool_init(&x86_dbregspl, sizeof(struct dbreg), 16, 0, 0, "dbregs",
NULL, IPL_NONE);
}
void
@ -88,16 +87,16 @@ x86_dbregs_clear(struct lwp *l)
KASSERT(pcb->pcb_dbregs == NULL);
/*
* It's sufficient to just disable Debug Control Register (DR7)
* it will deactivate hardware watchpoints
* It's sufficient to just disable Debug Control Register (DR7).
* It will deactivate hardware watchpoints.
*/
ldr7(0);
/*
* However at some point we need to clear Debug Status Registers (DR6)
* CPU will never do it automatically
* However at some point we need to clear Debug Status Registers
* (DR6). The CPU will never do it automatically.
*
* Clear BREAKPOINT_CONDITION_DETECTED bits and ignore the rest
* Clear BREAKPOINT_CONDITION_DETECTED bits and ignore the rest.
*/
ldr6(rdr6() & ~X86_BREAKPOINT_CONDITION_DETECTED);
}
@ -135,6 +134,7 @@ x86_dbregs_store_dr6(struct lwp *l)
{
struct pcb *pcb = lwp_getpcb(l);
KASSERT(l == curlwp);
KASSERT(pcb->pcb_dbregs != NULL);
pcb->pcb_dbregs->dr[6] = rdr6();
@ -143,15 +143,14 @@ x86_dbregs_store_dr6(struct lwp *l)
int
x86_dbregs_user_trap(void)
{
register_t dr7, dr6; /* debug registers dr6 and dr7 */
register_t bp; /* breakpoint bits extracted from dr6 */
register_t dr7, dr6;
register_t bp;
dr7 = rdr7();
if ((dr7 & X86_GLOBAL_BREAKPOINT) == 0) {
/*
* all Global Breakpoint bits in the DR7 register are zero,
* thus the trap couldn't have been caused by the
* hardware debug registers
* All Global Breakpoint bits are zero, thus the trap couldn't
* have been caused by the hardware debug registers.
*/
return 0;
}
@ -161,15 +160,15 @@ x86_dbregs_user_trap(void)
if (!bp) {
/*
* None of the breakpoint bits are set meaning this
* trap was not caused by any of the debug registers
* None of the breakpoint bits are set, meaning this
* trap was not caused by any of the debug registers.
*/
return 0;
}
/*
* at least one of the breakpoints were hit, check to see
* which ones and if any of them are user space addresses
* At least one of the breakpoints was hit, check to see
* which ones and if any of them are user space addresses.
*/
if (bp & X86_DR6_DR0_BREAKPOINT_CONDITION_DETECTED)
@ -197,12 +196,14 @@ x86_dbregs_validate(const struct dbreg *regs)
size_t i;
/* Check that DR0-DR3 contain user-space address */
for (i = 0; i < X86_DBREGS; i++)
for (i = 0; i < X86_DBREGS; i++) {
if (regs->dr[i] >= (vaddr_t)VM_MAXUSER_ADDRESS)
return EINVAL;
}
if (regs->dr[7] & X86_DR7_GENERAL_DETECT_ENABLE)
if (regs->dr[7] & X86_DR7_GENERAL_DETECT_ENABLE) {
return EINVAL;
}
/*
* Skip checks for reserved registers (DR4-DR5, DR8-DR15).
@ -216,8 +217,9 @@ x86_dbregs_write(struct lwp *l, const struct dbreg *regs)
{
struct pcb *pcb = lwp_getpcb(l);
if (pcb->pcb_dbregs == NULL)
if (pcb->pcb_dbregs == NULL) {
pcb->pcb_dbregs = pool_get(&x86_dbregspl, PR_WAITOK);
}
memcpy(pcb->pcb_dbregs, regs, sizeof(*regs));
}