mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'iommu-updates-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu updates from Joerg Roedel:
"Core changes:
- Make default-domains mandatory for all IOMMU drivers
- Remove group refcounting
- Add generic_single_device_group() helper and consolidate drivers
- Cleanup map/unmap ops
- Scaling improvements for the IOVA rcache depot
- Convert dart & iommufd to the new domain_alloc_paging()
ARM-SMMU:
- Device-tree binding update:
- Add qcom,sm7150-smmu-v2 for Adreno on SM7150 SoC
- SMMUv2:
- Support for Qualcomm SDM670 (MDSS) and SM7150 SoCs
- SMMUv3:
- Large refactoring of the context descriptor code to move the CD
table into the master, paving the way for '->set_dev_pasid()'
support on non-SVA domains
- Minor cleanups to the SVA code
Intel VT-d:
- Enable debugfs to dump domain attached to a pasid
- Remove an unnecessary inline function
AMD IOMMU:
- Initial patches for SVA support (not complete yet)
S390 IOMMU:
- DMA-API conversion and optimized IOTLB flushing
And some smaller fixes and improvements"
* tag 'iommu-updates-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (102 commits)
iommu/dart: Remove the force_bypass variable
iommu/dart: Call apple_dart_finalize_domain() as part of alloc_paging()
iommu/dart: Convert to domain_alloc_paging()
iommu/dart: Move the blocked domain support to a global static
iommu/dart: Use static global identity domains
iommufd: Convert to alloc_domain_paging()
iommu/vt-d: Use ops->blocked_domain
iommu/vt-d: Update the definition of the blocking domain
iommu: Move IOMMU_DOMAIN_BLOCKED global statics to ops->blocked_domain
Revert "iommu/vt-d: Remove unused function"
iommu/amd: Remove DMA_FQ type from domain allocation path
iommu: change iommu_map_sgtable to return signed values
iommu/virtio: Add __counted_by for struct viommu_request and use struct_size()
iommu/vt-d: debugfs: Support dumping a specified page table
iommu/vt-d: debugfs: Create/remove debugfs file per {device, pasid}
iommu/vt-d: debugfs: Dump entry pointing to huge page
iommu/vt-d: Remove unused function
iommu/arm-smmu-v3-sva: Remove bond refcount
iommu/arm-smmu-v3-sva: Remove unused iommu_sva handle
iommu/arm-smmu-v3: Rename cdcfg to cd_table
...
This commit is contained in:
commit
4bbdb725a3
58 files changed
+2147
-3917
No files matched your search
@@ -2227,7 +2227,7 @@
|
||||
forcing Dual Address Cycle for PCI cards supporting
|
||||
greater than 32-bit addressing.
|
||||
|
||||
iommu.strict= [ARM64, X86] Configure TLB invalidation behaviour
|
||||
iommu.strict= [ARM64, X86, S390] Configure TLB invalidation behaviour
|
||||
Format: { "0" | "1" }
|
||||
0 - Lazy mode.
|
||||
Request that DMA unmap operations use deferred
|
||||
@@ -5694,9 +5694,10 @@
|
||||
s390_iommu= [HW,S390]
|
||||
Set s390 IOTLB flushing mode
|
||||
strict
|
||||
With strict flushing every unmap operation will result in
|
||||
an IOTLB flush. Default is lazy flushing before reuse,
|
||||
which is faster.
|
||||
With strict flushing every unmap operation will result
|
||||
in an IOTLB flush. Default is lazy flushing before
|
||||
reuse, which is faster. Deprecated, equivalent to
|
||||
iommu.strict=1.
|
||||
|
||||
s390_iommu_aperture= [KNL,S390]
|
||||
Specifies the size of the per device DMA address space
|
||||
|
||||
@@ -110,6 +110,7 @@ properties:
|
||||
- qcom,sdm630-smmu-v2
|
||||
- qcom,sdm845-smmu-v2
|
||||
- qcom,sm6350-smmu-v2
|
||||
- qcom,sm7150-smmu-v2
|
||||
- const: qcom,adreno-smmu
|
||||
- const: qcom,smmu-v2
|
||||
- description: Qcom Adreno GPUs on Google Cheza platform
|
||||
@@ -409,6 +410,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm6350-smmu-v2
|
||||
- qcom,sm7150-smmu-v2
|
||||
- qcom,sm8150-smmu-500
|
||||
- qcom,sm8250-smmu-500
|
||||
then:
|
||||
|
||||
@@ -1076,7 +1076,6 @@ CONFIG_QCOM_IPCC=y
|
||||
CONFIG_OMAP_IOMMU=y
|
||||
CONFIG_OMAP_IOMMU_DEBUG=y
|
||||
CONFIG_ROCKCHIP_IOMMU=y
|
||||
CONFIG_TEGRA_IOMMU_GART=y
|
||||
CONFIG_TEGRA_IOMMU_SMMU=y
|
||||
CONFIG_EXYNOS_IOMMU=y
|
||||
CONFIG_QCOM_IOMMU=y
|
||||
|
||||
@@ -292,7 +292,6 @@ CONFIG_CHROME_PLATFORMS=y
|
||||
CONFIG_CROS_EC=y
|
||||
CONFIG_CROS_EC_I2C=m
|
||||
CONFIG_CROS_EC_SPI=m
|
||||
CONFIG_TEGRA_IOMMU_GART=y
|
||||
CONFIG_TEGRA_IOMMU_SMMU=y
|
||||
CONFIG_ARCH_TEGRA_2x_SOC=y
|
||||
CONFIG_ARCH_TEGRA_3x_SOC=y
|
||||
|
||||
+24
-29
@@ -1280,13 +1280,19 @@ struct iommu_table_group_ops spapr_tce_table_group_ops = {
|
||||
/*
|
||||
* A simple iommu_ops to allow less cruft in generic VFIO code.
|
||||
*/
|
||||
static int spapr_tce_blocking_iommu_attach_dev(struct iommu_domain *dom,
|
||||
struct device *dev)
|
||||
static int
|
||||
spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain,
|
||||
struct device *dev)
|
||||
{
|
||||
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
|
||||
struct iommu_group *grp = iommu_group_get(dev);
|
||||
struct iommu_table_group *table_group;
|
||||
int ret = -EINVAL;
|
||||
|
||||
/* At first attach the ownership is already set */
|
||||
if (!domain)
|
||||
return 0;
|
||||
|
||||
if (!grp)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -1297,17 +1303,22 @@ static int spapr_tce_blocking_iommu_attach_dev(struct iommu_domain *dom,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spapr_tce_blocking_iommu_set_platform_dma(struct device *dev)
|
||||
{
|
||||
struct iommu_group *grp = iommu_group_get(dev);
|
||||
struct iommu_table_group *table_group;
|
||||
static const struct iommu_domain_ops spapr_tce_platform_domain_ops = {
|
||||
.attach_dev = spapr_tce_platform_iommu_attach_dev,
|
||||
};
|
||||
|
||||
table_group = iommu_group_get_iommudata(grp);
|
||||
table_group->ops->release_ownership(table_group);
|
||||
}
|
||||
static struct iommu_domain spapr_tce_platform_domain = {
|
||||
.type = IOMMU_DOMAIN_PLATFORM,
|
||||
.ops = &spapr_tce_platform_domain_ops,
|
||||
};
|
||||
|
||||
static const struct iommu_domain_ops spapr_tce_blocking_domain_ops = {
|
||||
.attach_dev = spapr_tce_blocking_iommu_attach_dev,
|
||||
static struct iommu_domain spapr_tce_blocked_domain = {
|
||||
.type = IOMMU_DOMAIN_BLOCKED,
|
||||
/*
|
||||
* FIXME: SPAPR mixes blocked and platform behaviors, the blocked domain
|
||||
* also sets the dma_api ops
|
||||
*/
|
||||
.ops = &spapr_tce_platform_domain_ops,
|
||||
};
|
||||
|
||||
static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap)
|
||||
@@ -1322,22 +1333,6 @@ static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap)
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct iommu_domain *spapr_tce_iommu_domain_alloc(unsigned int type)
|
||||
{
|
||||
struct iommu_domain *dom;
|
||||
|
||||
if (type != IOMMU_DOMAIN_BLOCKED)
|
||||
return NULL;
|
||||
|
||||
dom = kzalloc(sizeof(*dom), GFP_KERNEL);
|
||||
if (!dom)
|
||||
return NULL;
|
||||
|
||||
dom->ops = &spapr_tce_blocking_domain_ops;
|
||||
|
||||
return dom;
|
||||
}
|
||||
|
||||
static struct iommu_device *spapr_tce_iommu_probe_device(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
@@ -1371,12 +1366,12 @@ static struct iommu_group *spapr_tce_iommu_device_group(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct iommu_ops spapr_tce_iommu_ops = {
|
||||
.default_domain = &spapr_tce_platform_domain,
|
||||
.blocked_domain = &spapr_tce_blocked_domain,
|
||||
.capable = spapr_tce_iommu_capable,
|
||||
.domain_alloc = spapr_tce_iommu_domain_alloc,
|
||||
.probe_device = spapr_tce_iommu_probe_device,
|
||||
.release_device = spapr_tce_iommu_release_device,
|
||||
.device_group = spapr_tce_iommu_device_group,
|
||||
.set_platform_dma_ops = spapr_tce_blocking_iommu_set_platform_dma,
|
||||
};
|
||||
|
||||
static struct attribute *spapr_tce_iommu_attrs[] = {
|
||||
|
||||
@@ -159,13 +159,6 @@ struct zpci_dev {
|
||||
unsigned long *dma_table;
|
||||
int tlb_refresh;
|
||||
|
||||
spinlock_t iommu_bitmap_lock;
|
||||
unsigned long *iommu_bitmap;
|
||||
unsigned long *lazy_bitmap;
|
||||
unsigned long iommu_size;
|
||||
unsigned long iommu_pages;
|
||||
unsigned int next_bit;
|
||||
|
||||
struct iommu_device iommu_dev; /* IOMMU core handle */
|
||||
|
||||
char res_name[16];
|
||||
@@ -180,10 +173,6 @@ struct zpci_dev {
|
||||
struct zpci_fmb *fmb;
|
||||
u16 fmb_update; /* update interval */
|
||||
u16 fmb_length;
|
||||
/* software counters */
|
||||
atomic64_t allocated_pages;
|
||||
atomic64_t mapped_pages;
|
||||
atomic64_t unmapped_pages;
|
||||
|
||||
u8 version;
|
||||
enum pci_bus_speed max_bus_speed;
|
||||
|
||||
@@ -50,6 +50,9 @@ struct clp_fh_list_entry {
|
||||
#define CLP_UTIL_STR_LEN 64
|
||||
#define CLP_PFIP_NR_SEGMENTS 4
|
||||
|
||||
/* PCI function type numbers */
|
||||
#define PCI_FUNC_TYPE_ISM 0x5 /* ISM device */
|
||||
|
||||
extern bool zpci_unique_uid;
|
||||
|
||||
struct clp_rsp_slpc_pci {
|
||||
|
||||
@@ -82,117 +82,16 @@ enum zpci_ioat_dtype {
|
||||
#define ZPCI_TABLE_VALID_MASK 0x20
|
||||
#define ZPCI_TABLE_PROT_MASK 0x200
|
||||
|
||||
static inline unsigned int calc_rtx(dma_addr_t ptr)
|
||||
{
|
||||
return ((unsigned long) ptr >> ZPCI_RT_SHIFT) & ZPCI_INDEX_MASK;
|
||||
}
|
||||
struct zpci_iommu_ctrs {
|
||||
atomic64_t mapped_pages;
|
||||
atomic64_t unmapped_pages;
|
||||
atomic64_t global_rpcits;
|
||||
atomic64_t sync_map_rpcits;
|
||||
atomic64_t sync_rpcits;
|
||||
};
|
||||
|
||||
static inline unsigned int calc_sx(dma_addr_t ptr)
|
||||
{
|
||||
return ((unsigned long) ptr >> ZPCI_ST_SHIFT) & ZPCI_INDEX_MASK;
|
||||
}
|
||||
|
||||
static inline unsigned int calc_px(dma_addr_t ptr)
|
||||
{
|
||||
return ((unsigned long) ptr >> PAGE_SHIFT) & ZPCI_PT_MASK;
|
||||
}
|
||||
|
||||
static inline void set_pt_pfaa(unsigned long *entry, phys_addr_t pfaa)
|
||||
{
|
||||
*entry &= ZPCI_PTE_FLAG_MASK;
|
||||
*entry |= (pfaa & ZPCI_PTE_ADDR_MASK);
|
||||
}
|
||||
|
||||
static inline void set_rt_sto(unsigned long *entry, phys_addr_t sto)
|
||||
{
|
||||
*entry &= ZPCI_RTE_FLAG_MASK;
|
||||
*entry |= (sto & ZPCI_RTE_ADDR_MASK);
|
||||
*entry |= ZPCI_TABLE_TYPE_RTX;
|
||||
}
|
||||
|
||||
static inline void set_st_pto(unsigned long *entry, phys_addr_t pto)
|
||||
{
|
||||
*entry &= ZPCI_STE_FLAG_MASK;
|
||||
*entry |= (pto & ZPCI_STE_ADDR_MASK);
|
||||
*entry |= ZPCI_TABLE_TYPE_SX;
|
||||
}
|
||||
|
||||
static inline void validate_rt_entry(unsigned long *entry)
|
||||
{
|
||||
*entry &= ~ZPCI_TABLE_VALID_MASK;
|
||||
*entry &= ~ZPCI_TABLE_OFFSET_MASK;
|
||||
*entry |= ZPCI_TABLE_VALID;
|
||||
*entry |= ZPCI_TABLE_LEN_RTX;
|
||||
}
|
||||
|
||||
static inline void validate_st_entry(unsigned long *entry)
|
||||
{
|
||||
*entry &= ~ZPCI_TABLE_VALID_MASK;
|
||||
*entry |= ZPCI_TABLE_VALID;
|
||||
}
|
||||
|
||||
static inline void invalidate_pt_entry(unsigned long *entry)
|
||||
{
|
||||
WARN_ON_ONCE((*entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_INVALID);
|
||||
*entry &= ~ZPCI_PTE_VALID_MASK;
|
||||
*entry |= ZPCI_PTE_INVALID;
|
||||
}
|
||||
|
||||
static inline void validate_pt_entry(unsigned long *entry)
|
||||
{
|
||||
WARN_ON_ONCE((*entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID);
|
||||
*entry &= ~ZPCI_PTE_VALID_MASK;
|
||||
*entry |= ZPCI_PTE_VALID;
|
||||
}
|
||||
|
||||
static inline void entry_set_protected(unsigned long *entry)
|
||||
{
|
||||
*entry &= ~ZPCI_TABLE_PROT_MASK;
|
||||
*entry |= ZPCI_TABLE_PROTECTED;
|
||||
}
|
||||
|
||||
static inline void entry_clr_protected(unsigned long *entry)
|
||||
{
|
||||
*entry &= ~ZPCI_TABLE_PROT_MASK;
|
||||
*entry |= ZPCI_TABLE_UNPROTECTED;
|
||||
}
|
||||
|
||||
static inline int reg_entry_isvalid(unsigned long entry)
|
||||
{
|
||||
return (entry & ZPCI_TABLE_VALID_MASK) == ZPCI_TABLE_VALID;
|
||||
}
|
||||
|
||||
static inline int pt_entry_isvalid(unsigned long entry)
|
||||
{
|
||||
return (entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID;
|
||||
}
|
||||
|
||||
static inline unsigned long *get_rt_sto(unsigned long entry)
|
||||
{
|
||||
if ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RTX)
|
||||
return phys_to_virt(entry & ZPCI_RTE_ADDR_MASK);
|
||||
else
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static inline unsigned long *get_st_pto(unsigned long entry)
|
||||
{
|
||||
if ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_SX)
|
||||
return phys_to_virt(entry & ZPCI_STE_ADDR_MASK);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Prototypes */
|
||||
void dma_free_seg_table(unsigned long);
|
||||
unsigned long *dma_alloc_cpu_table(gfp_t gfp);
|
||||
void dma_cleanup_tables(unsigned long *);
|
||||
unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr,
|
||||
gfp_t gfp);
|
||||
void dma_update_cpu_trans(unsigned long *entry, phys_addr_t page_addr, int flags);
|
||||
|
||||
extern const struct dma_map_ops s390_pci_dma_ops;
|
||||
struct zpci_dev;
|
||||
|
||||
struct zpci_iommu_ctrs *zpci_get_iommu_ctrs(struct zpci_dev *zdev);
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
# Makefile for the s390 PCI subsystem.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_dma.o pci_clp.o pci_sysfs.o \
|
||||
obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_clp.o pci_sysfs.o \
|
||||
pci_event.o pci_debug.o pci_insn.o pci_mmio.o \
|
||||
pci_bus.o pci_kvm_hook.o
|
||||
obj-$(CONFIG_PCI_IOV) += pci_iov.o
|
||||
+15
-20
@@ -124,7 +124,11 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
|
||||
|
||||
WARN_ON_ONCE(iota & 0x3fff);
|
||||
fib.pba = base;
|
||||
fib.pal = limit;
|
||||
/* Work around off by one in ISM virt device */
|
||||
if (zdev->pft == PCI_FUNC_TYPE_ISM && limit > base)
|
||||
fib.pal = limit + (1 << 12);
|
||||
else
|
||||
fib.pal = limit;
|
||||
fib.iota = iota | ZPCI_IOTA_RTTO_FLAG;
|
||||
fib.gd = zdev->gisa;
|
||||
cc = zpci_mod_fc(req, &fib, status);
|
||||
@@ -153,6 +157,7 @@ int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
|
||||
int zpci_fmb_enable_device(struct zpci_dev *zdev)
|
||||
{
|
||||
u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_SET_MEASURE);
|
||||
struct zpci_iommu_ctrs *ctrs;
|
||||
struct zpci_fib fib = {0};
|
||||
u8 cc, status;
|
||||
|
||||
@@ -165,9 +170,15 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)
|
||||
WARN_ON((u64) zdev->fmb & 0xf);
|
||||
|
||||
/* reset software counters */
|
||||
atomic64_set(&zdev->allocated_pages, 0);
|
||||
atomic64_set(&zdev->mapped_pages, 0);
|
||||
atomic64_set(&zdev->unmapped_pages, 0);
|
||||
ctrs = zpci_get_iommu_ctrs(zdev);
|
||||
if (ctrs) {
|
||||
atomic64_set(&ctrs->mapped_pages, 0);
|
||||
atomic64_set(&ctrs->unmapped_pages, 0);
|
||||
atomic64_set(&ctrs->global_rpcits, 0);
|
||||
atomic64_set(&ctrs->sync_map_rpcits, 0);
|
||||
atomic64_set(&ctrs->sync_rpcits, 0);
|
||||
}
|
||||
|
||||
|
||||
fib.fmb_addr = virt_to_phys(zdev->fmb);
|
||||
fib.gd = zdev->gisa;
|
||||
@@ -582,7 +593,6 @@ int pcibios_device_add(struct pci_dev *pdev)
|
||||
pdev->no_vf_scan = 1;
|
||||
|
||||
pdev->dev.groups = zpci_attr_groups;
|
||||
pdev->dev.dma_ops = &s390_pci_dma_ops;
|
||||
zpci_map_resources(pdev);
|
||||
|
||||
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
|
||||
@@ -756,8 +766,6 @@ int zpci_hot_reset_device(struct zpci_dev *zdev)
|
||||
if (zdev->dma_table)
|
||||
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
|
||||
virt_to_phys(zdev->dma_table), &status);
|
||||
else
|
||||
rc = zpci_dma_init_device(zdev);
|
||||
if (rc) {
|
||||
zpci_disable_device(zdev);
|
||||
return rc;
|
||||
@@ -865,11 +873,6 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
|
||||
if (zdev->zbus->bus)
|
||||
zpci_bus_remove_device(zdev, false);
|
||||
|
||||
if (zdev->dma_table) {
|
||||
rc = zpci_dma_exit_device(zdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
if (zdev_enabled(zdev)) {
|
||||
rc = zpci_disable_device(zdev);
|
||||
if (rc)
|
||||
@@ -918,8 +921,6 @@ void zpci_release_device(struct kref *kref)
|
||||
if (zdev->zbus->bus)
|
||||
zpci_bus_remove_device(zdev, false);
|
||||
|
||||
if (zdev->dma_table)
|
||||
zpci_dma_exit_device(zdev);
|
||||
if (zdev_enabled(zdev))
|
||||
zpci_disable_device(zdev);
|
||||
|
||||
@@ -1109,10 +1110,6 @@ static int __init pci_base_init(void)
|
||||
if (rc)
|
||||
goto out_irq;
|
||||
|
||||
rc = zpci_dma_init();
|
||||
if (rc)
|
||||
goto out_dma;
|
||||
|
||||
rc = clp_scan_pci_devices();
|
||||
if (rc)
|
||||
goto out_find;
|
||||
@@ -1122,8 +1119,6 @@ static int __init pci_base_init(void)
|
||||
return 0;
|
||||
|
||||
out_find:
|
||||
zpci_dma_exit();
|
||||
out_dma:
|
||||
zpci_irq_exit();
|
||||
out_irq:
|
||||
zpci_mem_exit();
|
||||
|
||||
@@ -47,11 +47,6 @@ static int zpci_bus_prepare_device(struct zpci_dev *zdev)
|
||||
rc = zpci_enable_device(zdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = zpci_dma_init_device(zdev);
|
||||
if (rc) {
|
||||
zpci_disable_device(zdev);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (!zdev->has_resources) {
|
||||
|
||||
@@ -53,9 +53,11 @@ static char *pci_fmt3_names[] = {
|
||||
};
|
||||
|
||||
static char *pci_sw_names[] = {
|
||||
"Allocated pages",
|
||||
"Mapped pages",
|
||||
"Unmapped pages",
|
||||
"Global RPCITs",
|
||||
"Sync Map RPCITs",
|
||||
"Sync RPCITs",
|
||||
};
|
||||
|
||||
static void pci_fmb_show(struct seq_file *m, char *name[], int length,
|
||||
@@ -69,10 +71,14 @@ static void pci_fmb_show(struct seq_file *m, char *name[], int length,
|
||||
|
||||
static void pci_sw_counter_show(struct seq_file *m)
|
||||
{
|
||||
struct zpci_dev *zdev = m->private;
|
||||
atomic64_t *counter = &zdev->allocated_pages;
|
||||
struct zpci_iommu_ctrs *ctrs = zpci_get_iommu_ctrs(m->private);
|
||||
atomic64_t *counter;
|
||||
int i;
|
||||
|
||||
if (!ctrs)
|
||||
return;
|
||||
|
||||
counter = &ctrs->mapped_pages;
|
||||
for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
|
||||
seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
|
||||
atomic64_read(counter));
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -59,9 +59,16 @@ static inline bool ers_result_indicates_abort(pci_ers_result_t ers_res)
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_passed_through(struct zpci_dev *zdev)
|
||||
static bool is_passed_through(struct pci_dev *pdev)
|
||||
{
|
||||
return zdev->s390_domain;
|
||||
struct zpci_dev *zdev = to_zpci(pdev);
|
||||
bool ret;
|
||||
|
||||
mutex_lock(&zdev->kzdev_lock);
|
||||
ret = !!zdev->kzdev;
|
||||
mutex_unlock(&zdev->kzdev_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_driver_supported(struct pci_driver *driver)
|
||||
@@ -176,7 +183,7 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
|
||||
}
|
||||
pdev->error_state = pci_channel_io_frozen;
|
||||
|
||||
if (is_passed_through(to_zpci(pdev))) {
|
||||
if (is_passed_through(pdev)) {
|
||||
pr_info("%s: Cannot be recovered in the host because it is a pass-through device\n",
|
||||
pci_name(pdev));
|
||||
goto out_unlock;
|
||||
@@ -239,7 +246,7 @@ static void zpci_event_io_failure(struct pci_dev *pdev, pci_channel_state_t es)
|
||||
* we will inject the error event and let the guest recover the device
|
||||
* itself.
|
||||
*/
|
||||
if (is_passed_through(to_zpci(pdev)))
|
||||
if (is_passed_through(pdev))
|
||||
goto out;
|
||||
driver = to_pci_driver(pdev->dev.driver);
|
||||
if (driver && driver->err_handler && driver->err_handler->error_detected)
|
||||
@@ -306,8 +313,6 @@ static void zpci_event_hard_deconfigured(struct zpci_dev *zdev, u32 fh)
|
||||
/* Even though the device is already gone we still
|
||||
* need to free zPCI resources as part of the disable.
|
||||
*/
|
||||
if (zdev->dma_table)
|
||||
zpci_dma_exit_device(zdev);
|
||||
if (zdev_enabled(zdev))
|
||||
zpci_disable_device(zdev);
|
||||
zdev->state = ZPCI_FN_STATE_STANDBY;
|
||||
|
||||
@@ -56,6 +56,7 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct zpci_dev *zdev = to_zpci(pdev);
|
||||
int ret = 0;
|
||||
u8 status;
|
||||
|
||||
/* Can't use device_remove_self() here as that would lead us to lock
|
||||
* the pci_rescan_remove_lock while holding the device' kernfs lock.
|
||||
@@ -82,12 +83,6 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
|
||||
pci_lock_rescan_remove();
|
||||
if (pci_dev_is_added(pdev)) {
|
||||
pci_stop_and_remove_bus_device(pdev);
|
||||
if (zdev->dma_table) {
|
||||
ret = zpci_dma_exit_device(zdev);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (zdev_enabled(zdev)) {
|
||||
ret = zpci_disable_device(zdev);
|
||||
/*
|
||||
@@ -105,14 +100,16 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
|
||||
ret = zpci_enable_device(zdev);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = zpci_dma_init_device(zdev);
|
||||
if (ret) {
|
||||
zpci_disable_device(zdev);
|
||||
goto out;
|
||||
|
||||
if (zdev->dma_table) {
|
||||
ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
|
||||
virt_to_phys(zdev->dma_table), &status);
|
||||
if (ret)
|
||||
zpci_disable_device(zdev);
|
||||
}
|
||||
pci_rescan_bus(zdev->zbus->bus);
|
||||
}
|
||||
out:
|
||||
pci_rescan_bus(zdev->zbus->bus);
|
||||
pci_unlock_rescan_remove();
|
||||
if (kn)
|
||||
sysfs_unbreak_active_protection(kn);
|
||||
|
||||
+2
-13
@@ -95,7 +95,7 @@ config IOMMU_DEBUGFS
|
||||
choice
|
||||
prompt "IOMMU default domain type"
|
||||
depends on IOMMU_API
|
||||
default IOMMU_DEFAULT_DMA_LAZY if X86
|
||||
default IOMMU_DEFAULT_DMA_LAZY if X86 || S390
|
||||
default IOMMU_DEFAULT_DMA_STRICT
|
||||
help
|
||||
Choose the type of IOMMU domain used to manage DMA API usage by
|
||||
@@ -150,7 +150,7 @@ config OF_IOMMU
|
||||
|
||||
# IOMMU-agnostic DMA-mapping layer
|
||||
config IOMMU_DMA
|
||||
def_bool ARM64 || X86
|
||||
def_bool ARM64 || X86 || S390
|
||||
select DMA_OPS
|
||||
select IOMMU_API
|
||||
select IOMMU_IOVA
|
||||
@@ -240,17 +240,6 @@ config SUN50I_IOMMU
|
||||
help
|
||||
Support for the IOMMU introduced in the Allwinner H6 SoCs.
|
||||
|
||||
config TEGRA_IOMMU_GART
|
||||
bool "Tegra GART IOMMU Support"
|
||||
depends on ARCH_TEGRA_2x_SOC
|
||||
depends on TEGRA_MC
|
||||
select IOMMU_API
|
||||
help
|
||||
Enables support for remapping discontiguous physical memory
|
||||
shared with the operating system into contiguous I/O virtual
|
||||
space through the GART (Graphics Address Relocation Table)
|
||||
hardware included on Tegra SoCs.
|
||||
|
||||
config TEGRA_IOMMU_SMMU
|
||||
bool "NVIDIA Tegra SMMU Support"
|
||||
depends on ARCH_TEGRA
|
||||
|
||||
@@ -20,7 +20,6 @@ obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
|
||||
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
|
||||
obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
|
||||
obj-$(CONFIG_SUN50I_IOMMU) += sun50i-iommu.o
|
||||
obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
|
||||
obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
|
||||
obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
|
||||
obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
|
||||
|
||||
@@ -23,15 +23,6 @@ config AMD_IOMMU
|
||||
your BIOS for an option to enable it or if you have an IVRS ACPI
|
||||
table.
|
||||
|
||||
config AMD_IOMMU_V2
|
||||
tristate "AMD IOMMU Version 2 driver"
|
||||
depends on AMD_IOMMU
|
||||
select MMU_NOTIFIER
|
||||
help
|
||||
This option enables support for the AMD IOMMUv2 features of the IOMMU
|
||||
hardware. Select this option if you want to use devices that support
|
||||
the PCI PRI and PASID interface.
|
||||
|
||||
config AMD_IOMMU_DEBUGFS
|
||||
bool "Enable AMD IOMMU internals in DebugFS"
|
||||
depends on AMD_IOMMU && IOMMU_DEBUGFS
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_AMD_IOMMU) += iommu.o init.o quirks.o io_pgtable.o io_pgtable_v2.o
|
||||
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o
|
||||
obj-$(CONFIG_AMD_IOMMU_V2) += iommu_v2.o
|
||||
@@ -38,9 +38,6 @@ extern int amd_iommu_guest_ir;
|
||||
extern enum io_pgtable_fmt amd_iommu_pgtable;
|
||||
extern int amd_iommu_gpt_level;
|
||||
|
||||
/* IOMMUv2 specific functions */
|
||||
struct iommu_domain;
|
||||
|
||||
bool amd_iommu_v2_supported(void);
|
||||
struct amd_iommu *get_amd_iommu(unsigned int idx);
|
||||
u8 amd_iommu_pc_get_max_banks(unsigned int idx);
|
||||
@@ -51,10 +48,10 @@ int amd_iommu_pc_get_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
|
||||
int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
|
||||
u8 fxn, u64 *value);
|
||||
|
||||
int amd_iommu_register_ppr_notifier(struct notifier_block *nb);
|
||||
int amd_iommu_unregister_ppr_notifier(struct notifier_block *nb);
|
||||
void amd_iommu_domain_direct_map(struct iommu_domain *dom);
|
||||
int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids);
|
||||
/* Device capabilities */
|
||||
int amd_iommu_pdev_enable_cap_pri(struct pci_dev *pdev);
|
||||
void amd_iommu_pdev_disable_cap_pri(struct pci_dev *pdev);
|
||||
|
||||
int amd_iommu_flush_page(struct iommu_domain *dom, u32 pasid, u64 address);
|
||||
void amd_iommu_update_and_flush_device_table(struct protection_domain *domain);
|
||||
void amd_iommu_domain_update(struct protection_domain *domain);
|
||||
@@ -87,9 +84,25 @@ static inline bool is_rd890_iommu(struct pci_dev *pdev)
|
||||
(pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
|
||||
}
|
||||
|
||||
static inline bool iommu_feature(struct amd_iommu *iommu, u64 mask)
|
||||
static inline bool check_feature(u64 mask)
|
||||
{
|
||||
return !!(iommu->features & mask);
|
||||
return (amd_iommu_efr & mask);
|
||||
}
|
||||
|
||||
static inline bool check_feature2(u64 mask)
|
||||
{
|
||||
return (amd_iommu_efr2 & mask);
|
||||
}
|
||||
|
||||
static inline int check_feature_gpt_level(void)
|
||||
{
|
||||
return ((amd_iommu_efr >> FEATURE_GATS_SHIFT) & FEATURE_GATS_MASK);
|
||||
}
|
||||
|
||||
static inline bool amd_iommu_gt_ppr_supported(void)
|
||||
{
|
||||
return (check_feature(FEATURE_GT) &&
|
||||
check_feature(FEATURE_PPR));
|
||||
}
|
||||
|
||||
static inline u64 iommu_virt_to_phys(void *vaddr)
|
||||
@@ -105,7 +118,6 @@ static inline void *iommu_phys_to_virt(unsigned long paddr)
|
||||
static inline
|
||||
void amd_iommu_domain_set_pt_root(struct protection_domain *domain, u64 root)
|
||||
{
|
||||
atomic64_set(&domain->iop.pt_root, root);
|
||||
domain->iop.root = (u64 *)(root & PAGE_MASK);
|
||||
domain->iop.mode = root & 7; /* lowest 3 bits encode pgtable mode */
|
||||
}
|
||||
@@ -146,8 +158,5 @@ void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
|
||||
u64 *root, int mode);
|
||||
struct dev_table_entry *get_dev_table(struct amd_iommu *iommu);
|
||||
|
||||
extern u64 amd_iommu_efr;
|
||||
extern u64 amd_iommu_efr2;
|
||||
|
||||
extern bool amd_iommu_snp_en;
|
||||
#endif
|
||||
Loaded 20 of 58 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user