From patchwork Tue Apr 9 23:46:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Borislav Petkov X-Patchwork-Id: 2418451 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 17519DF25A for ; Tue, 9 Apr 2013 23:46:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935267Ab3DIXqU (ORCPT ); Tue, 9 Apr 2013 19:46:20 -0400 Received: from mail.skyhub.de ([78.46.96.112]:34558 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934828Ab3DIXqT (ORCPT ); Tue, 9 Apr 2013 19:46:19 -0400 X-Virus-Scanned: Nedap ESD1 at mail.skyhub.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alien8.de; s=alien8; t=1365551178; bh=q+muRtHD99pqENpg+hM97fOYQzM8QC0RJ08Jq0s0dYE=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Transfer-Encoding; b=gQPtE2xfidyYZCRD8uODvylQYnHLvLs569h5H 0uFE3wAA/OIm5v9oTH/I+lgWJV4aLyTckuNiu1jrS92T3ZbmfGqK1SJ2vADeAuZWwLc ajsywCo8Whsvia/1zSWZU2V667OojDWRkD5lxd0qy+5aSi0ZubQDGmZiDPqPS7SoJ5g = Received: from mail.skyhub.de ([127.0.0.1]) by localhost (door.skyhub.de [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id W-0CGUIBaGNb; Wed, 10 Apr 2013 01:46:18 +0200 (CEST) Received: from liondog.tnic (p54B7EAC2.dip.t-dialin.net [84.183.234.194]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.skyhub.de (SuperMail on ZX Spectrum 128k) with ESMTPSA id 4A9641D9C12; Wed, 10 Apr 2013 01:46:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alien8.de; s=alien8; t=1365551163; bh=q+muRtHD99pqENpg+hM97fOYQzM8QC0RJ08Jq0s0dYE=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Transfer-Encoding; b=jhalVPeKD/RHjUTKA7D+aasvkNfis89dDdOys e57eCQCmjGkwxRmszzgmcZYO7cc2H2/Fa09qwvSRtBjhYGmucxiqAnbM3CWtcWuA6PT xXlBwo+pvEsF35L1dHk32LfQrRgS5aVD2MMonaGmhNGYaCVJNTpFBME9VW3WztiT2IU = Received: by liondog.tnic (Postfix, from userid 1000) id 76B1F10077B; Wed, 10 Apr 2013 01:46:02 +0200 (CEST) Date: Wed, 10 Apr 2013 01:46:02 +0200 From: Borislav Petkov To: kvm@vger.kernel.org Cc: Andre Przywara , =?utf-8?B?SsO2cmcgUsO2ZGVs?= , "H. Peter Anvin" , x86-ml Subject: [RFC PATCH] Emulate MOVBE Message-ID: <20130409234602.GI5077@pd.tnic> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Hi guys, so I was trying to repro tglx's bug in smpboot.c and for some reason, the most reliable way to trigger it was to boot an 32-bit atom smp guest in kvm (don't ask :)). The problem, however, was that atom wants MOVBE and qemu doesn't emulate it yet (except Richard's patches which I used in order to be able to actually even boot a guest). However, without hw acceleration, qemu is pretty slow, and waiting for an smp guest to boot in sw-only emulation is not fun. So, just for funsies, I decided to give the MOVBE emulation a try. Patch is below, 8 core smp atom guest boots fine and in 6-ish seconds with it. :-) I know, I know, it still needs cleaning up and proper rFLAGS handling but that is for later. For now, I'd very much like to hear whether this approach even makes sense and if so, what should be improved. Thanks, and thanks to Andre and Jörg for their help. Not-yet-signed-off-by: Borislav Petkov diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 15f960c06ff7..ae01c765cd77 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -281,6 +281,7 @@ struct x86_emulate_ctxt { /* decode cache */ u8 twobyte; + u8 thirdbyte; u8 b; u8 intercept; u8 lock_prefix; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a335cc6cde72..0ccff339359d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -152,6 +152,7 @@ #define Avx ((u64)1 << 43) /* Advanced Vector Extensions */ #define Fastop ((u64)1 << 44) /* Use opcode::u.fastop */ #define NoWrite ((u64)1 << 45) /* No writeback */ +#define ThreeByte ((u64)1 << 46) /* Three byte opcodes 0F 38 and 0F 3A */ #define X2(x...) x, x #define X3(x...) X2(x), x @@ -3107,6 +3108,34 @@ static int em_mov(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } +static int em_movbe(struct x86_emulate_ctxt *ctxt) +{ + char *valptr = ctxt->src.valptr; + + switch (ctxt->op_bytes) { + case 2: + *(u16 *)valptr = swab16(*(u16 *)valptr); + break; + case 4: + *(u32 *)valptr = swab32(*(u32 *)valptr); + + /* + * clear upper dword for 32-bit operand size in 64-bit mode. + */ + if (ctxt->mode == X86EMUL_MODE_PROT64) + *((u32 *)valptr + 1) = 0x0; + break; + case 8: + *(u64 *)valptr = swab64(*(u64 *)valptr); + break; + default: + return X86EMUL_PROPAGATE_FAULT; + } + + memcpy(ctxt->dst.valptr, ctxt->src.valptr, ctxt->op_bytes); + return X86EMUL_CONTINUE; +} + static int em_cr_write(struct x86_emulate_ctxt *ctxt) { if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) @@ -3974,7 +4003,8 @@ static const struct opcode twobyte_table[256] = { I(ImplicitOps | VendorSpecific, em_sysenter), I(ImplicitOps | Priv | VendorSpecific, em_sysexit), N, N, - N, N, N, N, N, N, N, N, + I(ModRM | Mov | ThreeByte | VendorSpecific, em_movbe), + N, N, N, N, N, N, N, /* 0x40 - 0x4F */ X16(D(DstReg | SrcMem | ModRM | Mov)), /* 0x50 - 0x5F */ @@ -4323,6 +4353,15 @@ done_prefixes: } ctxt->d = opcode.flags; + if (ctxt->d & ThreeByte) { + ctxt->thirdbyte = insn_fetch(u8, ctxt); + + if (ctxt->thirdbyte == 0xf0) + ctxt->d |= DstReg | SrcMem; + else + ctxt->d |= DstMem | SrcReg; + } + if (ctxt->d & ModRM) ctxt->modrm = insn_fetch(u8, ctxt);