aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-04-15 19:19:13 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-04-15 19:19:13 +0100
commit721d48a69266bc8ce9a8595c9e4a9b74dc90149c (patch)
tree0f9b8215aa53414a587c117f5aaf73f2c592b2f0
parenta9bb1258e0f4d9d7ae00ff1130857556d8f4f470 (diff)
downloadxen-721d48a69266bc8ce9a8595c9e4a9b74dc90149c.tar.gz
xen-721d48a69266bc8ce9a8595c9e4a9b74dc90149c.tar.bz2
xen-721d48a69266bc8ce9a8595c9e4a9b74dc90149c.zip
x86_emulate: Emulate CLFLUSH instruction
We recently found that FreeBSD 8.0 guest failed to install and boot on Xen. The reason was that FreeBSD detected clflush feature and invoked this instruction to flush MMIO space. This caused a page fault; but x86_emulate.c failed to emulate this instruction (not supported). As a result, a page fault was detected inside FreeBSD. A similar issue was reported earlier. http://lists.xensource.com/archives/html/xen-devel/2010-03/msg00362.html From: Wei Huang <wei.huang2@amd.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com> xen-unstable changeset: 21189:d18e6a6c618a xen-unstable date: Thu Apr 15 18:47:58 2010 +0100
-rw-r--r--xen/arch/x86/x86_emulate/x86_emulate.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index 3449f21eab..51e199adbc 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -227,7 +227,8 @@ static uint8_t twobyte_table[256] = {
DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
/* 0xA8 - 0xAF */
ImplicitOps, ImplicitOps, 0, DstBitBase|SrcReg|ModRM,
- DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstReg|SrcMem|ModRM,
+ DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
+ ImplicitOps|ModRM, DstReg|SrcMem|ModRM,
/* 0xB0 - 0xB7 */
ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
DstReg|SrcMem|ModRM|Mov, DstBitBase|SrcReg|ModRM,
@@ -4008,6 +4009,19 @@ x86_emulate(
emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
break;
+ case 0xae: /* Grp15 */
+ switch ( modrm_reg & 7 )
+ {
+ case 7: /* clflush */
+ fail_if(ops->wbinvd == NULL);
+ if ( (rc = ops->wbinvd(ctxt)) != 0 )
+ goto done;
+ break;
+ default:
+ goto cannot_emulate;
+ }
+ break;
+
case 0xaf: /* imul */
_regs.eflags &= ~(EFLG_OF|EFLG_CF);
switch ( dst.bytes )