NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-i386/46338: memcpy/memmove/bcopy kernel panics when hitting page boundary on i386



>Number:         46338
>Category:       port-i386
>Synopsis:       memcpy/memmove/bcopy kernel panics when hitting page boundary 
>on i386
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 16 07:10:00 +0000 2012
>Originator:     Nat Sloss
>Release:        NetBSD Current 6.99.4
>Organization:
>Environment:
NetBSD beast 6.99.4 NetBSD 6.99.4 (LOCKDEBUG) #81: Mon Apr 16 12:31:11 EST 2012 
 build@beast:/home/build/src/sys/arch/i386/compile/obj/LOCKDEBUG i386
>Description:
Hi I've experienced kernel crashes with iosynchronous usb transfers and this 
problem could be the cause of kern/38432.

Occasionally the kernel will panic trap type 6 code 0 or code 2 in memcpy+0x14 
repe movsl "registers".

I have discovered that the source file memcpy.S doesn't handle page boundaries 
as the error code 0 is read error, page not loaded supervisor access, and code 
2 for write.

The kernel panics whenever an address is accessed on a page boundary because of 
the use of MOVS.

This type of panic will occur when either the source address or destination 
address + copy length crosses a page boundary.

>How-To-Repeat:
This problem will occur when ever source address + copy length is greater than 
65536 or destination address + copy length is greater than 65536.

ie memcpy( 0xXXXXFFF0, 0xXXXXFFEF, 0x30);

It effects all drivers using memcpy although I notice it consistently with usb 
and in particular audio.

Could you please pull up NetBSD 5 and 6 when a solution is found.

And just a question will I have to recompile all binaries on my system or just 
the kernel.
>Fix:
Memcopy should copy to in page size segments due to the use of movs.

copy:
if dist + length > 0xFFFF then
        copy_length = 0xFFFF - dist

if src + copy_length > 0xFFFF then
        copy_length = 0xFFFF - src

cx register = copy_length
length -= copy_length
rep
movsl

if length > 0 then
        goto copy




Home | Main Index | Thread Index | Old Index