From owner-svn-src-head@FreeBSD.ORG Tue May 21 11:24:33 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 5AD39339; Tue, 21 May 2013 11:24:33 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 3C523989; Tue, 21 May 2013 11:24:33 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r4LBOX2D053576; Tue, 21 May 2013 11:24:33 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r4LBOWlY053572; Tue, 21 May 2013 11:24:32 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201305211124.r4LBOWlY053572@svn.freebsd.org> From: Konstantin Belousov Date: Tue, 21 May 2013 11:24:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r250851 - in head/sys/amd64: amd64 include X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 May 2013 11:24:33 -0000 Author: kib Date: Tue May 21 11:24:32 2013 New Revision: 250851 URL: http://svnweb.freebsd.org/changeset/base/250851 Log: Fix the hardware watchpoints on SMP amd64. Load the updated %dr registers also on other CPUs, besides the CPU which happens to execute the ddb. The debugging registers are stored in the pcpu area, together with the command which is executed by the IPI stop handler upon resume. Reviewed by: jhb Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/amd64/amd64/db_trace.c head/sys/amd64/amd64/mp_machdep.c head/sys/amd64/include/md_var.h head/sys/amd64/include/pcpu.h Modified: head/sys/amd64/amd64/db_trace.c ============================================================================== --- head/sys/amd64/amd64/db_trace.c Tue May 21 11:07:12 2013 (r250850) +++ head/sys/amd64/amd64/db_trace.c Tue May 21 11:24:32 2013 (r250851) @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -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: head/sys/amd64/amd64/mp_machdep.c ============================================================================== --- head/sys/amd64/amd64/mp_machdep.c Tue May 21 11:07:12 2013 (r250850) +++ head/sys/amd64/amd64/mp_machdep.c Tue May 21 11:24:32 2013 (r250851) @@ -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" @@ -1396,6 +1397,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: head/sys/amd64/include/md_var.h ============================================================================== --- head/sys/amd64/include/md_var.h Tue May 21 11:07:12 2013 (r250850) +++ head/sys/amd64/include/md_var.h Tue May 21 11:24:32 2013 (r250851) @@ -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: head/sys/amd64/include/pcpu.h ============================================================================== --- head/sys/amd64/include/pcpu.h Tue May 21 11:07:12 2013 (r250850) +++ head/sys/amd64/include/pcpu.h Tue May 21 11:24:32 2013 (r250851) @@ -78,9 +78,14 @@ struct system_segment_descriptor *pc_tss; \ u_int pc_cmci_mask /* MCx banks for CMCI */ \ PCPU_XEN_FIELDS; \ - char __pad[293] /* be divisor of PAGE_SIZE \ + uint64_t pc_dbreg[16]; /* ddb debugging regs */ \ + int pc_dbreg_cmd; /* ddb debugging reg cmd */ \ + char __pad[161] /* be divisor of PAGE_SIZE \ after cache alignment */ +#define PC_DBREG_CMD_NONE 0 +#define PC_DBREG_CMD_LOAD 1 + #ifdef _KERNEL #ifdef lint