qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] page fault during ins


From: Fabrice Bellard
Subject: Re: [Qemu-devel] page fault during ins
Date: Tue, 14 Dec 2004 22:40:15 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20040913

Very interesting remark. If it explains a bug in one OS (for example the win 2000 disk full issue !), then it will become high priority.

Another issue could be problems with 'movsw': the CPU could verify that it can write before doing the read to avoid restarting problems when talking to memory mapped devices...

Fabrice.

Piotras wrote:
Hi!

The current implementation of ins (Input from Port to String) is not-restartable. If page fault occurs during write, the port read is redone and for some devices this may give unexpected results.

This is different from what real CPU does. From my tests with Pentium II it seems that the CPU first makes sure that data can be written, and then issue IO read. I'm attaching my test program -- it may do harm to your system, so be very careful. The test assumes that there is a CDROM connected as master to second IDE controller (hdc).


Regards,

Piotrek


------------------------------------------------------------------------

#include <sys/io.h>
#include <sys/mman.h>
#include <signal.h>
#include <stdio.h>
#include <stdint.h>


uint16_t *data;

void segv()
{
    printf("SEGV\n");
    data = mmap(data, 4096, PROT_READ | PROT_WRITE,
                MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
    if (data == MAP_FAILED) {
        exit(1);
    }
}

int main()
{
    int i;
    unsigned char v;
data = mmap(0, 4096, PROT_NONE,
                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (data == MAP_FAILED) {
        exit(1);
    }
    signal(SIGSEGV, segv);

    iopl(3);

    do {
        v = inb(0x0177);
    } while ((v & 0xc0) != 0x40);
    outb(0x00, 0x0176);
    outb(0xa1, 0x0177);
    do {
        v = inb(0x0177);
    } while ((v & 0x08) != 0x08);
    insw(0x0170, data, 256);
    for(i = 0; i < 256; ++ i) {
        printf("%04x%c", data[i], (i % 8 != 7)? ' ': '\n');
    }
}


------------------------------------------------------------------------

_______________________________________________
Qemu-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/qemu-devel





reply via email to

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