|
|
76daa3 |
From 2bf16e1b643f9aeb9230206cb3cc1f599ab0a3f0 Mon Sep 17 00:00:00 2001
|
|
|
76daa3 |
From: Peter Xu <peterx@redhat.com>
|
|
|
76daa3 |
Date: Mon, 24 Apr 2017 02:52:48 +0200
|
|
|
76daa3 |
Subject: [PATCH 09/23] memory: introduce memory_region_notify_one()
|
|
|
76daa3 |
|
|
|
76daa3 |
RH-Author: Peter Xu <peterx@redhat.com>
|
|
|
76daa3 |
Message-id: <1493002373-13010-5-git-send-email-peterx@redhat.com>
|
|
|
76daa3 |
Patchwork-id: 74852
|
|
|
76daa3 |
O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH v2 4/9] memory: introduce memory_region_notify_one()
|
|
|
76daa3 |
Bugzilla: 1335808
|
|
|
76daa3 |
RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
|
|
|
76daa3 |
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
76daa3 |
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
|
|
|
76daa3 |
|
|
|
76daa3 |
Generalizing the notify logic in memory_region_notify_iommu() into a
|
|
|
76daa3 |
single function. This can be further used in customized replay()
|
|
|
76daa3 |
functions for IOMMUs.
|
|
|
76daa3 |
|
|
|
76daa3 |
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
|
|
76daa3 |
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
|
|
76daa3 |
Reviewed-by: \"Michael S. Tsirkin\" <mst@redhat.com>
|
|
|
76daa3 |
Signed-off-by: Peter Xu <peterx@redhat.com>
|
|
|
76daa3 |
Message-Id: <1491562755-23867-5-git-send-email-peterx@redhat.com>
|
|
|
76daa3 |
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
76daa3 |
(cherry picked from commit bd2bfa4c52e5f4dc6dbaa5be0521aedc31cb53d9)
|
|
|
76daa3 |
Signed-off-by: Peter Xu <peterx@redhat.com>
|
|
|
76daa3 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
76daa3 |
---
|
|
|
76daa3 |
include/exec/memory.h | 15 +++++++++++++++
|
|
|
76daa3 |
memory.c | 40 ++++++++++++++++++++++++----------------
|
|
|
76daa3 |
2 files changed, 39 insertions(+), 16 deletions(-)
|
|
|
76daa3 |
|
|
|
76daa3 |
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
|
|
76daa3 |
index fb7dff3..055b3a8 100644
|
|
|
76daa3 |
--- a/include/exec/memory.h
|
|
|
76daa3 |
+++ b/include/exec/memory.h
|
|
|
76daa3 |
@@ -688,6 +688,21 @@ void memory_region_notify_iommu(MemoryRegion *mr,
|
|
|
76daa3 |
IOMMUTLBEntry entry);
|
|
|
76daa3 |
|
|
|
76daa3 |
/**
|
|
|
76daa3 |
+ * memory_region_notify_one: notify a change in an IOMMU translation
|
|
|
76daa3 |
+ * entry to a single notifier
|
|
|
76daa3 |
+ *
|
|
|
76daa3 |
+ * This works just like memory_region_notify_iommu(), but it only
|
|
|
76daa3 |
+ * notifies a specific notifier, not all of them.
|
|
|
76daa3 |
+ *
|
|
|
76daa3 |
+ * @notifier: the notifier to be notified
|
|
|
76daa3 |
+ * @entry: the new entry in the IOMMU translation table. The entry
|
|
|
76daa3 |
+ * replaces all old entries for the same virtual I/O address range.
|
|
|
76daa3 |
+ * Deleted entries have .@perm == 0.
|
|
|
76daa3 |
+ */
|
|
|
76daa3 |
+void memory_region_notify_one(IOMMUNotifier *notifier,
|
|
|
76daa3 |
+ IOMMUTLBEntry *entry);
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+/**
|
|
|
76daa3 |
* memory_region_register_iommu_notifier: register a notifier for changes to
|
|
|
76daa3 |
* IOMMU translation entries.
|
|
|
76daa3 |
*
|
|
|
76daa3 |
diff --git a/memory.c b/memory.c
|
|
|
76daa3 |
index b4ed67b..ded4bf1 100644
|
|
|
76daa3 |
--- a/memory.c
|
|
|
76daa3 |
+++ b/memory.c
|
|
|
76daa3 |
@@ -1662,32 +1662,40 @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
|
|
|
76daa3 |
memory_region_update_iommu_notify_flags(mr);
|
|
|
76daa3 |
}
|
|
|
76daa3 |
|
|
|
76daa3 |
-void memory_region_notify_iommu(MemoryRegion *mr,
|
|
|
76daa3 |
- IOMMUTLBEntry entry)
|
|
|
76daa3 |
+void memory_region_notify_one(IOMMUNotifier *notifier,
|
|
|
76daa3 |
+ IOMMUTLBEntry *entry)
|
|
|
76daa3 |
{
|
|
|
76daa3 |
- IOMMUNotifier *iommu_notifier;
|
|
|
76daa3 |
IOMMUNotifierFlag request_flags;
|
|
|
76daa3 |
|
|
|
76daa3 |
- assert(memory_region_is_iommu(mr));
|
|
|
76daa3 |
+ /*
|
|
|
76daa3 |
+ * Skip the notification if the notification does not overlap
|
|
|
76daa3 |
+ * with registered range.
|
|
|
76daa3 |
+ */
|
|
|
76daa3 |
+ if (notifier->start > entry->iova + entry->addr_mask + 1 ||
|
|
|
76daa3 |
+ notifier->end < entry->iova) {
|
|
|
76daa3 |
+ return;
|
|
|
76daa3 |
+ }
|
|
|
76daa3 |
|
|
|
76daa3 |
- if (entry.perm & IOMMU_RW) {
|
|
|
76daa3 |
+ if (entry->perm & IOMMU_RW) {
|
|
|
76daa3 |
request_flags = IOMMU_NOTIFIER_MAP;
|
|
|
76daa3 |
} else {
|
|
|
76daa3 |
request_flags = IOMMU_NOTIFIER_UNMAP;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
|
|
|
76daa3 |
+ if (notifier->notifier_flags & request_flags) {
|
|
|
76daa3 |
+ notifier->notify(notifier, entry);
|
|
|
76daa3 |
+ }
|
|
|
76daa3 |
+}
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+void memory_region_notify_iommu(MemoryRegion *mr,
|
|
|
76daa3 |
+ IOMMUTLBEntry entry)
|
|
|
76daa3 |
+{
|
|
|
76daa3 |
+ IOMMUNotifier *iommu_notifier;
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ assert(memory_region_is_iommu(mr));
|
|
|
76daa3 |
+
|
|
|
76daa3 |
IOMMU_NOTIFIER_FOREACH(iommu_notifier, mr) {
|
|
|
76daa3 |
- /*
|
|
|
76daa3 |
- * Skip the notification if the notification does not overlap
|
|
|
76daa3 |
- * with registered range.
|
|
|
76daa3 |
- */
|
|
|
76daa3 |
- if (iommu_notifier->start > entry.iova + entry.addr_mask + 1 ||
|
|
|
76daa3 |
- iommu_notifier->end < entry.iova) {
|
|
|
76daa3 |
- continue;
|
|
|
76daa3 |
- }
|
|
|
76daa3 |
- if (iommu_notifier->notifier_flags & request_flags) {
|
|
|
76daa3 |
- iommu_notifier->notify(iommu_notifier, &entry);
|
|
|
76daa3 |
- }
|
|
|
76daa3 |
+ memory_region_notify_one(iommu_notifier, &entry);
|
|
|
76daa3 |
}
|
|
|
76daa3 |
}
|
|
|
76daa3 |
|
|
|
76daa3 |
--
|
|
|
76daa3 |
1.8.3.1
|
|
|
76daa3 |
|