Skip to content

Commit b0119e8

Browse files
committed
iommu: Introduce new 'struct iommu_device'
This struct represents one hardware iommu in the iommu core code. For now it only has the iommu-ops associated with it, but that will be extended soon. The register/unregister interface is also added, as well as making use of it in the Intel and AMD IOMMU drivers. Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent c09e22d commit b0119e8

File tree

8 files changed

+77
-4
lines changed

8 files changed

+77
-4
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static struct timer_list queue_timer;
112112
* Domain for untranslated devices - only allocated
113113
* if iommu=pt passed on kernel cmd line.
114114
*/
115-
static const struct iommu_ops amd_iommu_ops;
115+
const struct iommu_ops amd_iommu_ops;
116116

117117
static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
118118
int amd_iommu_max_glx_val = -1;
@@ -3217,7 +3217,7 @@ static void amd_iommu_apply_dm_region(struct device *dev,
32173217
WARN_ON_ONCE(reserve_iova(&dma_dom->iovad, start, end) == NULL);
32183218
}
32193219

3220-
static const struct iommu_ops amd_iommu_ops = {
3220+
const struct iommu_ops amd_iommu_ops = {
32213221
.capable = amd_iommu_capable,
32223222
.domain_alloc = amd_iommu_domain_alloc,
32233223
.domain_free = amd_iommu_domain_free,

drivers/iommu/amd_iommu_init.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
* out of it.
9595
*/
9696

97+
extern const struct iommu_ops amd_iommu_ops;
98+
9799
/*
98100
* structure describing one IOMMU in the ACPI table. Typically followed by one
99101
* or more ivhd_entrys.
@@ -1639,6 +1641,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)
16391641
amd_iommu_groups, "ivhd%d",
16401642
iommu->index);
16411643

1644+
iommu_device_set_ops(&iommu->iommu, &amd_iommu_ops);
1645+
iommu_device_register(&iommu->iommu);
1646+
16421647
return pci_enable_device(iommu->dev);
16431648
}
16441649

drivers/iommu/amd_iommu_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,9 @@ struct amd_iommu {
538538
/* IOMMU sysfs device */
539539
struct device *iommu_dev;
540540

541+
/* Handle for IOMMU core code */
542+
struct iommu_device iommu;
543+
541544
/*
542545
* We can't rely on the BIOS to restore all values on reinit, so we
543546
* need to stash them

drivers/iommu/dmar.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ static unsigned long dmar_seq_ids[BITS_TO_LONGS(DMAR_UNITS_SUPPORTED)];
7474
static int alloc_iommu(struct dmar_drhd_unit *drhd);
7575
static void free_iommu(struct intel_iommu *iommu);
7676

77+
extern const struct iommu_ops intel_iommu_ops;
78+
7779
static void dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
7880
{
7981
/*
@@ -1084,6 +1086,12 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
10841086
err = PTR_ERR(iommu->iommu_dev);
10851087
goto err_unmap;
10861088
}
1089+
1090+
iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
1091+
1092+
err = iommu_device_register(&iommu->iommu);
1093+
if (err)
1094+
goto err_unmap;
10871095
}
10881096

10891097
drhd->iommu = iommu;
@@ -1102,6 +1110,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
11021110
static void free_iommu(struct intel_iommu *iommu)
11031111
{
11041112
iommu_device_destroy(iommu->iommu_dev);
1113+
iommu_device_unregister(&iommu->iommu);
11051114

11061115
if (iommu->irq) {
11071116
if (iommu->pr_irq) {

drivers/iommu/intel-iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
547547
static DEFINE_SPINLOCK(device_domain_lock);
548548
static LIST_HEAD(device_domain_list);
549549

550-
static const struct iommu_ops intel_iommu_ops;
550+
const struct iommu_ops intel_iommu_ops;
551551

552552
static bool translation_pre_enabled(struct intel_iommu *iommu)
553553
{
@@ -5292,7 +5292,7 @@ struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
52925292
}
52935293
#endif /* CONFIG_INTEL_IOMMU_SVM */
52945294

5295-
static const struct iommu_ops intel_iommu_ops = {
5295+
const struct iommu_ops intel_iommu_ops = {
52965296
.capable = intel_iommu_capable,
52975297
.domain_alloc = intel_iommu_domain_alloc,
52985298
.domain_free = intel_iommu_domain_free,

drivers/iommu/iommu.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,25 @@ struct iommu_group_attribute iommu_group_attr_##_name = \
7777
#define to_iommu_group(_kobj) \
7878
container_of(_kobj, struct iommu_group, kobj)
7979

80+
static LIST_HEAD(iommu_device_list);
81+
static DEFINE_SPINLOCK(iommu_device_lock);
82+
83+
int iommu_device_register(struct iommu_device *iommu)
84+
{
85+
spin_lock(&iommu_device_lock);
86+
list_add_tail(&iommu->list, &iommu_device_list);
87+
spin_unlock(&iommu_device_lock);
88+
89+
return 0;
90+
}
91+
92+
void iommu_device_unregister(struct iommu_device *iommu)
93+
{
94+
spin_lock(&iommu_device_lock);
95+
list_del(&iommu->list);
96+
spin_unlock(&iommu_device_lock);
97+
}
98+
8099
static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
81100
unsigned type);
82101
static int __iommu_attach_device(struct iommu_domain *domain,

include/linux/intel-iommu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/dma_remapping.h>
3030
#include <linux/mmu_notifier.h>
3131
#include <linux/list.h>
32+
#include <linux/iommu.h>
3233
#include <asm/cacheflush.h>
3334
#include <asm/iommu.h>
3435

@@ -440,6 +441,7 @@ struct intel_iommu {
440441
struct irq_domain *ir_msi_domain;
441442
#endif
442443
struct device *iommu_dev; /* IOMMU-sysfs device */
444+
struct iommu_device iommu; /* IOMMU core code handle */
443445
int node;
444446
u32 flags; /* Software defined flags */
445447
};

include/linux/iommu.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,26 @@ struct iommu_ops {
204204
unsigned long pgsize_bitmap;
205205
};
206206

207+
/**
208+
* struct iommu_device - IOMMU core representation of one IOMMU hardware
209+
* instance
210+
* @list: Used by the iommu-core to keep a list of registered iommus
211+
* @ops: iommu-ops for talking to this iommu
212+
*/
213+
struct iommu_device {
214+
struct list_head list;
215+
const struct iommu_ops *ops;
216+
};
217+
218+
int iommu_device_register(struct iommu_device *iommu);
219+
void iommu_device_unregister(struct iommu_device *iommu);
220+
221+
static inline void iommu_device_set_ops(struct iommu_device *iommu,
222+
const struct iommu_ops *ops)
223+
{
224+
iommu->ops = ops;
225+
}
226+
207227
#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */
208228
#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */
209229
#define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3 /* Pre Driver bind */
@@ -361,6 +381,7 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
361381
struct iommu_ops {};
362382
struct iommu_group {};
363383
struct iommu_fwspec {};
384+
struct iommu_device {};
364385

365386
static inline bool iommu_present(struct bus_type *bus)
366387
{
@@ -558,6 +579,20 @@ static inline void iommu_device_destroy(struct device *dev)
558579
{
559580
}
560581

582+
static inline int iommu_device_register(struct iommu_device *iommu)
583+
{
584+
return -ENODEV;
585+
}
586+
587+
static inline void iommu_device_set_ops(struct iommu_device *iommu,
588+
const struct iommu_ops *ops)
589+
{
590+
}
591+
592+
static inline void iommu_device_unregister(struct iommu_device *iommu)
593+
{
594+
}
595+
561596
static inline int iommu_device_link(struct device *dev, struct device *link)
562597
{
563598
return -EINVAL;

0 commit comments

Comments
 (0)