From mboxrd@z Thu Jan 1 00:00:00 1970 From: Aurelien Jarno Subject: [PATCH] KVM: Access registers for instructions with ModR/M byte and Mod = 3 Date: Wed, 17 Oct 2007 19:30:41 +0200 Message-ID: <20071017173041.GA8545@hall.aurel32.net> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Return-path: Content-Disposition: inline List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org On Wed, Oct 17, 2007 at 06:23:41PM +0200, Aurelien Jarno wrote: > >> The 0F 01 instruction is then correctly emulated, but another of this > > Oops s/0F 01/invlpg/ > >> group is probably not, as the patch clearly fix the problem on AMD. > > > > I confirm the problem. SVM does not virtualize smsw and lmsw that have > to be emulated. And it looks like the decoding or/and emulation of those > instructions is currently broken in KVM. > Ok, next try. This time I have opened the IA32 manual (I should have done that before), so I hope it is correct. KVM: Access registers for instructions with ModR/M byte and Mod = 3 The patch belows changes the access type to register from memory for instructions that are declared as SrcMem or DstMem, but have a ModR/M byte with Mod = 3. It fixes (at least) the lmsw and smsw instructions on an AMD64 CPU, which are needed for FreeBSD. Signed-off-by: Aurelien Jarno diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index e974ace..005e57c 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c @@ -831,6 +831,12 @@ modrm_done: if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7) break; + /* For instructions with a ModR/M byte, switch to register + access if Mod = 3. */ + if ((c->d & ModRM) && c->modrm_mod == 3) { + c->src.type = OP_REG; + break; + } srcmem_common: c->src.type = OP_MEM; break; @@ -893,7 +899,12 @@ srcmem_common: } break; case DstMem: - c->dst.type = OP_MEM; + /* For instructions with a ModR/M byte, switch to register + access if Mod = 3. */ + if ((c->d & ModRM) && c->modrm_mod == 3) + c->dst.type = OP_REG; + else + c->dst.type = OP_MEM; break; } -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' aurel32-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org | aurelien-rXXEIb44qovR7s880joybQ@public.gmane.org `- people.debian.org/~aurel32 | www.aurel32.net ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/