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:
parent
1577172429
commit
2b85909210
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue