|
@@ -36,6 +36,7 @@
|
|
|
|
|
|
static struct kset *iommu_group_kset;
|
|
static struct kset *iommu_group_kset;
|
|
static DEFINE_IDA(iommu_group_ida);
|
|
static DEFINE_IDA(iommu_group_ida);
|
|
|
|
+static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
|
|
|
|
|
|
struct iommu_callback_data {
|
|
struct iommu_callback_data {
|
|
const struct iommu_ops *ops;
|
|
const struct iommu_ops *ops;
|
|
@@ -112,6 +113,18 @@ static int __iommu_attach_group(struct iommu_domain *domain,
|
|
static void __iommu_detach_group(struct iommu_domain *domain,
|
|
static void __iommu_detach_group(struct iommu_domain *domain,
|
|
struct iommu_group *group);
|
|
struct iommu_group *group);
|
|
|
|
|
|
|
|
+static int __init iommu_set_def_domain_type(char *str)
|
|
|
|
+{
|
|
|
|
+ bool pt;
|
|
|
|
+
|
|
|
|
+ if (!str || strtobool(str, &pt))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+early_param("iommu.passthrough", iommu_set_def_domain_type);
|
|
|
|
+
|
|
static ssize_t iommu_group_attr_show(struct kobject *kobj,
|
|
static ssize_t iommu_group_attr_show(struct kobject *kobj,
|
|
struct attribute *__attr, char *buf)
|
|
struct attribute *__attr, char *buf)
|
|
{
|
|
{
|
|
@@ -1015,10 +1028,19 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
|
|
* IOMMU driver.
|
|
* IOMMU driver.
|
|
*/
|
|
*/
|
|
if (!group->default_domain) {
|
|
if (!group->default_domain) {
|
|
- group->default_domain = __iommu_domain_alloc(dev->bus,
|
|
|
|
- IOMMU_DOMAIN_DMA);
|
|
|
|
|
|
+ struct iommu_domain *dom;
|
|
|
|
+
|
|
|
|
+ dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
|
|
|
|
+ if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
|
|
|
|
+ dev_warn(dev,
|
|
|
|
+ "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
|
|
|
|
+ iommu_def_domain_type);
|
|
|
|
+ dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ group->default_domain = dom;
|
|
if (!group->domain)
|
|
if (!group->domain)
|
|
- group->domain = group->default_domain;
|
|
|
|
|
|
+ group->domain = dom;
|
|
}
|
|
}
|
|
|
|
|
|
ret = iommu_group_add_device(group, dev);
|
|
ret = iommu_group_add_device(group, dev);
|