hw/arm/smmuv3: Implement fault injection
We convert iommu_fault structs received from the kernel into the data struct used by the emulation code and record the evnts into the virtual event queue. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
This commit is contained in:
parent
1e1a34cb30
commit
b81289b550
107
hw-arm-smmuv3-Implement-fault-injection.patch
Normal file
107
hw-arm-smmuv3-Implement-fault-injection.patch
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
From 55bfd18b7671c82705d83d543281add0afcda31f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eric Auger <eric.auger@redhat.com>
|
||||||
|
Date: Thu, 13 Sep 2018 14:24:45 +0200
|
||||||
|
Subject: [PATCH] hw/arm/smmuv3: Implement fault injection
|
||||||
|
|
||||||
|
We convert iommu_fault structs received from the kernel
|
||||||
|
into the data struct used by the emulation code and record
|
||||||
|
the evnts into the virtual event queue.
|
||||||
|
|
||||||
|
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||||
|
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
|
||||||
|
---
|
||||||
|
hw/arm/smmuv3.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 71 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
|
||||||
|
index 3d2151857d..931d6eae57 100644
|
||||||
|
--- a/hw/arm/smmuv3.c
|
||||||
|
+++ b/hw/arm/smmuv3.c
|
||||||
|
@@ -1594,6 +1594,76 @@ static int smmuv3_get_attr(IOMMUMemoryRegion *iommu,
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct iommu_fault;
|
||||||
|
+
|
||||||
|
+static inline int
|
||||||
|
+smmuv3_inject_faults(IOMMUMemoryRegion *iommu_mr, int count,
|
||||||
|
+ struct iommu_fault *buf)
|
||||||
|
+{
|
||||||
|
+#ifdef __linux__
|
||||||
|
+ SMMUDevice *sdev = container_of(iommu_mr, SMMUDevice, iommu);
|
||||||
|
+ SMMUv3State *s3 = sdev->smmu;
|
||||||
|
+ uint32_t sid = smmu_get_sid(sdev);
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < count; i++) {
|
||||||
|
+ SMMUEventInfo info = {};
|
||||||
|
+ struct iommu_fault_unrecoverable *record;
|
||||||
|
+
|
||||||
|
+ if (buf[i].type != IOMMU_FAULT_DMA_UNRECOV) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ info.sid = sid;
|
||||||
|
+ record = &buf[i].event;
|
||||||
|
+
|
||||||
|
+ switch (record->reason) {
|
||||||
|
+ case IOMMU_FAULT_REASON_PASID_INVALID:
|
||||||
|
+ info.type = SMMU_EVT_C_BAD_SUBSTREAMID;
|
||||||
|
+ /* TODO further fill info.u.c_bad_substream */
|
||||||
|
+ break;
|
||||||
|
+ case IOMMU_FAULT_REASON_PASID_FETCH:
|
||||||
|
+ info.type = SMMU_EVT_F_CD_FETCH;
|
||||||
|
+ break;
|
||||||
|
+ case IOMMU_FAULT_REASON_BAD_PASID_ENTRY:
|
||||||
|
+ info.type = SMMU_EVT_C_BAD_CD;
|
||||||
|
+ /* TODO further fill info.u.c_bad_cd */
|
||||||
|
+ break;
|
||||||
|
+ case IOMMU_FAULT_REASON_WALK_EABT:
|
||||||
|
+ info.type = SMMU_EVT_F_WALK_EABT;
|
||||||
|
+ info.u.f_walk_eabt.addr = record->addr;
|
||||||
|
+ info.u.f_walk_eabt.addr2 = record->fetch_addr;
|
||||||
|
+ break;
|
||||||
|
+ case IOMMU_FAULT_REASON_PTE_FETCH:
|
||||||
|
+ info.type = SMMU_EVT_F_TRANSLATION;
|
||||||
|
+ info.u.f_translation.addr = record->addr;
|
||||||
|
+ break;
|
||||||
|
+ case IOMMU_FAULT_REASON_OOR_ADDRESS:
|
||||||
|
+ info.type = SMMU_EVT_F_ADDR_SIZE;
|
||||||
|
+ info.u.f_addr_size.addr = record->addr;
|
||||||
|
+ break;
|
||||||
|
+ case IOMMU_FAULT_REASON_ACCESS:
|
||||||
|
+ info.type = SMMU_EVT_F_ACCESS;
|
||||||
|
+ info.u.f_access.addr = record->addr;
|
||||||
|
+ break;
|
||||||
|
+ case IOMMU_FAULT_REASON_PERMISSION:
|
||||||
|
+ info.type = SMMU_EVT_F_PERMISSION;
|
||||||
|
+ info.u.f_permission.addr = record->addr;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ warn_report("%s Unexpected fault reason received from host: %d",
|
||||||
|
+ __func__, record->reason);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ smmuv3_record_event(s3, &info);
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+#else
|
||||||
|
+ return -1;
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
@@ -1602,6 +1672,7 @@ static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
|
||||||
|
imrc->translate = smmuv3_translate;
|
||||||
|
imrc->notify_flag_changed = smmuv3_notify_flag_changed;
|
||||||
|
imrc->get_attr = smmuv3_get_attr;
|
||||||
|
+ imrc->inject_faults = smmuv3_inject_faults;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo smmuv3_type_info = {
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user