svn commit: r251050 - in stable/9/sys/amd64: amd64 include
Konstantin Belousov
kib at FreeBSD.org
Tue May 28 05:36:19 UTC 2013
Author: kib
Date: Tue May 28 05:36:18 2013
New Revision: 251050
URL: http://svnweb.freebsd.org/changeset/base/251050
Log:
MFC r250851:
Fix the hardware watchpoints on SMP amd64.
Modified:
stable/9/sys/amd64/amd64/db_trace.c
stable/9/sys/amd64/amd64/mp_machdep.c
stable/9/sys/amd64/include/md_var.h
stable/9/sys/amd64/include/pcpu.h
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/amd64/amd64/db_trace.c
==============================================================================
--- stable/9/sys/amd64/amd64/db_trace.c Tue May 28 05:25:10 2013 (r251049)
+++ stable/9/sys/amd64/amd64/db_trace.c Tue May 28 05:36:18 2013 (r251050)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/proc.h>
+#include <sys/smp.h>
#include <sys/stack.h>
#include <sys/sysent.h>
@@ -63,6 +64,8 @@ static db_varfcn_t db_frame;
static db_varfcn_t db_rsp;
static db_varfcn_t db_ss;
+CTASSERT(sizeof(struct dbreg) == sizeof(((struct pcpu *)NULL)->pc_dbreg));
+
/*
* Machine register set.
*/
@@ -591,64 +594,82 @@ db_md_set_watchpoint(addr, size)
db_expr_t addr;
db_expr_t size;
{
- struct dbreg d;
- int avail, i, wsize;
+ struct dbreg *d;
+ struct pcpu *pc;
+ int avail, c, cpu, i, wsize;
- fill_dbregs(NULL, &d);
+ d = (struct dbreg *)PCPU_PTR(dbreg);
+ cpu = PCPU_GET(cpuid);
+ fill_dbregs(NULL, d);
avail = 0;
- for(i = 0; i < 4; i++) {
- if (!DBREG_DR7_ENABLED(d.dr[7], i))
+ for (i = 0; i < 4; i++) {
+ if (!DBREG_DR7_ENABLED(d->dr[7], i))
avail++;
}
if (avail * 8 < size)
return (-1);
- for (i = 0; i < 4 && (size > 0); i++) {
- if (!DBREG_DR7_ENABLED(d.dr[7], i)) {
+ for (i = 0; i < 4 && size > 0; i++) {
+ if (!DBREG_DR7_ENABLED(d->dr[7], i)) {
if (size >= 8 || (avail == 1 && size > 4))
wsize = 8;
else if (size > 2)
wsize = 4;
else
wsize = size;
- amd64_set_watch(i, addr, wsize,
- DBREG_DR7_WRONLY, &d);
+ amd64_set_watch(i, addr, wsize, DBREG_DR7_WRONLY, d);
addr += wsize;
size -= wsize;
avail--;
}
}
- set_dbregs(NULL, &d);
+ set_dbregs(NULL, d);
+ CPU_FOREACH(c) {
+ if (c == cpu)
+ continue;
+ pc = pcpu_find(c);
+ memcpy(pc->pc_dbreg, d, sizeof(*d));
+ pc->pc_dbreg_cmd = PC_DBREG_CMD_LOAD;
+ }
- return(0);
+ return (0);
}
-
int
db_md_clr_watchpoint(addr, size)
db_expr_t addr;
db_expr_t size;
{
- struct dbreg d;
- int i;
+ struct dbreg *d;
+ struct pcpu *pc;
+ int i, c, cpu;
- fill_dbregs(NULL, &d);
+ d = (struct dbreg *)PCPU_PTR(dbreg);
+ cpu = PCPU_GET(cpuid);
+ fill_dbregs(NULL, d);
- for(i = 0; i < 4; i++) {
- if (DBREG_DR7_ENABLED(d.dr[7], i)) {
- if ((DBREG_DRX((&d), i) >= addr) &&
- (DBREG_DRX((&d), i) < addr+size))
- amd64_clr_watch(i, &d);
+ for (i = 0; i < 4; i++) {
+ if (DBREG_DR7_ENABLED(d->dr[7], i)) {
+ if (DBREG_DRX((d), i) >= addr &&
+ DBREG_DRX((d), i) < addr + size)
+ amd64_clr_watch(i, d);
}
}
- set_dbregs(NULL, &d);
+ set_dbregs(NULL, d);
+ CPU_FOREACH(c) {
+ if (c == cpu)
+ continue;
+ pc = pcpu_find(c);
+ memcpy(pc->pc_dbreg, d, sizeof(*d));
+ pc->pc_dbreg_cmd = PC_DBREG_CMD_LOAD;
+ }
- return(0);
+ return (0);
}
@@ -699,3 +720,17 @@ db_md_list_watchpoints()
}
db_printf("\n");
}
+
+void
+amd64_db_resume_dbreg(void)
+{
+ struct dbreg *d;
+
+ switch (PCPU_GET(dbreg_cmd)) {
+ case PC_DBREG_CMD_LOAD:
+ d = (struct dbreg *)PCPU_PTR(dbreg);
+ set_dbregs(NULL, d);
+ PCPU_SET(dbreg_cmd, PC_DBREG_CMD_NONE);
+ break;
+ }
+}
Modified: stable/9/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- stable/9/sys/amd64/amd64/mp_machdep.c Tue May 28 05:25:10 2013 (r251049)
+++ stable/9/sys/amd64/amd64/mp_machdep.c Tue May 28 05:36:18 2013 (r251050)
@@ -28,6 +28,7 @@
__FBSDID("$FreeBSD$");
#include "opt_cpu.h"
+#include "opt_ddb.h"
#include "opt_kstack_pages.h"
#include "opt_sched.h"
#include "opt_smp.h"
@@ -1397,6 +1398,10 @@ cpustop_handler(void)
CPU_CLR_ATOMIC(cpu, &started_cpus);
CPU_CLR_ATOMIC(cpu, &stopped_cpus);
+#ifdef DDB
+ amd64_db_resume_dbreg();
+#endif
+
if (cpu == 0 && cpustop_restartfunc != NULL) {
cpustop_restartfunc();
cpustop_restartfunc = NULL;
Modified: stable/9/sys/amd64/include/md_var.h
==============================================================================
--- stable/9/sys/amd64/include/md_var.h Tue May 28 05:25:10 2013 (r251049)
+++ stable/9/sys/amd64/include/md_var.h Tue May 28 05:36:18 2013 (r251050)
@@ -117,5 +117,6 @@ void minidumpsys(struct dumperinfo *);
struct savefpu *get_pcb_user_save_td(struct thread *td);
struct savefpu *get_pcb_user_save_pcb(struct pcb *pcb);
struct pcb *get_pcb_td(struct thread *td);
+void amd64_db_resume_dbreg(void);
#endif /* !_MACHINE_MD_VAR_H_ */
Modified: stable/9/sys/amd64/include/pcpu.h
==============================================================================
--- stable/9/sys/amd64/include/pcpu.h Tue May 28 05:25:10 2013 (r251049)
+++ stable/9/sys/amd64/include/pcpu.h Tue May 28 05:36:18 2013 (r251050)
@@ -77,7 +77,12 @@
/* Pointer to the CPU TSS descriptor */ \
struct system_segment_descriptor *pc_tss; \
u_int pc_cmci_mask /* MCx banks for CMCI */ \
- PCPU_XEN_FIELDS
+ PCPU_XEN_FIELDS; \
+ uint64_t pc_dbreg[16]; /* ddb debugging regs */ \
+ int pc_dbreg_cmd; /* ddb debugging reg cmd */ \
+
+#define PC_DBREG_CMD_NONE 0
+#define PC_DBREG_CMD_LOAD 1
#ifdef _KERNEL
More information about the svn-src-stable-9
mailing list