From patchwork Wed Nov 23 09:20:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 9442787 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EE6C4600BA for ; Wed, 23 Nov 2016 09:23:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D4E6F20410 for ; Wed, 23 Nov 2016 09:23:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C8102206AF; Wed, 23 Nov 2016 09:23:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0236520410 for ; Wed, 23 Nov 2016 09:23:00 +0000 (UTC) Received: from localhost ([::1]:60386 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c9Tlc-0001ja-0f for patchwork-qemu-devel@patchwork.kernel.org; Wed, 23 Nov 2016 04:23:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36377) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c9Tjq-0000vv-E0 for qemu-devel@nongnu.org; Wed, 23 Nov 2016 04:21:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c9Tjm-0004gz-9z for qemu-devel@nongnu.org; Wed, 23 Nov 2016 04:21:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:32898) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1c9Tjm-0004eB-19 for qemu-devel@nongnu.org; Wed, 23 Nov 2016 04:21:06 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 79A124DAF7; Wed, 23 Nov 2016 09:21:03 +0000 (UTC) Received: from pxdev.xzpeter.org (vpn1-7-82.pek2.redhat.com [10.72.7.82]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uAN9KwIA002679; Wed, 23 Nov 2016 04:20:59 -0500 From: Peter Xu To: qemu-devel@nongnu.org Date: Wed, 23 Nov 2016 17:20:58 +0800 Message-Id: <1479892858-4218-1-git-send-email-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 23 Nov 2016 09:21:03 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH] memory: add section range info for IOMMU notifier X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, alex.williamson@redhat.com, peterx@redhat.com, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP In this patch, IOMMUNotifier.{start|end} are introduced to store section information for a specific notifier. When notification occurs, we not only check the notification type (MAP|UNMAP), but also check whether the notified iova is in the range of specific IOMMU notifier, and skip those notifiers if not in the listened range. When removing an region, we need to make sure we removed the correct VFIOGuestIOMMU by checking the IOMMUNotifier.start address as well. Suggested-by: David Gibson Signed-off-by: Peter Xu --- This patch fixes the same issue with the following one: [PATCH] vfio: avoid adding same iommu mr for notify Alex/David, would you please help provide some review comments on either of the two patches? When we can settle down the best way, then I'll drop the other one (I still prefer the other one...). Thanks, Signed-off-by: Peter Xu --- hw/vfio/common.c | 7 ++++++- include/exec/memory.h | 3 +++ memory.c | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 801578b..c3db115 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -455,6 +455,10 @@ static void vfio_listener_region_add(MemoryListener *listener, giommu->container = container; giommu->n.notify = vfio_iommu_map_notify; giommu->n.notifier_flags = IOMMU_NOTIFIER_ALL; + giommu->n.start = section->offset_within_address_space; + llend = int128_add(int128_make64(giommu->n.start), section->size); + llend = int128_sub(llend, int128_one()); + giommu->n.end = int128_get64(llend); QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next); memory_region_register_iommu_notifier(giommu->iommu, &giommu->n); @@ -525,7 +529,8 @@ static void vfio_listener_region_del(MemoryListener *listener, VFIOGuestIOMMU *giommu; QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) { - if (giommu->iommu == section->mr) { + if (giommu->iommu == section->mr && + giommu->n.start == section->offset_within_address_space) { memory_region_unregister_iommu_notifier(giommu->iommu, &giommu->n); QLIST_REMOVE(giommu, giommu_next); diff --git a/include/exec/memory.h b/include/exec/memory.h index 9728a2f..87357ea 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -84,6 +84,9 @@ typedef enum { struct IOMMUNotifier { void (*notify)(struct IOMMUNotifier *notifier, IOMMUTLBEntry *data); IOMMUNotifierFlag notifier_flags; + /* Notify for address space range start <= addr <= end */ + hwaddr start; + hwaddr end; QLIST_ENTRY(IOMMUNotifier) node; }; typedef struct IOMMUNotifier IOMMUNotifier; diff --git a/memory.c b/memory.c index 33110e9..f89d047 100644 --- a/memory.c +++ b/memory.c @@ -1662,7 +1662,9 @@ void memory_region_notify_iommu(MemoryRegion *mr, } QLIST_FOREACH(iommu_notifier, &mr->iommu_notify, node) { - if (iommu_notifier->notifier_flags & request_flags) { + if (iommu_notifier->notifier_flags & request_flags && + iommu_notifier->start <= entry.iova && + iommu_notifier->end >= entry.iova) { iommu_notifier->notify(iommu_notifier, &entry); } }