From patchwork Wed Apr 20 13:33:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 721871 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3KDXU6V029934 for ; Wed, 20 Apr 2011 13:33:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753324Ab1DTNd0 (ORCPT ); Wed, 20 Apr 2011 09:33:26 -0400 Received: from va3ehsobe006.messaging.microsoft.com ([216.32.180.16]:47917 "EHLO VA3EHSOBE009.bigfish.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752787Ab1DTNdZ (ORCPT ); Wed, 20 Apr 2011 09:33:25 -0400 Received: from mail52-va3-R.bigfish.com (10.7.14.245) by VA3EHSOBE009.bigfish.com (10.7.40.29) with Microsoft SMTP Server id 14.1.225.8; Wed, 20 Apr 2011 13:33:24 +0000 Received: from mail52-va3 (localhost.localdomain [127.0.0.1]) by mail52-va3-R.bigfish.com (Postfix) with ESMTP id 1015B190062D; Wed, 20 Apr 2011 13:33:24 +0000 (UTC) X-SpamScore: -31 X-BigFish: VPS-31(zzbb2dKbb2cK9371O1432N98dKzz1202hzz15d4R8275bh8275dhz32i668h839h62h) X-Spam-TCS-SCL: 1:0 X-Forefront-Antispam-Report: KIP:(null); UIP:(null); IPVD:NLI; H:ausb3twp02.amd.com; RD:none; EFVD:NLI Received: from mail52-va3 (localhost.localdomain [127.0.0.1]) by mail52-va3 (MessageSwitch) id 1303306403830874_6919; Wed, 20 Apr 2011 13:33:23 +0000 (UTC) Received: from VA3EHSMHS024.bigfish.com (unknown [10.7.14.240]) by mail52-va3.bigfish.com (Postfix) with ESMTP id B6BDA125804F; Wed, 20 Apr 2011 13:33:23 +0000 (UTC) Received: from ausb3twp02.amd.com (163.181.249.109) by VA3EHSMHS024.bigfish.com (10.7.99.34) with Microsoft SMTP Server id 14.1.225.8; Wed, 20 Apr 2011 13:33:22 +0000 X-WSS-ID: 0LJYDNI-02-B7N-02 X-M-MSG: Received: from sausexedgep02.amd.com (sausexedgep02-ext.amd.com [163.181.249.73]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by ausb3twp02.amd.com (Axway MailGate 3.8.1) with ESMTP id 212C5FCC29D; Wed, 20 Apr 2011 08:33:17 -0500 (CDT) Received: from sausexhtp02.amd.com (163.181.3.152) by sausexedgep02.amd.com (163.181.36.59) with Microsoft SMTP Server (TLS) id 8.3.106.1; Wed, 20 Apr 2011 08:33:27 -0500 Received: from storexhtp02.amd.com (172.24.4.4) by sausexhtp02.amd.com (163.181.3.152) with Microsoft SMTP Server (TLS) id 8.3.83.0; Wed, 20 Apr 2011 08:33:19 -0500 Received: from gwo.osrc.amd.com (165.204.16.204) by storexhtp02.amd.com (172.24.4.4) with Microsoft SMTP Server id 8.3.83.0; Wed, 20 Apr 2011 09:33:17 -0400 Received: from lemmy.osrc.amd.com (lemmy.osrc.amd.com [165.204.15.93]) by gwo.osrc.amd.com (Postfix) with ESMTP id 96E6349C1FB; Wed, 20 Apr 2011 14:33:16 +0100 (BST) Received: by lemmy.osrc.amd.com (Postfix, from userid 1000) id 6F4AFFF8AA; Wed, 20 Apr 2011 15:33:16 +0200 (CEST) Date: Wed, 20 Apr 2011 15:33:16 +0200 From: "Roedel, Joerg" To: Avi Kivity CC: Takuya Yoshikawa , "mtosatti@redhat.com" , "kvm@vger.kernel.org" , "yoshikawa.takuya@oss.ntt.co.jp" Subject: [PATCH] KVM: MMU: Make cmpxchg_gpte aware of nesting too Message-ID: <20110420133316.GA2192@amd.com> References: <20110419033220.e527bcae.takuya.yoshikawa@gmail.com> <20110419033453.ffa856c9.takuya.yoshikawa@gmail.com> <4DAEA240.9020104@redhat.com> <20110420093515.GX2192@amd.com> <4DAEAFD4.1050609@redhat.com> <20110420110630.GZ2192@amd.com> <4DAEC0F4.70201@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4DAEC0F4.70201@redhat.com> User-Agent: Mutt/1.5.20 (2009-06-14) X-OriginatorOrg: amd.com 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.6 (demeter1.kernel.org [140.211.167.41]); Wed, 20 Apr 2011 13:34:27 +0000 (UTC) On Wed, Apr 20, 2011 at 07:18:12AM -0400, Avi Kivity wrote: > On 04/20/2011 02:06 PM, Roedel, Joerg wrote: > > The cmpxchg_gpte function treats all table_gfns as l1-gfns. I'll send a > > fix soon. > > Thanks. Here is a fix for review. I am out-of-office starting in nearly one hour until next Tuesday. So the corrections will most likely not happen before :) The patch ist tested with npt and shadow paging as well as with npt-on-npt (64 bit wit kvm). Regards, Joerg From 6b1dcd9f17bbd482061180001d1f45c3adcef430 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 20 Apr 2011 15:22:21 +0200 Subject: [PATCH] KVM: MMU: Make cmpxchg_gpte aware of nesting too This patch makes the cmpxchg_gpte() function aware of the difference between l1-gfns and l2-gfns when nested virtualization is in use. This fixes a potential data-corruption problem in the l1-guest and makes the code work correct (at least as correct as the hardware which is emulated in this code) again. Cc: stable@kernel.org Signed-off-by: Joerg Roedel --- arch/x86/kvm/paging_tmpl.h | 30 +++++++++++++++++++++++------- 1 files changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 74f8567..e442bf4 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -78,15 +78,21 @@ static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl) return (gpte & PT_LVL_ADDR_MASK(lvl)) >> PAGE_SHIFT; } -static bool FNAME(cmpxchg_gpte)(struct kvm *kvm, +static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gfn_t table_gfn, unsigned index, pt_element_t orig_pte, pt_element_t new_pte) { pt_element_t ret; pt_element_t *table; struct page *page; + gpa_t gpa; - page = gfn_to_page(kvm, table_gfn); + gpa = mmu->translate_gpa(vcpu, table_gfn << PAGE_SHIFT, + PFERR_USER_MASK|PFERR_WRITE_MASK); + if (gpa == UNMAPPED_GVA) + return -EFAULT; + + page = gfn_to_page(vcpu->kvm, gpa_to_gfn(gpa)); table = kmap_atomic(page, KM_USER0); ret = CMPXCHG(&table[index], orig_pte, new_pte); @@ -192,11 +198,17 @@ walk: #endif if (!eperm && !rsvd_fault && !(pte & PT_ACCESSED_MASK)) { + int ret; trace_kvm_mmu_set_accessed_bit(table_gfn, index, sizeof(pte)); - if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, - index, pte, pte|PT_ACCESSED_MASK)) + ret = FNAME(cmpxchg_gpte)(vcpu, mmu, table_gfn, + index, pte, pte|PT_ACCESSED_MASK); + if (ret < 0) { + present = false; + break; + } else if (ret) goto walk; + mark_page_dirty(vcpu->kvm, table_gfn); pte |= PT_ACCESSED_MASK; } @@ -245,13 +257,17 @@ walk: goto error; if (write_fault && !is_dirty_gpte(pte)) { - bool ret; + int ret; trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte)); - ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte, + ret = FNAME(cmpxchg_gpte)(vcpu, mmu, table_gfn, index, pte, pte|PT_DIRTY_MASK); - if (ret) + if (ret < 0) { + present = false; + goto error; + } if (ret) goto walk; + mark_page_dirty(vcpu->kvm, table_gfn); pte |= PT_DIRTY_MASK; walker->ptes[walker->level - 1] = pte;