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

Re: [Xen-devel] RE: [Xen-changelog] Fix MOVS instruction emulation for HVM MMIO.



  Hi,

> No, the test is for if the first (current) operation is crossing a
> page boundary, not if the NEXT one is... That's why the code in this
> condition is using hvm_copy to fetch the data that is being
> accessed...

Ok, point taken.  But that also means that the access range calculation
isn't that simple, it's quite different for the two directions ...

Patch against 9681 (testing repository) attached.

cheers,

  Gerd

-- 
Gerd Hoffmann <kraxel@xxxxxxx>
Erst mal heiraten, ein, zwei Kinder, und wenn alles läuft
geh' ich nach drei Jahren mit der Familie an die Börse.
http://www.suse.de/~kraxel/julika-dora.jpeg
diff -r 42eee0575ab7 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Tue May 16 18:52:53 2006
+++ b/xen/arch/x86/hvm/platform.c       Thu May 18 14:09:36 2006
@@ -830,7 +830,7 @@
         unsigned long count = GET_REPEAT_COUNT();
         unsigned long size = mmio_inst.op_size;
         int sign = regs->eflags & EF_DF ? -1 : 1;
-        unsigned long addr = 0;
+        unsigned long addr, high_addr, low_addr;
         int dir;
 
         /* determine non-MMIO address */
@@ -851,6 +851,13 @@
                 addr = regs->edi;
             }
         }
+       if (sign > 0) {
+           high_addr = addr + count * size - 1;
+           low_addr  = addr;
+       } else {
+           high_addr = addr + size - 1;
+           low_addr  = addr - (count-1) * size;
+       }
 
         mmio_opp->flags = mmio_inst.flags;
         mmio_opp->instr = mmio_inst.instr;
@@ -865,7 +872,8 @@
          * copy ourself. After this copy succeeds, "rep movs" is executed
          * again.
          */
-        if ((addr & PAGE_MASK) != ((addr + sign * (size - 1)) & PAGE_MASK)) {
+        if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
+           /* one movs crosses page border */
             unsigned long value = 0;
 
             mmio_opp->flags |= OVERLAP;
@@ -876,15 +884,14 @@
                 hvm_copy(&value, addr, size, HVM_COPY_IN);
             send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
         } else {
-            if ((addr & PAGE_MASK) != ((addr + sign * (count * size - 1)) & 
PAGE_MASK)) {
+           if ((high_addr & PAGE_MASK) != (low_addr & PAGE_MASK)) {
+                /* $count movs will cross page border */
                 regs->eip -= inst_len; /* do not advance %eip */
-
-                if (sign > 0)
-                    count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
-                else
-                    count = (addr & ~PAGE_MASK) / size;
+               if (sign > 0)
+                   count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
+               else
+                   count = ((high_addr + size - 1) & ~PAGE_MASK) / size;
             }
-
             send_mmio_req(IOREQ_TYPE_COPY, gpa, count, size, addr, dir, 1);
         }
         break;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.