From patchwork Mon Feb 15 12:48:28 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 79396 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1FCmf9u009111 for ; Mon, 15 Feb 2010 12:48:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755550Ab0BOMsf (ORCPT ); Mon, 15 Feb 2010 07:48:35 -0500 Received: from mx1.redhat.com ([209.132.183.28]:30119 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752682Ab0BOMsb (ORCPT ); Mon, 15 Feb 2010 07:48:31 -0500 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o1FCmV9k019565 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 15 Feb 2010 07:48:31 -0500 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o1FCmUni028697 for ; Mon, 15 Feb 2010 07:48:30 -0500 Received: from localhost.localdomain (file.tlv.redhat.com [10.35.255.8]) by cleopatra.tlv.redhat.com (Postfix) with ESMTP id 9841D25005B; Mon, 15 Feb 2010 14:48:29 +0200 (IST) From: Avi Kivity To: Marcelo Tosatti , kvm@vger.kernel.org Subject: [PATCH 3/4] KVM: Don't follow an atmoic operation by a non-atomic one Date: Mon, 15 Feb 2010 14:48:28 +0200 Message-Id: <1266238109-30280-4-git-send-email-avi@redhat.com> In-Reply-To: <1266238109-30280-1-git-send-email-avi@redhat.com> References: <1266238109-30280-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 15 Feb 2010 12:48:41 +0000 (UTC) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 38344be..0b1f0a0 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3215,7 +3215,8 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, static int emulator_write_emulated_onepage(unsigned long addr, const void *val, unsigned int bytes, - struct kvm_vcpu *vcpu) + struct kvm_vcpu *vcpu, + bool mmu_only) { gpa_t gpa; u32 error_code; @@ -3231,6 +3232,10 @@ static int emulator_write_emulated_onepage(unsigned long addr, if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) goto mmio; + if (mmu_only) { + kvm_mmu_pte_write(vcpu, gpa, val, bytes, 1); + return X86EMUL_CONTINUE; + } if (emulator_write_phys(vcpu, gpa, val, bytes)) return X86EMUL_CONTINUE; @@ -3251,24 +3256,35 @@ mmio: return X86EMUL_CONTINUE; } -int emulator_write_emulated(unsigned long addr, - const void *val, - unsigned int bytes, - struct kvm_vcpu *vcpu) +static int __emulator_write_emulated(unsigned long addr, + const void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu, + bool mmu_only) { /* Crossing a page boundary? */ if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { int rc, now; now = -addr & ~PAGE_MASK; - rc = emulator_write_emulated_onepage(addr, val, now, vcpu); + rc = emulator_write_emulated_onepage(addr, val, now, vcpu, + mmu_only); if (rc != X86EMUL_CONTINUE) return rc; addr += now; val += now; bytes -= now; } - return emulator_write_emulated_onepage(addr, val, bytes, vcpu); + return emulator_write_emulated_onepage(addr, val, bytes, vcpu, + mmu_only); +} + +int emulator_write_emulated(unsigned long addr, + const void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu) +{ + return __emulator_write_emulated(addr, val, bytes, vcpu, false); } EXPORT_SYMBOL_GPL(emulator_write_emulated); @@ -3332,6 +3348,8 @@ static int emulator_cmpxchg_emulated(unsigned long addr, if (!exchanged) return X86EMUL_CMPXCHG_FAILED; + return __emulator_write_emulated(addr, new, bytes, vcpu, true); + emul_write: printk_once(KERN_WARNING "kvm: emulating exchange as write\n");