[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC v3 10/27] memory: Add IOMMUConfigNotifier
From: |
Eric Auger |
Subject: |
[Qemu-arm] [RFC v3 10/27] memory: Add IOMMUConfigNotifier |
Date: |
Fri, 12 Apr 2019 12:03:37 +0200 |
With this patch, an IOMMUNotifier can now be either
an IOTLB notifier or a config notifier. A config notifier
is supposed to be called on guest translation config change.
This gives host a chance to update the physical IOMMU
configuration so that is consistent with the guest view.
The notifier is passed an IOMMUConfig. The first type of
configuration introduced here consists in the PASID
configuration.
We introduce the associated helpers, iommu_config_notifier_init,
memory_region_config_notify_iommu
Signed-off-by: Eric Auger <address@hidden>
---
v1 -> v2:
- use pasid_table config
- pass IOMMUNotifierFlag flags to iommu_config_notifier_init
to prepare for other config flags
- Introduce IOMMUConfig
- s/IOMMU_NOTIFIER_S1_CFG/IOMMU_NOTIFIER_PASID_CFG
- remove unused IOMMUStage1ConfigType
---
hw/vfio/common.c | 15 ++++++++-----
include/exec/memory.h | 52 ++++++++++++++++++++++++++++++++++++++++++-
memory.c | 25 +++++++++++++++++++++
3 files changed, 86 insertions(+), 6 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index a9004b6d20..0853c8c376 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -703,11 +703,16 @@ static void vfio_listener_region_del(MemoryListener
*listener,
VFIOGuestIOMMU *giommu;
QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) {
- if (MEMORY_REGION(giommu->iommu) == section->mr &&
- is_iommu_iotlb_notifier(&giommu->n) &&
- giommu->n.iotlb_notifier.start ==
section->offset_within_region) {
- memory_region_unregister_iommu_notifier(section->mr,
- &giommu->n);
+ if (MEMORY_REGION(giommu->iommu) == section->mr) {
+ if (is_iommu_iotlb_notifier(&giommu->n) &&
+ giommu->n.iotlb_notifier.start ==
+ section->offset_within_region) {
+ memory_region_unregister_iommu_notifier(section->mr,
+ &giommu->n);
+ } else {
+ memory_region_unregister_iommu_notifier(section->mr,
+ &giommu->n);
+ }
QLIST_REMOVE(giommu, giommu_next);
g_free(giommu);
break;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 3918352a17..f54052e9b3 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -26,6 +26,9 @@
#include "qom/object.h"
#include "qemu/rcu.h"
#include "hw/qdev-core.h"
+#ifdef CONFIG_LINUX
+#include <linux/iommu.h>
+#endif
#define RAM_ADDR_INVALID (~(ram_addr_t)0)
@@ -74,6 +77,14 @@ struct IOMMUTLBEntry {
IOMMUAccessFlags perm;
};
+typedef struct IOMMUConfig {
+ union {
+#ifdef __linux__
+ struct iommu_pasid_table_config pasid_cfg;
+#endif
+ };
+} IOMMUConfig;
+
/*
* Bitmap for different IOMMUNotifier capabilities. Each notifier can
* register with one or multiple IOMMU Notifier capability bit(s).
@@ -84,13 +95,18 @@ typedef enum {
IOMMU_NOTIFIER_IOTLB_UNMAP = 0x1,
/* Notify entry changes (newly created entries) */
IOMMU_NOTIFIER_IOTLB_MAP = 0x2,
+ /* Notify stage 1 config changes */
+ IOMMU_NOTIFIER_CONFIG_PASID = 0x4,
} IOMMUNotifierFlag;
#define IOMMU_NOTIFIER_IOTLB_ALL (IOMMU_NOTIFIER_IOTLB_MAP |
IOMMU_NOTIFIER_IOTLB_UNMAP)
+#define IOMMU_NOTIFIER_CONFIG_ALL (IOMMU_NOTIFIER_CONFIG_PASID)
struct IOMMUNotifier;
typedef void (*IOMMUNotify)(struct IOMMUNotifier *notifier,
IOMMUTLBEntry *data);
+typedef void (*IOMMUConfigNotify)(struct IOMMUNotifier *notifier,
+ IOMMUConfig *cfg);
typedef struct IOMMUIOLTBNotifier {
IOMMUNotify notify;
@@ -99,10 +115,15 @@ typedef struct IOMMUIOLTBNotifier {
hwaddr end;
} IOMMUIOLTBNotifier;
+typedef struct IOMMUConfigNotifier {
+ IOMMUConfigNotify notify;
+} IOMMUConfigNotifier;
+
struct IOMMUNotifier {
IOMMUNotifierFlag notifier_flags;
union {
IOMMUIOLTBNotifier iotlb_notifier;
+ IOMMUConfigNotifier config_notifier;
};
int iommu_idx;
QLIST_ENTRY(IOMMUNotifier) node;
@@ -147,6 +168,16 @@ static inline void iommu_iotlb_notifier_init(IOMMUNotifier
*n, IOMMUNotify fn,
n->iommu_idx = iommu_idx;
}
+static inline void iommu_config_notifier_init(IOMMUNotifier *n,
+ IOMMUConfigNotify fn,
+ IOMMUNotifierFlag flags,
+ int iommu_idx)
+{
+ n->notifier_flags = flags;
+ n->iommu_idx = iommu_idx;
+ n->config_notifier.notify = fn;
+}
+
/*
* Memory region callbacks
*/
@@ -647,6 +678,12 @@ static inline bool is_iommu_iotlb_notifier(IOMMUNotifier
*n)
{
return n->notifier_flags & IOMMU_NOTIFIER_IOTLB_ALL;
}
+
+static inline bool is_iommu_config_notifier(IOMMUNotifier *n)
+{
+ return n->notifier_flags & IOMMU_NOTIFIER_CONFIG_ALL;
+}
+
#ifdef CONFIG_POSIX
/**
@@ -1054,6 +1091,19 @@ void memory_region_iotlb_notify_iommu(IOMMUMemoryRegion
*iommu_mr,
int iommu_idx,
IOMMUTLBEntry entry);
+/**
+ * memory_region_config_notify_iommu: notify a change in a translation
+ * configuration structure.
+ * @iommu_mr: the memory region that was changed
+ * @iommu_idx: the IOMMU index for the translation table which has changed
+ * @flag: config change type
+ * @config: new guest config
+ */
+void memory_region_config_notify_iommu(IOMMUMemoryRegion *iommu_mr,
+ int iommu_idx,
+ IOMMUNotifierFlag flag,
+ IOMMUConfig *config);
+
/**
* memory_region_iotlb_notify_one: notify a change in an IOMMU translation
* entry to a single notifier
@@ -1071,7 +1121,7 @@ void memory_region_iotlb_notify_one(IOMMUNotifier
*notifier,
/**
* memory_region_register_iommu_notifier: register a notifier for changes to
- * IOMMU translation entries.
+ * IOMMU translation entries or translation config settings.
*
* @mr: the memory region to observe
* @n: the IOMMUNotifier to be added; the notify callback receives a
diff --git a/memory.c b/memory.c
index bd9f425f0d..8cd3c65872 100644
--- a/memory.c
+++ b/memory.c
@@ -1934,6 +1934,13 @@ void
memory_region_unregister_iommu_notifier(MemoryRegion *mr,
memory_region_update_iommu_notify_flags(iommu_mr);
}
+static void
+memory_region_config_notify_one(IOMMUNotifier *notifier,
+ IOMMUConfig *cfg)
+{
+ notifier->config_notifier.notify(notifier, cfg);
+}
+
void memory_region_iotlb_notify_one(IOMMUNotifier *notifier,
IOMMUTLBEntry *entry)
{
@@ -1976,6 +1983,24 @@ void memory_region_iotlb_notify_iommu(IOMMUMemoryRegion
*iommu_mr,
}
}
+void memory_region_config_notify_iommu(IOMMUMemoryRegion *iommu_mr,
+ int iommu_idx,
+ IOMMUNotifierFlag flag,
+ IOMMUConfig *config)
+{
+ IOMMUNotifier *iommu_notifier;
+
+ assert(memory_region_is_iommu(MEMORY_REGION(iommu_mr)));
+
+ IOMMU_NOTIFIER_FOREACH(iommu_notifier, iommu_mr) {
+ if (iommu_notifier->iommu_idx == iommu_idx &&
+ is_iommu_config_notifier(iommu_notifier) &&
+ iommu_notifier->notifier_flags == flag) {
+ memory_region_config_notify_one(iommu_notifier, config);
+ }
+ }
+}
+
int memory_region_iommu_get_attr(IOMMUMemoryRegion *iommu_mr,
enum IOMMUMemoryRegionAttr attr,
void *data)
--
2.20.1
- [Qemu-arm] [RFC v3 00/27] vSMMUv3/pSMMUv3 2 stage VFIO integration, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 01/27] hw/arm/smmuv3: Remove SMMUNotifierNode, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 02/27] vfio/common: Introduce vfio_set_irq_signaling helper, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 04/27] header update against 5.1-rc3 and IOMMU/VFIO nested stage APIs, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 03/27] update-linux-headers: Import iommu.h, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 05/27] memory: add IOMMU_ATTR_VFIO_NESTED IOMMU memory region attribute, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 06/27] memory: add IOMMU_ATTR_MSI_TRANSLATE IOMMU memory region attribute, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 07/27] hw/arm/smmuv3: Advertise VFIO_NESTED and MSI_TRANSLATE attributes, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 08/27] hw/vfio/common: Force nested if iommu requires it, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 09/27] memory: Prepare for different kinds of IOMMU MR notifiers, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 10/27] memory: Add IOMMUConfigNotifier,
Eric Auger <=
- [Qemu-arm] [RFC v3 11/27] memory: Add arch_id and leaf fields in IOTLBEntry, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 12/27] hw/arm/smmuv3: Store the PASID table GPA in the translation config, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 13/27] hw/arm/smmuv3: Implement dummy replay, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 14/27] hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA invalidation, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 15/27] hw/arm/smmuv3: Fill the IOTLBEntry leaf field on NH_VA invalidation, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 16/27] hw/arm/smmuv3: Notify on config changes, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 17/27] hw/vfio/common: Introduce vfio_alloc_guest_iommu helper, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 18/27] hw/vfio/common: Introduce hostwin_from_range helper, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 19/27] hw/vfio/common: Introduce helpers to DMA map/unap a RAM section, Eric Auger, 2019/04/12
- [Qemu-arm] [RFC v3 20/27] hw/vfio/common: Setup nested stage mappings, Eric Auger, 2019/04/12