Skip to content

Commit 79ae1ec

Browse files
LuBaolujgunthorpe
authored andcommitted
iommu/vt-d: Add helper for nested domain allocation
This adds helper for accepting user parameters and allocate a nested domain. Link: https://lore.kernel.org/r/20231026044216.64964-4-yi.l.liu@intel.com Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 04f261a commit 79ae1ec

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

drivers/iommu/intel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0
22
obj-$(CONFIG_DMAR_TABLE) += dmar.o
3-
obj-$(CONFIG_INTEL_IOMMU) += iommu.o pasid.o
3+
obj-$(CONFIG_INTEL_IOMMU) += iommu.o pasid.o nested.o
44
obj-$(CONFIG_DMAR_TABLE) += trace.o cap_audit.o
55
obj-$(CONFIG_DMAR_PERF) += perf.o
66
obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o

drivers/iommu/intel/iommu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,8 @@ void *alloc_pgtable_page(int node, gfp_t gfp);
884884
void free_pgtable_page(void *vaddr);
885885
void iommu_flush_write_buffer(struct intel_iommu *iommu);
886886
struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn);
887+
struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
888+
const struct iommu_user_data *user_data);
887889

888890
#ifdef CONFIG_INTEL_IOMMU_SVM
889891
void intel_svm_check(struct intel_iommu *iommu);

drivers/iommu/intel/nested.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* nested.c - nested mode translation support
4+
*
5+
* Copyright (C) 2023 Intel Corporation
6+
*
7+
* Author: Lu Baolu <baolu.lu@linux.intel.com>
8+
* Jacob Pan <jacob.jun.pan@linux.intel.com>
9+
* Yi Liu <yi.l.liu@intel.com>
10+
*/
11+
12+
#define pr_fmt(fmt) "DMAR: " fmt
13+
14+
#include <linux/iommu.h>
15+
16+
#include "iommu.h"
17+
18+
static void intel_nested_domain_free(struct iommu_domain *domain)
19+
{
20+
kfree(to_dmar_domain(domain));
21+
}
22+
23+
static const struct iommu_domain_ops intel_nested_domain_ops = {
24+
.free = intel_nested_domain_free,
25+
};
26+
27+
struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
28+
const struct iommu_user_data *user_data)
29+
{
30+
struct dmar_domain *s2_domain = to_dmar_domain(parent);
31+
struct iommu_hwpt_vtd_s1 vtd;
32+
struct dmar_domain *domain;
33+
int ret;
34+
35+
/* Must be nested domain */
36+
if (user_data->type != IOMMU_HWPT_DATA_VTD_S1)
37+
return ERR_PTR(-EOPNOTSUPP);
38+
if (parent->ops != intel_iommu_ops.default_domain_ops)
39+
return ERR_PTR(-EINVAL);
40+
41+
ret = iommu_copy_struct_from_user(&vtd, user_data,
42+
IOMMU_HWPT_DATA_VTD_S1, __reserved);
43+
if (ret)
44+
return ERR_PTR(ret);
45+
46+
domain = kzalloc(sizeof(*domain), GFP_KERNEL_ACCOUNT);
47+
if (!domain)
48+
return ERR_PTR(-ENOMEM);
49+
50+
domain->use_first_level = true;
51+
domain->s2_domain = s2_domain;
52+
domain->s1_pgtbl = vtd.pgtbl_addr;
53+
domain->s1_cfg = vtd;
54+
domain->domain.ops = &intel_nested_domain_ops;
55+
domain->domain.type = IOMMU_DOMAIN_NESTED;
56+
INIT_LIST_HEAD(&domain->devices);
57+
INIT_LIST_HEAD(&domain->dev_pasids);
58+
spin_lock_init(&domain->lock);
59+
xa_init(&domain->iommu_array);
60+
61+
return &domain->domain;
62+
}

0 commit comments

Comments
 (0)