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);