Index: /trunk/src/VBox/Devices/PC/BIOS-new/ahci.c
===================================================================
--- /trunk/src/VBox/Devices/PC/BIOS-new/ahci.c	(revision 38850)
+++ /trunk/src/VBox/Devices/PC/BIOS-new/ahci.c	(revision 38851)
@@ -43,4 +43,11 @@
 
 #define AHCI_MAX_STORAGE_DEVICES 4
+
+/* Because we don't tell the recompiler when guest's physical memory 
+ * is written, it can incorrectly cache guest code overwritten by
+ * bus master DMA. We just re-write the memory block to flush any of
+ * its caches. This is not exactly efficient, but works!
+ */
+#define DMA_WORKAROUND      1
 
 /**
@@ -645,4 +652,5 @@
 }
 
+
 /**
  * Read data from the device.
@@ -668,4 +676,7 @@
                   u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
                   u8SectCountExp, SegData :> OffData, u16Sectors * 512, 0);
+#ifdef DMA_WORKAROUND
+    rep_movsw(SegData :> OffData, SegData :> OffData, u16Sectors * 512 / 2);
+#endif
 }
 
Index: /trunk/src/VBox/Devices/PC/BIOS-new/inlines.h
===================================================================
--- /trunk/src/VBox/Devices/PC/BIOS-new/inlines.h	(revision 38850)
+++ /trunk/src/VBox/Devices/PC/BIOS-new/inlines.h	(revision 38851)
@@ -61,4 +61,12 @@
     modify exact [] nomemory aborts;
 
+void rep_movsw(void __far *d, void __far *s, int nwords);
+#pragma aux rep_movsw =     \
+    "push   ds"             \
+    "mov    ds, dx"         \
+    "rep    movsw"          \
+    "pop    ds"             \
+    parm [es di] [dx si] [cx];
+
 char __far *rep_insb(char __far *buffer, unsigned nbytes, unsigned port);
 #pragma aux rep_insb = ".286" "rep insb" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
