From 3ad234d4efc659416d35b44461b74d6886cec9e2 Mon Sep 17 00:00:00 2001 From: "Brian S. Dean" Date: Thu, 19 Jul 2001 04:37:27 +0000 Subject: [PATCH] swtch.s: During context save, use the correct bit mask for clearing the non-reserved bits of dr7. During context restore, load dr7 in such a way as to not disturb reserved bits. machdep.c: Don't explicitly disallow the setting of the reserved bits in dr7 since we now keep from setting them when we load dr7 from the PCB. This allows one to write back the dr7 value obtained from the system without triggering an EINVAL (one of the reserved bits always seems to be set after taking a trace trap). MFC after: 7 days --- sys/amd64/amd64/cpu_switch.S | 10 ++++++++-- sys/amd64/amd64/machdep.c | 3 --- sys/amd64/amd64/swtch.s | 10 ++++++++-- sys/i386/i386/machdep.c | 3 --- sys/i386/i386/swtch.s | 10 ++++++++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index 180b87be8fc7..0f2f7a86e98c 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -104,7 +104,7 @@ ENTRY(cpu_switch) jz 1f /* no, skip over */ movl %dr7,%eax /* yes, do the save */ movl %eax,PCB_DR7(%edx) - andl $0x0000ff00, %eax /* disable all watchpoints */ + andl $0x0000fc00, %eax /* disable all watchpoints */ movl %eax,%dr7 movl %dr6,%eax movl %eax,PCB_DR6(%edx) @@ -271,7 +271,13 @@ cpu_switch_load_gs: movl %eax,%dr1 movl PCB_DR0(%edx),%eax movl %eax,%dr0 - movl PCB_DR7(%edx),%eax + movl %dr7,%eax /* load dr7 so as not to disturb */ + andl $0x0000fc00,%eax /* reserved bits */ + pushl %ebx + movl PCB_DR7(%edx),%ebx + andl $~0x0000fc00,%ebx + orl %ebx,%eax + popl %ebx movl %eax,%dr7 1: ret diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 7e9a4dd222da..c12e6761fb19 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -2314,9 +2314,6 @@ set_dbregs(p, dbregs) if ((dbregs->dr7 & mask1) == mask2) return (EINVAL); - if (dbregs->dr7 & 0x0000fc00) - return (EINVAL); - pcb = &p->p_addr->u_pcb; /* diff --git a/sys/amd64/amd64/swtch.s b/sys/amd64/amd64/swtch.s index 180b87be8fc7..0f2f7a86e98c 100644 --- a/sys/amd64/amd64/swtch.s +++ b/sys/amd64/amd64/swtch.s @@ -104,7 +104,7 @@ ENTRY(cpu_switch) jz 1f /* no, skip over */ movl %dr7,%eax /* yes, do the save */ movl %eax,PCB_DR7(%edx) - andl $0x0000ff00, %eax /* disable all watchpoints */ + andl $0x0000fc00, %eax /* disable all watchpoints */ movl %eax,%dr7 movl %dr6,%eax movl %eax,PCB_DR6(%edx) @@ -271,7 +271,13 @@ cpu_switch_load_gs: movl %eax,%dr1 movl PCB_DR0(%edx),%eax movl %eax,%dr0 - movl PCB_DR7(%edx),%eax + movl %dr7,%eax /* load dr7 so as not to disturb */ + andl $0x0000fc00,%eax /* reserved bits */ + pushl %ebx + movl PCB_DR7(%edx),%ebx + andl $~0x0000fc00,%ebx + orl %ebx,%eax + popl %ebx movl %eax,%dr7 1: ret diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 7e9a4dd222da..c12e6761fb19 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -2314,9 +2314,6 @@ set_dbregs(p, dbregs) if ((dbregs->dr7 & mask1) == mask2) return (EINVAL); - if (dbregs->dr7 & 0x0000fc00) - return (EINVAL); - pcb = &p->p_addr->u_pcb; /* diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s index 180b87be8fc7..0f2f7a86e98c 100644 --- a/sys/i386/i386/swtch.s +++ b/sys/i386/i386/swtch.s @@ -104,7 +104,7 @@ ENTRY(cpu_switch) jz 1f /* no, skip over */ movl %dr7,%eax /* yes, do the save */ movl %eax,PCB_DR7(%edx) - andl $0x0000ff00, %eax /* disable all watchpoints */ + andl $0x0000fc00, %eax /* disable all watchpoints */ movl %eax,%dr7 movl %dr6,%eax movl %eax,PCB_DR6(%edx) @@ -271,7 +271,13 @@ cpu_switch_load_gs: movl %eax,%dr1 movl PCB_DR0(%edx),%eax movl %eax,%dr0 - movl PCB_DR7(%edx),%eax + movl %dr7,%eax /* load dr7 so as not to disturb */ + andl $0x0000fc00,%eax /* reserved bits */ + pushl %ebx + movl PCB_DR7(%edx),%ebx + andl $~0x0000fc00,%ebx + orl %ebx,%eax + popl %ebx movl %eax,%dr7 1: ret