From c865c8ec1033e6b98742c259bd858bb73feb3102 Mon Sep 17 00:00:00 2001
From: Marcelo Tosatti <mtosatti@redhat.com>
Date: Mon, 1 Mar 2010 20:52:08 -0300
Subject: [PATCH 05/20] device assignment: default requires IOMMU

RH-Author: Marcelo Tosatti <mtosatti@redhat.com>
Message-id: <df242853200f7a62086acae95a5d17e135456cc6.1267476474.git.mtosatti@redhat.com>
Patchwork-id: 7353
O-Subject: [PATCH 06/21] device assignment: default requires IOMMU
Bugzilla: 569613
RH-Acked-by: Chris Wright <chrisw@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Gleb Natapov <gleb@redhat.com>

From: Chris Wright <chrisw@sous-sol.org>

The default mode for device assignment is to rely on an IOMMU for
proper translations and a functioning device in the guest.  The current
logic makes this requirement advisory, and simply disables the request
for IOMMU if one is not found on the host.  This makes for a confused
user when the device assignment appears to work, but the device in the
guest is not functioning  (I've seen about a half-dozen reports with
this failure mode).

Change the logic such that the default requires the IOMMU.  Period.
If the host does not have an IOMMU, device assignment will fail.

This is a user visible change, however I think the current situation is
simply broken.

And, of course, disabling the IOMMU requirement using the old:

   -pcidevice host=[addr],dma=none

or the newer:

   -device pci-assign,host=[addr],iommu=0

will do what it always did (not require an IOMMU, and fail to work
properly).

Cc: Alexander Graf <agraf@suse.de>
Cc: Dmitri Seletski <drjoms@gmail.com>
Cc: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Chris Wright <chrisw@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
(cherry picked from commit c01cfac552861ca4d82e359791a2d79da7f80cb5)
---
 hw/device-assignment.c |   17 +++++++++--------
 1 files changed, 9 insertions(+), 8 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/device-assignment.c |   17 +++++++++--------
 1 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 04c6538..d1d050e 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -639,14 +639,15 @@ static int assign_device(AssignedDevice *dev)
     assigned_dev_data.devfn = dev->h_devfn;
 
 #ifdef KVM_CAP_IOMMU
-    /* We always enable the IOMMU if present
-     * (or when not disabled on the command line)
-     */
-    r = kvm_check_extension(kvm_state, KVM_CAP_IOMMU);
-    if (!r)
-        dev->use_iommu = 0;
-    if (dev->use_iommu)
-	assigned_dev_data.flags |= KVM_DEV_ASSIGN_ENABLE_IOMMU;
+    /* We always enable the IOMMU unless disabled on the command line */
+    if (dev->use_iommu) {
+        if (!kvm_check_extension(kvm_state, KVM_CAP_IOMMU)) {
+            fprintf(stderr, "No IOMMU found.  Unable to assign device \"%s\"\n",
+                    dev->dev.qdev.id);
+            return -ENODEV;
+        }
+        assigned_dev_data.flags |= KVM_DEV_ASSIGN_ENABLE_IOMMU;
+    }
 #else
     dev->use_iommu = 0;
 #endif
-- 
1.7.0.3

