qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] page fault during ins
@ 2004-12-13 14:52 Piotras
  2004-12-14 21:40 ` Fabrice Bellard
  0 siblings, 1 reply; 9+ messages in thread
From: Piotras @ 2004-12-13 14:52 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 566 bytes --]

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

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: test-ide.c --]
[-- Type: text/x-csrc; name="test-ide.c", Size: 919 bytes --]

#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');
    }
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
  2004-12-13 14:52 Piotras
@ 2004-12-14 21:40 ` Fabrice Bellard
  2004-12-14 22:29   ` malc
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Fabrice Bellard @ 2004-12-14 21:40 UTC (permalink / raw)
  To: Piotras, qemu-devel

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
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
  2004-12-14 21:40 ` Fabrice Bellard
@ 2004-12-14 22:29   ` malc
  2004-12-15  8:17   ` Piotras
  2004-12-15  8:22   ` Piotras
  2 siblings, 0 replies; 9+ messages in thread
From: malc @ 2004-12-14 22:29 UTC (permalink / raw)
  To: qemu-devel

On Tue, 14 Dec 2004, Fabrice Bellard wrote:

> 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...
>

Interp does it right (if my memory serves me), so this can always be
checked with it.

-- 
mailto:malc@pulsesoft.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
  2004-12-14 21:40 ` Fabrice Bellard
  2004-12-14 22:29   ` malc
@ 2004-12-15  8:17   ` Piotras
  2004-12-17  0:07     ` Mark Williamson
  2004-12-23  8:45     ` Benjamin Herrenschmidt
  2004-12-15  8:22   ` Piotras
  2 siblings, 2 replies; 9+ messages in thread
From: Piotras @ 2004-12-15  8:17 UTC (permalink / raw)
  To: Fabrice Bellard, qemu-devel

Do we have any device where iomem read changes device state? 
Wouldn't such hardware cause problems with speculative execution 
(memory reads) on some real CPUs? Or am I missing something?


Piotrek


On Tue, 14 Dec 2004 22:40:15 +0100, Fabrice Bellard <fabrice@bellard.org> wrote:
> 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.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
  2004-12-14 21:40 ` Fabrice Bellard
  2004-12-14 22:29   ` malc
  2004-12-15  8:17   ` Piotras
@ 2004-12-15  8:22   ` Piotras
  2 siblings, 0 replies; 9+ messages in thread
From: Piotras @ 2004-12-15  8:22 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 387 bytes --]

Hi!

Maybe someone who experiences the problem could check the attached 
patch? The patch is not really correct, but chances are it could help.


Regards,

Piotrek

On Tue, 14 Dec 2004 22:40:15 +0100, Fabrice Bellard <fabrice@bellard.org> wrote:
> 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.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: wnt.patch --]
[-- Type: text/x-patch; name="wnt.patch", Size: 675 bytes --]

diff -ru qemu-0.6.1/target-i386/translate.c qemu-0.6.1-A-prepare/target-i386/translate.c
--- qemu-0.6.1/target-i386/translate.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-0.6.1-A-prepare/target-i386/translate.c	2004-12-14 17:32:29.000000000 +0100
@@ -874,8 +874,10 @@
 
 static inline void gen_ins(DisasContext *s, int ot)
 {
-    gen_op_in_DX_T0[ot]();
     gen_string_movl_A0_EDI(s);
+    /* XXX: this is not correct, find another solution to avoid side-effect on restart (mmu fault) */
+    gen_op_st_T0_A0[ot + s->mem_index]();
+    gen_op_in_DX_T0[ot]();
     gen_op_st_T0_A0[ot + s->mem_index]();
     gen_op_movl_T0_Dshift[ot]();
     if (s->aflag) {

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
@ 2004-12-15 18:36 Juergen Keil
  2004-12-15 20:07 ` Piotras
  0 siblings, 1 reply; 9+ messages in thread
From: Juergen Keil @ 2004-12-15 18:36 UTC (permalink / raw)
  To: qemu-devel

> Maybe someone who experiences the problem could check the attached 
> patch? The patch is not really correct, but chances are it could help.

> diff -ru qemu-0.6.1/target-i386/translate.c
> qemu-0.6.1-A-prepare/target-i386/translate.c
> --- qemu-0.6.1/target-i386/translate.c	2004-11-14 21:51:33.000000000 +0100
> +++ qemu-0.6.1-A-prepare/target-i386/translate.c	2004-12-14 17:32:29.000000000 +0100
> @@ -874,8 +874,10 @@
>  
>  static inline void gen_ins(DisasContext *s, int ot)
>  {
> -    gen_op_in_DX_T0[ot]();
>      gen_string_movl_A0_EDI(s);
> +    /* XXX: this is not correct, find another solution to avoid side-effect on restart (mmu fault) */
> +    gen_op_st_T0_A0[ot + s->mem_index]();
> +    gen_op_in_DX_T0[ot]();
>      gen_op_st_T0_A0[ot + s->mem_index]();
>      gen_op_movl_T0_Dshift[ot]();
>      if (s->aflag) {


I seems this patch doesn't help.  I just tried a W2K install on a 1G
qemu qcow HDD (host OS: Solaris x86), and got the "disk full" problem.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
  2004-12-15 18:36 [Qemu-devel] page fault during ins Juergen Keil
@ 2004-12-15 20:07 ` Piotras
  0 siblings, 0 replies; 9+ messages in thread
From: Piotras @ 2004-12-15 20:07 UTC (permalink / raw)
  To: Juergen Keil, qemu-devel

Leo Whitman confirmed your results.

No luck this time;-(


Regards,

Piotrek

On Wed, 15 Dec 2004 19:36:46 +0100 (CET), Juergen Keil <jk@tools.de> wrote:
> > Maybe someone who experiences the problem could check the attached
> > patch? The patch is not really correct, but chances are it could help.
> 
> > diff -ru qemu-0.6.1/target-i386/translate.c
> > qemu-0.6.1-A-prepare/target-i386/translate.c
> > --- qemu-0.6.1/target-i386/translate.c        2004-11-14 21:51:33.000000000 +0100
> > +++ qemu-0.6.1-A-prepare/target-i386/translate.c      2004-12-14 17:32:29.000000000 +0100
> > @@ -874,8 +874,10 @@
> >
> >  static inline void gen_ins(DisasContext *s, int ot)
> >  {
> > -    gen_op_in_DX_T0[ot]();
> >      gen_string_movl_A0_EDI(s);
> > +    /* XXX: this is not correct, find another solution to avoid side-effect on restart (mmu fault) */
> > +    gen_op_st_T0_A0[ot + s->mem_index]();
> > +    gen_op_in_DX_T0[ot]();
> >      gen_op_st_T0_A0[ot + s->mem_index]();
> >      gen_op_movl_T0_Dshift[ot]();
> >      if (s->aflag) {
> 
> I seems this patch doesn't help.  I just tried a W2K install on a 1G
> qemu qcow HDD (host OS: Solaris x86), and got the "disk full" problem.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
  2004-12-15  8:17   ` Piotras
@ 2004-12-17  0:07     ` Mark Williamson
  2004-12-23  8:45     ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 9+ messages in thread
From: Mark Williamson @ 2004-12-17  0:07 UTC (permalink / raw)
  To: qemu-devel

> Do we have any device where iomem read changes device state?

It seems like a plausible thing to do, despite seemingly slightly strange 
semantically.

> Wouldn't such hardware cause problems with speculative execution
> (memory reads) on some real CPUs? Or am I missing something?

IO memory regions would have a flag(s) set in the relevant page tables telling 
the CPU that it's not real memory.  This flag would be set by the operating 
system.

This allows the CPU to maintain correct semantics for such devices (not 
reordering writes, not caching reads, etc), whilst still being able to 
optimise accesses to physical RAM aggressively.

Cheers,
Mark

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] page fault during ins
  2004-12-15  8:17   ` Piotras
  2004-12-17  0:07     ` Mark Williamson
@ 2004-12-23  8:45     ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2004-12-23  8:45 UTC (permalink / raw)
  To: Piotras, qemu-devel

On Wed, 2004-12-15 at 09:17 +0100, Piotras wrote:
> Do we have any device where iomem read changes device state? 
> Wouldn't such hardware cause problems with speculative execution 
> (memory reads) on some real CPUs? Or am I missing something?

This is still quit common unfortunately...

On archs like ppc, this is why IO space is marked "Guarded" to prevent
speculation.

Ben.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-12-23  9:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-15 18:36 [Qemu-devel] page fault during ins Juergen Keil
2004-12-15 20:07 ` Piotras
  -- strict thread matches above, loose matches on Subject: below --
2004-12-13 14:52 Piotras
2004-12-14 21:40 ` Fabrice Bellard
2004-12-14 22:29   ` malc
2004-12-15  8:17   ` Piotras
2004-12-17  0:07     ` Mark Williamson
2004-12-23  8:45     ` Benjamin Herrenschmidt
2004-12-15  8:22   ` Piotras

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).