Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=02c03a326a5df825cc01de426f72e160db2b9538
Commit:     02c03a326a5df825cc01de426f72e160db2b9538
Parent:     74906345ff9f84f2b3b772d368c7e49f4ba27456
Author:     Luca Tettamanti <[EMAIL PROTECTED]>
AuthorDate: Tue Jun 19 22:41:20 2007 +0200
Committer:  Avi Kivity <[EMAIL PROTECTED]>
CommitDate: Mon Jul 16 12:05:48 2007 +0300

    KVM: Fix x86 emulator writeback
    
    When the old value and new one are the same the emulator skips the
    write; this is undesirable 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 <[EMAIL PROTECTED]>
    Signed-off-by: Avi Kivity <[EMAIL PROTECTED]>
---
 drivers/kvm/x86_emulate.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 92620e4..f60012d 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -485,6 +485,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];
@@ -1051,7 +1052,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;
                        break;
                default:
                        goto cannot_emulate;
@@ -1060,7 +1061,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. */
@@ -1168,7 +1169,7 @@ pop_instruction:
                        goto done;
 
                register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
-               dst.orig_val = dst.val; /* Disable writeback. */
+               no_wb = 1; /* Disable writeback. */
                break;
        }
        goto writeback;
@@ -1323,7 +1324,7 @@ twobyte_insn:
 
 twobyte_special_insn:
        /* Disable writeback. */
-       dst.orig_val = dst.val;
+       no_wb = 1;
        switch (b) {
        case 0x09:              /* wbinvd */
                break;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to