[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] bug reading word straddling page boundary
From: |
Bruce Rogers |
Subject: |
[Qemu-devel] bug reading word straddling page boundary |
Date: |
Thu, 04 Sep 2008 10:34:32 -0600 |
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
- [Qemu-devel] bug reading word straddling page boundary,
Bruce Rogers <=