debuggers.hg

changeset 21235:d18e6a6c618a

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>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Apr 15 18:47:58 2010 +0100 (2010-04-15)
parents ffffddc4b1e0
children 7ee8bb40200a
files xen/arch/x86/x86_emulate/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate/x86_emulate.c	Thu Apr 15 17:36:55 2010 +0100
     1.2 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c	Thu Apr 15 18:47:58 2010 +0100
     1.3 @@ -227,7 +227,8 @@ static uint8_t twobyte_table[256] = {
     1.4      DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
     1.5      /* 0xA8 - 0xAF */
     1.6      ImplicitOps, ImplicitOps, 0, DstBitBase|SrcReg|ModRM,
     1.7 -    DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstReg|SrcMem|ModRM,
     1.8 +    DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
     1.9 +    ImplicitOps|ModRM, DstReg|SrcMem|ModRM,
    1.10      /* 0xB0 - 0xB7 */
    1.11      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.12      DstReg|SrcMem|ModRM|Mov, DstBitBase|SrcReg|ModRM,
    1.13 @@ -4008,6 +4009,19 @@ x86_emulate(
    1.14          emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
    1.15          break;
    1.16  
    1.17 +    case 0xae: /* Grp15 */
    1.18 +        switch ( modrm_reg & 7 )
    1.19 +        {
    1.20 +        case 7: /* clflush */
    1.21 +            fail_if(ops->wbinvd == NULL);
    1.22 +            if ( (rc = ops->wbinvd(ctxt)) != 0 )
    1.23 +                goto done;
    1.24 +            break;
    1.25 +        default:
    1.26 +            goto cannot_emulate;
    1.27 +        }
    1.28 +        break;
    1.29 +
    1.30      case 0xaf: /* imul */
    1.31          _regs.eflags &= ~(EFLG_OF|EFLG_CF);
    1.32          switch ( dst.bytes )