Subject: port-i386/19724: page fault trap in i386_set_ldt()
To: None <gnats-bugs@gnats.netbsd.org>
From: None <stephenm@employees.org>
List: netbsd-bugs
Date: 01/07/2003 05:15:26
>Number: 19724
>Category: port-i386
>Synopsis: page fault trap in i386_set_ldt()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-i386-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jan 07 06:32:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator: Stephen Ma
>Release: NetBSD 1.6L 2003-01-04
>Organization:
People's Front for the correct spelling of the word "Organisation"
>Environment:
System: NetBSD whitewater.local 1.6L NetBSD 1.6L (WHITEWATER) #56: Sun Jan 5 22:02:22 PST 2003 root@whitewater.local:/v1/netbsd/obj/src/sys/arch/i386/compile/WHITEWATER i386
Architecture: i386
Machine: i386
>Description:
The kernel can crash in memcpy(), called from i386_set_ldt() when running wine.
I can only get this crash to occur when running the Windows Real Player 8 Basic
under wine-20021125nb1, although I've not tested many windows programs.
DDB traceback etc follows:
kernel: page fault trap, code=0
Stopped in pid 320 (wine) at memcpy+0x1e: repe movsl (%esi),%es:(%edi)
db> trace
memcpy(cae21b4c,48632af0,cae78f78,0,cae78f80) at memcpy+0x1e
sys_sysarch(cae21b4c,cae78f80,cae78f78,cae21b4c,0) at sys_sysarch+0x75
syscall_plain(1f,4863008f,4863001f,4863001f,1007) at syscall_plain+0xa7
db> show registers
ds 0x10
es 0x10
fs 0x30
gs 0x10
edi 0xcaf35000 end+0xac33b58
esi 0xcae71000 end+0xab6fb58
ebp 0xcae78f10 end+0xab77a68
ebx 0x1000
edx 0x1000
ecx 0x400
eax 0xcaf35000 end+0xac33b58
eip 0xc027b1ba memcpy+0x1e
cs 0x8
eflags 0x10206
esp 0xcae78ebc end+0xab77a14
ss 0x10
memcpy+0x1e: repe movsl (%esi),%es:(%edi)
db> show object 0xcaf35000
OBJECT 0xcaf35000: locked=808202288, pgops=0x30302c30, npages=807411722, refs=87
5572281
db> show object 0xcae71000
kernel: page fault trap, code=0
Faulted in DDB; continuing...
>How-To-Repeat:
Run Windows Real Player 8 Basic under wine-20021125nb1. The crash seems to
happen after about 2-3 minutes of audio playback.
>Fix:
Looks like there's a bogus call to uvm_km_free() in i386_set_idt().
sys/arch/i386/i386/sys_machdep.c:
$NetBSD: sys_machdep.c,v 1.66 2002/10/08 20:23:27 fvdl Exp $
--- sys_machdep.c.~1.66.~ Wed Oct 9 03:03:44 2002
+++ sys_machdep.c Sun Jan 5 21:45:41 2003
@@ -197,7 +197,7 @@ i386_set_ldt(p, args, retval)
goto out;
/* Check descriptors for access violations. */
- for (i = 0, n = ua.start; i < ua.num; i++, n++) {
+ for (i = 0; i < ua.num; i++) {
union descriptor *desc = &descv[i];
switch (desc->sd.sd_type) {
@@ -267,8 +267,7 @@ i386_set_ldt(p, args, retval)
/* allocate user ldt */
simple_lock(&pmap->pm_lock);
- if (pmap->pm_ldt == 0 || (ua.start + ua.num) > pmap->pm_ldt_len) {
- old_ldt = pmap->pm_ldt;
+ if (pmap->pm_ldt == NULL || (ua.start + ua.num) > pmap->pm_ldt_len) {
if (pmap->pm_flags & PMF_USER_LDT)
ldt_len = pmap->pm_ldt_len;
else
@@ -299,7 +298,6 @@ i386_set_ldt(p, args, retval)
if (old_ldt != NULL) {
old_len = pmap->pm_ldt_len * sizeof(union descriptor);
- uvm_km_free(kernel_map, (vaddr_t)old_ldt, old_len);
} else {
old_len = NLDT * sizeof(union descriptor);
old_ldt = ldt;
>Release-Note:
>Audit-Trail:
>Unformatted: