qemu-devel
[Top][All Lists]
Advanced

[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






reply via email to

[Prev in Thread] Current Thread [Next in Thread]