From mboxrd@z Thu Jan 1 00:00:00 1970 From: Avi Kivity Subject: Re: missing kvm smp tlb flush in invlpg Date: Sun, 15 Mar 2009 12:35:48 +0200 Message-ID: <49BCDA04.1020602@redhat.com> References: <20090312171843.GU27823@random.random> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org, Marcelo Tosatti To: Andrea Arcangeli Return-path: Received: from mx2.redhat.com ([66.187.237.31]:60361 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758278AbZCOKfv (ORCPT ); Sun, 15 Mar 2009 06:35:51 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n2FAZnLh026480 for ; Sun, 15 Mar 2009 06:35:49 -0400 In-Reply-To: <20090312171843.GU27823@random.random> Sender: kvm-owner@vger.kernel.org List-ID: Andrea Arcangeli wrote: > From: Andrea Arcangeli > > While looking at invlpg out of sync code with Izik I think I noticed a > missing smp tlb flush here. Without this the other cpu can still write > to a freed host physical page. tlb smp flush must happen if > rmap_remove is called always before mmu_lock is released because the > VM will take the mmu_lock before it can finally add the page to the > freelist after swapout. mmu notifier makes it safe to flush the tlb > after freeing the page (otherwise it would never be safe) so we can do > a single flush for multiple sptes invalidated. > Izik pointed out that for invlpg, the guest is responsible for smp tlb flushes, and mmu notifiers will protect against pageout. We still have a couple of holes, though, with the current code: - tlb loaded with an entry - guest invlpg - invlpg code drops the spte and rmap entry - pageout - mmu notifiers don't find an rmap entry, so tlb is not flushed The second hole is much simpler, we need a local invlpg at least. This doesn't show up on Intel since a vmexit will flush the entire tlb (and most AMDs have NPT by now). I think we can fix this without taking the hit of the IPI by - running a local invlpg() - making need_flush a vm flag instead of a local - clearing need_flush whenever remote tlbs are flushed - flushing remote tlbs on an mmu_notifier call when need_flush is set Since mmu notifier calls are rare, this would collapse many remote tlb flushes into one. -- error compiling committee.c: too many arguments to function