[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20070619204120.GA18800@dreamland.darkstar.lan>
Date: Tue, 19 Jun 2007 22:41:20 +0200
From: Luca Tettamanti <kronos.it@...il.com>
To: kvm-devel@...ts.sourceforge.net
Cc: Avi Kivity <avi@...ranet.com>, linux-kernel@...r.kernel.org
Subject: [PATCH 1/2] kvm: Fix x86 emulator writeback
When the old value and new one are the same the emulator skips the
write; this is undesiderable when the destination is a MMIO area and the
write shall be performed regardless of the previous value. This
optimization breaks e.g. a Linux guest APIC compiled without
X86_GOOD_APIC.
Remove the check and perform the writeback stage in the emulation unless
it's explicitly disabled (currently push and some 2 bytes instructions
may disable the writeback).
Signed-Off-By: Luca Tettamanti <kronos.it@...il.com>
---
Tested with Fedora7, Solaris10 and WinXP on a 32 bit host with Intel
CPU.
drivers/kvm/x86_emulate.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index a4a8481..eb10448 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -482,6 +482,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
int mode = ctxt->mode;
unsigned long modrm_ea;
int use_modrm_ea, index_reg = 0, base_reg = 0, scale, rip_relative = 0;
+ int no_wb = 0;
/* Shadow copy of register state. Committed on successful emulation. */
unsigned long _regs[NR_VCPU_REGS];
@@ -1048,7 +1049,7 @@ done_prefixes:
_regs[VCPU_REGS_RSP]),
&dst.val, dst.bytes, ctxt)) != 0)
goto done;
- dst.val = dst.orig_val; /* skanky: disable writeback */
+ no_wb = 1; /* skanky: disable writeback */
break;
default:
goto cannot_emulate;
@@ -1057,7 +1058,7 @@ done_prefixes:
}
writeback:
- if ((d & Mov) || (dst.orig_val != dst.val)) {
+ if (!no_wb) {
switch (dst.type) {
case OP_REG:
/* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
@@ -1306,7 +1307,7 @@ twobyte_insn:
twobyte_special_insn:
/* Disable writeback. */
- dst.orig_val = dst.val;
+ no_wb = 1;
switch (b) {
case 0x09: /* wbinvd */
break;
Luca
--
Colui che sorride quando le cose vanno male ha pensato a qualcuno a cui
dare la colpa.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists