* [Qemu-devel] bug reading word straddling page boundary
@ 2008-09-04 16:34 Bruce Rogers
2008-09-04 19:19 ` Alexander Graf
2008-09-05 11:02 ` Kevin Wolf
0 siblings, 2 replies; 4+ messages in thread
From: Bruce Rogers @ 2008-09-04 16:34 UTC (permalink / raw)
To: Qemu-devel
Hi,
This bug was identified as the issue preventing NetWare from installing under qemu (kvm-73, in qemu only emulation mode.) (Hence we're talking i386 architecture here.) The high level failure occurs executing Java code, and when I debugged down to the specific issue, its when the jvm executes a word "Move with Zero-Extend instruction", where the word being accessed is in memory, and straddling a page boundary. The JVM has recently written this instruction to memory (interpreter stuff), which appears to be part of the required setup for this problem to exhibit itself. The problem is that the upper word is not fully zeroed as a result of the instruction, indeed, bits 16-23 in the result contain the byte immediately following the data to be read, while the high byte is correctly zeroed. It's interesting to note that if I change the instruction to be the sign extended version, it works correctly.
I have been able to re-create the problem with a simple program, which also exhibits the failure. I've included the code below. I've compiled it and run it on a SLES 10 SP2 vm, running under kvm version 73, but in qemu only emulation mode. And of course, the problem was found running NetWare (v6.5 SP7) vm, and I've also demonstrated it with the equvalent code below under the NetWare vm. The output from the program is 0x00003344 outside of the qemu environment, and 0x00223344 in the qemu environment.
I am not as familiar with the qemu code to identify the source of the bug myself, and so am asking for the community's help in tracking down where the problem lies. I'll continue to look.
Thanks!
- Bruce Rogers
(C source)
#include <stdio.h>
extern unsigned int ShowBug();
main()
{
unsigned int x = ShowBug();
printf("Value returned is 0x%08x\n", x);
return 0;
}
(Assembly source)
# This assembly file provides a function, ShowBug(), which reads a signature
# (which straddles a page boundary) using the movzwl (%ecx), %eax instruction.
# This instruction is dynamically written out to memory by this function, and
# then jumped to. The value we expect in %eax is 0x00003344, but due to a bug
# in qemu, the value 0x00223344 is placed there.
.data
# Our purpose here is to provide a memory region far enough away from the code
# created to not have their proximity be a factor.
DataArea:
.rept 16384
.byte 0
.endr
SelfModifiedCode:
.long
.rept 4096
.byte 0
.endr
.text
.globl ShowBug
ShowBug:
movl $DataArea, %ecx
addl $8191, %ecx
andl $0xfffff000, %ecx
# back off 1 byte from page boundary - we'll grab the word that straddles it
subl $1, %ecx
#put a signature out there
movl $0x11223344, (%ecx)
#opcodes for "movzwl (%ecx), %eax" followed by a "ret"
movl $0xc301b70f, SelfModifiedCode
movl $0, %eax
jmp SelfModifiedCode
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] bug reading word straddling page boundary
2008-09-04 16:34 [Qemu-devel] bug reading word straddling page boundary Bruce Rogers
@ 2008-09-04 19:19 ` Alexander Graf
2008-09-05 11:02 ` Kevin Wolf
1 sibling, 0 replies; 4+ messages in thread
From: Alexander Graf @ 2008-09-04 19:19 UTC (permalink / raw)
To: qemu-devel@nongnu.org; +Cc: <Qemu-devel@nongnu.org>
Am 04.09.2008 um 18:34 schrieb "Bruce Rogers" <brogers@novell.com>:
> Hi,
>
> This bug was identified as the issue preventing NetWare from
> installing under qemu (kvm-73, in qemu only emulation mode.) (Hence
> we're talking i386 architecture here.) The high level failure
> occurs executing Java code, and when I debugged down to the specific
> issue, its when the jvm executes a word "Move with Zero-Extend
> instruction", where the word being accessed is in memory, and
> straddling a page boundary. The JVM has recently written this
> instruction to memory (interpreter stuff), which appears to be part
> of the required setup for this problem to exhibit itself. The
> problem is that the upper word is not fully zeroed as a result of
> the instruction, indeed, bits 16-23 in the result contain the byte
> immediately following the data to be read, while the high byte is
> correctly zeroed. It's interesting to note that if I change the
> instruction to be the sign extended version, it works correctly.
>
> I have been able to re-create the problem with a simple program,
> which also exhibits the failure. I've included the code below.
> I've compiled it and run it on a SLES 10 SP2 vm, running under kvm
> version 73, but in qemu only emulation mode. And of course, the
> problem was found running NetWare (v6.5 SP7) vm, and I've also
> demonstrated it with the equvalent code below under the NetWare vm.
> The output from the program is 0x00003344 outside of the qemu
> environment, and 0x00223344 in the qemu environment.
>
> I am not as familiar with the qemu code to identify the source of
> the bug myself, and so am asking for the community's help in
> tracking down where the problem lies. I'll continue to look.
Wow cool, I didn't even know you were trying to get netware running on
qemu. Sounds like fun :)
To debug things further, run qemu with the -d in_asm,op,op_asm options
(iirc) that should give you the pseudo-opcodes qemu uses to generate
host code and the respective resulting assembly code.
After that it's mostly a question of finding the bad opcode in
translate.c and see if tjhe bug is in tcg (convert pseudo opcodes to
host opcodes) or the i386 translation (converting guest opcodes to
pseudo opcodes)
Good luck! As I'll be on the labs conf as of tomorrow, unfortunately i
can't help you any more than that.
Alex
>
>
> Thanks!
>
> - Bruce Rogers
>
> (C source)
> #include <stdio.h>
> extern unsigned int ShowBug();
> main()
> {
> unsigned int x = ShowBug();
> printf("Value returned is 0x%08x\n", x);
> return 0;
> }
>
> (Assembly source)
> # This assembly file provides a function, ShowBug(), which reads a
> signature
> # (which straddles a page boundary) using the movzwl (%ecx), %eax
> instruction.
> # This instruction is dynamically written out to memory by this
> function, and
> # then jumped to. The value we expect in %eax is 0x00003344, but due
> to a bug
> # in qemu, the value 0x00223344 is placed there.
>
> .data
>
> # Our purpose here is to provide a memory region far enough away
> from the code
> # created to not have their proximity be a factor.
> DataArea:
> .rept 16384
> .byte 0
> .endr
>
> SelfModifiedCode:
> .long
> .rept 4096
> .byte 0
> .endr
>
> .text
>
> .globl ShowBug
> ShowBug:
> movl $DataArea, %ecx
> addl $8191, %ecx
> andl $0xfffff000, %ecx
> # back off 1 byte from page boundary - we'll grab the word that
> straddles it
> subl $1, %ecx
> #put a signature out there
> movl $0x11223344, (%ecx)
> #opcodes for "movzwl (%ecx), %eax" followed by a "ret"
> movl $0xc301b70f, SelfModifiedCode
> movl $0, %eax
> jmp SelfModifiedCode
>
>
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] bug reading word straddling page boundary
2008-09-04 16:34 [Qemu-devel] bug reading word straddling page boundary Bruce Rogers
2008-09-04 19:19 ` Alexander Graf
@ 2008-09-05 11:02 ` Kevin Wolf
2008-09-05 16:46 ` Bruce Rogers
1 sibling, 1 reply; 4+ messages in thread
From: Kevin Wolf @ 2008-09-05 11:02 UTC (permalink / raw)
To: Bruce Rogers; +Cc: qemu-devel
Hi Bruce,
have you tried pure qemu? I can reproduce this on the qemu from my
installed KVM (which is kvm-70), but not on pure qemu. I used both SVN
HEAD and SVN Rev 5008 for the test and they both worked. The latter
should be older than the kvm-73 release, so this seems to be introduced
by KVM (or they were lucky enough to pull a bad version in between).
The "only" bad thing I noticed during my test is that the i386 userspace
emulator immediately segfaults...
Kevin
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] bug reading word straddling page boundary
2008-09-05 11:02 ` Kevin Wolf
@ 2008-09-05 16:46 ` Bruce Rogers
0 siblings, 0 replies; 4+ messages in thread
From: Bruce Rogers @ 2008-09-05 16:46 UTC (permalink / raw)
Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 879 bytes --]
Kevin,
Thanks for helping look into this. I am getting different behavior than you.
I am reproducing the bug with pure qemu as well as kvm-qemu, w/out kvm kernel modules.
With the kvm kernel modules loaded the bug is not reproducible.
This last test to verify the behavior was on OpenSuSE 11.1 alpha2, i386, non-pae.
- Bruce
>>> Kevin Wolf <kwolf@suse.de> 9/5/2008 5:02 AM >>>
Hi Bruce,
have you tried pure qemu? I can reproduce this on the qemu from my
installed KVM (which is kvm-70), but not on pure qemu. I used both SVN
HEAD and SVN Rev 5008 for the test and they both worked. The latter
should be older than the kvm-73 release, so this seems to be introduced
by KVM (or they were lucky enough to pull a bad version in between).
The "only" bad thing I noticed during my test is that the i386 userspace
emulator immediately segfaults...
Kevin
[-- Attachment #2: Type: text/html, Size: 1258 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-09-05 16:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-04 16:34 [Qemu-devel] bug reading word straddling page boundary Bruce Rogers
2008-09-04 19:19 ` Alexander Graf
2008-09-05 11:02 ` Kevin Wolf
2008-09-05 16:46 ` Bruce Rogers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).