Add IOMMU hook to unmap IOMMU devices from a VM.
This can be used if the devices need to be selectively removed or to
provide extra assurance that the devices didn't get mapped in.
Change-Id: Id9d5ffb5fa5ed8d8f4cffb7592e198235bdc4b40
diff --git a/inc/hf/plat/iommu.h b/inc/hf/plat/iommu.h
index 9ef791d..0655232 100644
--- a/inc/hf/plat/iommu.h
+++ b/inc/hf/plat/iommu.h
@@ -30,6 +30,16 @@
struct mpool *ppool);
/**
+ * Unmaps the address space used by the platform IOMMU driver from the VM so
+ * that VM cannot program these devices.
+ *
+ * Note that any calls to unmap an address range will result in
+ * `plat_iommu_identity_map` being invoked to apply the change to the IOMMU
+ * mapping as well. The module must ensure it can handle this reentrancy.
+ */
+bool plat_iommu_unmap_iommus(struct vm_locked vm_locked, struct mpool *ppool);
+
+/**
* Maps the address range with the given mode for the given VM in the IOMMU.
*
* Assumes the identity map cannot fail. This may not always be true and if it
diff --git a/src/iommu/absent.c b/src/iommu/absent.c
index c89e9bb..80f3883 100644
--- a/src/iommu/absent.c
+++ b/src/iommu/absent.c
@@ -26,6 +26,14 @@
return true;
}
+bool plat_iommu_unmap_iommus(struct vm_locked vm_locked, struct mpool *ppool)
+{
+ (void)vm_locked;
+ (void)ppool;
+
+ return true;
+}
+
void plat_iommu_identity_map(struct vm_locked vm_locked, paddr_t begin,
paddr_t end, uint32_t mode)
{
diff --git a/src/load.c b/src/load.c
index e2a272e..c9af05b 100644
--- a/src/load.c
+++ b/src/load.c
@@ -28,6 +28,7 @@
#include "hf/memiter.h"
#include "hf/mm.h"
#include "hf/plat/console.h"
+#include "hf/plat/iommu.h"
#include "hf/static_assert.h"
#include "hf/std.h"
#include "hf/vm.h"
@@ -186,6 +187,12 @@
goto out;
}
+ if (!plat_iommu_unmap_iommus(vm_locked, ppool)) {
+ dlog("Unable to unmap IOMMUs from primary VM\n");
+ ret = false;
+ goto out;
+ }
+
vcpu_locked = vcpu_lock(vm_get_vcpu(vm, 0));
vcpu_on(vcpu_locked, ipa_from_pa(primary_begin), params->kernel_arg);
vcpu_unlock(&vcpu_locked);