mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branches 'apple/dart', 'arm/smmu/updates', 'arm/smmu/bindings', 'rockchip', 's390', 'core', 'intel/vt-d' and 'amd/amd-vi' into next
This commit is contained in:
@@ -90,6 +90,7 @@ properties:
|
||||
- enum:
|
||||
- qcom,qcm2290-smmu-500
|
||||
- qcom,qcs615-smmu-500
|
||||
- qcom,qcs8300-smmu-500
|
||||
- qcom,sa8255p-smmu-500
|
||||
- qcom,sa8775p-smmu-500
|
||||
- qcom,sar2130p-smmu-500
|
||||
@@ -397,6 +398,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs8300-smmu-500
|
||||
- qcom,sa8775p-smmu-500
|
||||
- qcom,sc7280-smmu-500
|
||||
- qcom,sc8280xp-smmu-500
|
||||
@@ -581,7 +583,6 @@ allOf:
|
||||
- cavium,smmu-v2
|
||||
- marvell,ap806-smmu-500
|
||||
- nvidia,smmu-500
|
||||
- qcom,qcs8300-smmu-500
|
||||
- qcom,qdu1000-smmu-500
|
||||
- qcom,sa8255p-smmu-500
|
||||
- qcom,sc7180-smmu-500
|
||||
|
||||
@@ -22,6 +22,7 @@ properties:
|
||||
- enum:
|
||||
- qcom,msm8916-iommu
|
||||
- qcom,msm8917-iommu
|
||||
- qcom,msm8937-iommu
|
||||
- qcom,msm8953-iommu
|
||||
- const: qcom,msm-iommu-v1
|
||||
- items:
|
||||
|
||||
@@ -144,7 +144,7 @@ struct zpci_dev {
|
||||
u8 util_str_avail : 1;
|
||||
u8 irqs_registered : 1;
|
||||
u8 tid_avail : 1;
|
||||
u8 reserved : 1;
|
||||
u8 rtr_avail : 1; /* Relaxed translation allowed */
|
||||
unsigned int devfn; /* DEVFN part of the RID*/
|
||||
|
||||
u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */
|
||||
@@ -217,6 +217,7 @@ extern struct airq_iv *zpci_aif_sbv;
|
||||
struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
|
||||
int zpci_add_device(struct zpci_dev *zdev);
|
||||
int zpci_enable_device(struct zpci_dev *);
|
||||
int zpci_reenable_device(struct zpci_dev *zdev);
|
||||
int zpci_disable_device(struct zpci_dev *);
|
||||
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
|
||||
int zpci_deconfigure_device(struct zpci_dev *zdev);
|
||||
@@ -245,6 +246,7 @@ void update_uid_checking(bool new);
|
||||
/* IOMMU Interface */
|
||||
int zpci_init_iommu(struct zpci_dev *zdev);
|
||||
void zpci_destroy_iommu(struct zpci_dev *zdev);
|
||||
int zpci_iommu_register_ioat(struct zpci_dev *zdev, u8 *status);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static inline bool zpci_use_mio(struct zpci_dev *zdev)
|
||||
|
||||
@@ -156,7 +156,9 @@ struct clp_rsp_query_pci_grp {
|
||||
u16 : 4;
|
||||
u16 noi : 12; /* number of interrupts */
|
||||
u8 version;
|
||||
u8 : 6;
|
||||
u8 : 2;
|
||||
u8 rtr : 1; /* Relaxed translation requirement */
|
||||
u8 : 3;
|
||||
u8 frame : 1;
|
||||
u8 refresh : 1; /* TLB refresh mode */
|
||||
u16 : 3;
|
||||
|
||||
+2
-15
@@ -433,7 +433,6 @@ static void kvm_s390_pci_dev_release(struct zpci_dev *zdev)
|
||||
static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
|
||||
{
|
||||
struct zpci_dev *zdev = opaque;
|
||||
u8 status;
|
||||
int rc;
|
||||
|
||||
if (!zdev)
|
||||
@@ -480,13 +479,7 @@ static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
|
||||
*/
|
||||
zdev->gisa = (u32)virt_to_phys(&kvm->arch.sie_page2->gisa);
|
||||
|
||||
rc = zpci_enable_device(zdev);
|
||||
if (rc)
|
||||
goto clear_gisa;
|
||||
|
||||
/* Re-register the IOMMU that was already created */
|
||||
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
|
||||
virt_to_phys(zdev->dma_table), &status);
|
||||
rc = zpci_reenable_device(zdev);
|
||||
if (rc)
|
||||
goto clear_gisa;
|
||||
|
||||
@@ -516,7 +509,6 @@ static void kvm_s390_pci_unregister_kvm(void *opaque)
|
||||
{
|
||||
struct zpci_dev *zdev = opaque;
|
||||
struct kvm *kvm;
|
||||
u8 status;
|
||||
|
||||
if (!zdev)
|
||||
return;
|
||||
@@ -550,12 +542,7 @@ static void kvm_s390_pci_unregister_kvm(void *opaque)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (zpci_enable_device(zdev))
|
||||
goto out;
|
||||
|
||||
/* Re-register the IOMMU that was already created */
|
||||
zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
|
||||
virt_to_phys(zdev->dma_table), &status);
|
||||
zpci_reenable_device(zdev);
|
||||
|
||||
out:
|
||||
spin_lock(&kvm->arch.kzdev_list_lock);
|
||||
|
||||
+20
-15
@@ -124,14 +124,13 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
|
||||
struct zpci_fib fib = {0};
|
||||
u8 cc;
|
||||
|
||||
WARN_ON_ONCE(iota & 0x3fff);
|
||||
fib.pba = base;
|
||||
/* 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.iota = iota;
|
||||
fib.gd = zdev->gisa;
|
||||
cc = zpci_mod_fc(req, &fib, status);
|
||||
if (cc)
|
||||
@@ -690,6 +689,23 @@ int zpci_enable_device(struct zpci_dev *zdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(zpci_enable_device);
|
||||
|
||||
int zpci_reenable_device(struct zpci_dev *zdev)
|
||||
{
|
||||
u8 status;
|
||||
int rc;
|
||||
|
||||
rc = zpci_enable_device(zdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = zpci_iommu_register_ioat(zdev, &status);
|
||||
if (rc)
|
||||
zpci_disable_device(zdev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(zpci_reenable_device);
|
||||
|
||||
int zpci_disable_device(struct zpci_dev *zdev)
|
||||
{
|
||||
u32 fh = zdev->fh;
|
||||
@@ -739,7 +755,6 @@ EXPORT_SYMBOL_GPL(zpci_disable_device);
|
||||
*/
|
||||
int zpci_hot_reset_device(struct zpci_dev *zdev)
|
||||
{
|
||||
u8 status;
|
||||
int rc;
|
||||
|
||||
lockdep_assert_held(&zdev->state_lock);
|
||||
@@ -758,19 +773,9 @@ int zpci_hot_reset_device(struct zpci_dev *zdev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = zpci_enable_device(zdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = zpci_reenable_device(zdev);
|
||||
|
||||
if (zdev->dma_table)
|
||||
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
|
||||
virt_to_phys(zdev->dma_table), &status);
|
||||
if (rc) {
|
||||
zpci_disable_device(zdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/dma-direct.h>
|
||||
|
||||
#include <asm/pci_clp.h>
|
||||
#include <asm/pci_dma.h>
|
||||
@@ -283,10 +284,34 @@ static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid)
|
||||
return zbus;
|
||||
}
|
||||
|
||||
static void pci_dma_range_setup(struct pci_dev *pdev)
|
||||
{
|
||||
struct zpci_dev *zdev = to_zpci(pdev);
|
||||
struct bus_dma_region *map;
|
||||
u64 aligned_end;
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
map->cpu_start = 0;
|
||||
map->dma_start = PAGE_ALIGN(zdev->start_dma);
|
||||
aligned_end = PAGE_ALIGN_DOWN(zdev->end_dma + 1);
|
||||
if (aligned_end >= map->dma_start)
|
||||
map->size = aligned_end - map->dma_start;
|
||||
else
|
||||
map->size = 0;
|
||||
WARN_ON_ONCE(map->size == 0);
|
||||
|
||||
pdev->dev.dma_range_map = map;
|
||||
}
|
||||
|
||||
void pcibios_bus_add_device(struct pci_dev *pdev)
|
||||
{
|
||||
struct zpci_dev *zdev = to_zpci(pdev);
|
||||
|
||||
pci_dma_range_setup(pdev);
|
||||
|
||||
/*
|
||||
* With pdev->no_vf_scan the common PCI probing code does not
|
||||
* perform PF/VF linking.
|
||||
|
||||
@@ -112,6 +112,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
|
||||
zdev->version = response->version;
|
||||
zdev->maxstbl = response->maxstbl;
|
||||
zdev->dtsm = response->dtsm;
|
||||
zdev->rtr_avail = response->rtr;
|
||||
|
||||
switch (response->version) {
|
||||
case 1:
|
||||
|
||||
@@ -52,7 +52,6 @@ static DEVICE_ATTR_RO(mio_enabled);
|
||||
|
||||
static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
|
||||
{
|
||||
u8 status;
|
||||
int ret;
|
||||
|
||||
pci_stop_and_remove_bus_device(pdev);
|
||||
@@ -70,16 +69,8 @@ static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = zpci_enable_device(zdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = zpci_reenable_device(zdev);
|
||||
|
||||
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);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ void acpi_arch_dma_setup(struct device *dev)
|
||||
else
|
||||
end = (1ULL << 32) - 1;
|
||||
|
||||
if (dev->dma_range_map) {
|
||||
dev_dbg(dev, "dma_range_map already set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = acpi_dma_get_range(dev, &map);
|
||||
if (!ret && map) {
|
||||
end = dma_range_map_max(map);
|
||||
|
||||
@@ -1632,13 +1632,6 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
|
||||
err = viot_iommu_configure(dev);
|
||||
mutex_unlock(&iommu_probe_device_lock);
|
||||
|
||||
/*
|
||||
* If we have reason to believe the IOMMU driver missed the initial
|
||||
* iommu_probe_device() call for dev, replay it to get things in order.
|
||||
*/
|
||||
if (!err && dev->bus)
|
||||
err = iommu_probe_device(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -364,7 +364,8 @@ static int amba_dma_configure(struct device *dev)
|
||||
ret = acpi_dma_configure(dev, attr);
|
||||
}
|
||||
|
||||
if (!ret && !drv->driver_managed_dma) {
|
||||
/* @drv may not be valid when we're called from the IOMMU layer */
|
||||
if (!ret && dev->driver && !drv->driver_managed_dma) {
|
||||
ret = iommu_device_use_default_domain(dev);
|
||||
if (ret)
|
||||
arch_teardown_dma_ops(dev);
|
||||
|
||||
@@ -1451,7 +1451,8 @@ static int platform_dma_configure(struct device *dev)
|
||||
attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
|
||||
ret = acpi_dma_configure(dev, attr);
|
||||
}
|
||||
if (ret || drv->driver_managed_dma)
|
||||
/* @drv may not be valid when we're called from the IOMMU layer */
|
||||
if (ret || !dev->driver || drv->driver_managed_dma)
|
||||
return ret;
|
||||
|
||||
ret = iommu_device_use_default_domain(dev);
|
||||
|
||||
@@ -153,7 +153,8 @@ static int fsl_mc_dma_configure(struct device *dev)
|
||||
else
|
||||
ret = acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
|
||||
|
||||
if (!ret && !mc_drv->driver_managed_dma) {
|
||||
/* @mc_drv may not be valid when we're called from the IOMMU layer */
|
||||
if (!ret && dev->driver && !mc_drv->driver_managed_dma) {
|
||||
ret = iommu_device_use_default_domain(dev);
|
||||
if (ret)
|
||||
arch_teardown_dma_ops(dev);
|
||||
|
||||
+2
-1
@@ -360,7 +360,8 @@ static int cdx_dma_configure(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!ret && !cdx_drv->driver_managed_dma) {
|
||||
/* @cdx_drv may not be valid when we're called from the IOMMU layer */
|
||||
if (!ret && dev->driver && !cdx_drv->driver_managed_dma) {
|
||||
ret = iommu_device_use_default_domain(dev);
|
||||
if (ret)
|
||||
arch_teardown_dma_ops(dev);
|
||||
|
||||
@@ -154,7 +154,6 @@ config IOMMU_DMA
|
||||
select DMA_OPS_HELPERS
|
||||
select IOMMU_API
|
||||
select IOMMU_IOVA
|
||||
select IRQ_MSI_IOMMU
|
||||
select NEED_SG_DMA_LENGTH
|
||||
select NEED_SG_DMA_FLAGS if SWIOTLB
|
||||
|
||||
@@ -483,8 +482,7 @@ config MTK_IOMMU
|
||||
|
||||
config MTK_IOMMU_V1
|
||||
tristate "MediaTek IOMMU Version 1 (M4U gen1) Support"
|
||||
depends on ARM
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
|
||||
select ARM_DMA_USE_IOMMU
|
||||
select IOMMU_API
|
||||
select MEMORY
|
||||
|
||||
@@ -47,7 +47,6 @@ extern unsigned long amd_iommu_pgsize_bitmap;
|
||||
/* Protection domain ops */
|
||||
void amd_iommu_init_identity_domain(void);
|
||||
struct protection_domain *protection_domain_alloc(void);
|
||||
void protection_domain_free(struct protection_domain *domain);
|
||||
struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
|
||||
struct mm_struct *mm);
|
||||
void amd_iommu_domain_free(struct iommu_domain *dom);
|
||||
@@ -176,12 +175,11 @@ void amd_iommu_apply_ivrs_quirks(void);
|
||||
#else
|
||||
static inline void amd_iommu_apply_ivrs_quirks(void) { }
|
||||
#endif
|
||||
struct dev_table_entry *amd_iommu_get_ivhd_dte_flags(u16 segid, u16 devid);
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
struct dev_table_entry *amd_iommu_get_ivhd_dte_flags(u16 segid, u16 devid);
|
||||
struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid);
|
||||
|
||||
#endif /* AMD_IOMMU_H */
|
||||
|
||||
@@ -112,6 +112,10 @@
|
||||
#define FEATURE_SNPAVICSUP_GAM(x) \
|
||||
(FIELD_GET(FEATURE_SNPAVICSUP, x) == 0x1)
|
||||
|
||||
#define FEATURE_NUM_INT_REMAP_SUP GENMASK_ULL(9, 8)
|
||||
#define FEATURE_NUM_INT_REMAP_SUP_2K(x) \
|
||||
(FIELD_GET(FEATURE_NUM_INT_REMAP_SUP, x) == 0x1)
|
||||
|
||||
/* Note:
|
||||
* The current driver only support 16-bit PASID.
|
||||
* Currently, hardware only implement upto 16-bit PASID
|
||||
@@ -175,13 +179,16 @@
|
||||
#define CONTROL_GAM_EN 25
|
||||
#define CONTROL_GALOG_EN 28
|
||||
#define CONTROL_GAINT_EN 29
|
||||
#define CONTROL_NUM_INT_REMAP_MODE 43
|
||||
#define CONTROL_NUM_INT_REMAP_MODE_MASK 0x03
|
||||
#define CONTROL_NUM_INT_REMAP_MODE_2K 0x01
|
||||
#define CONTROL_EPH_EN 45
|
||||
#define CONTROL_XT_EN 50
|
||||
#define CONTROL_INTCAPXT_EN 51
|
||||
#define CONTROL_IRTCACHEDIS 59
|
||||
#define CONTROL_SNPAVIC_EN 61
|
||||
|
||||
#define CTRL_INV_TO_MASK (7 << CONTROL_INV_TIMEOUT)
|
||||
#define CTRL_INV_TO_MASK 7
|
||||
#define CTRL_INV_TO_NONE 0
|
||||
#define CTRL_INV_TO_1MS 1
|
||||
#define CTRL_INV_TO_10MS 2
|
||||
@@ -309,15 +316,13 @@
|
||||
#define DTE_IRQ_REMAP_INTCTL (2ULL << 60)
|
||||
#define DTE_IRQ_REMAP_ENABLE 1ULL
|
||||
|
||||
/*
|
||||
* AMD IOMMU hardware only support 512 IRTEs despite
|
||||
* the architectural limitation of 2048 entries.
|
||||
*/
|
||||
#define DTE_INTTAB_ALIGNMENT 128
|
||||
#define DTE_INTTABLEN_VALUE 9ULL
|
||||
#define DTE_INTTABLEN (DTE_INTTABLEN_VALUE << 1)
|
||||
#define DTE_INTTABLEN_MASK (0xfULL << 1)
|
||||
#define MAX_IRQS_PER_TABLE (1 << DTE_INTTABLEN_VALUE)
|
||||
#define DTE_INTTABLEN_VALUE_512 9ULL
|
||||
#define DTE_INTTABLEN_512 (DTE_INTTABLEN_VALUE_512 << 1)
|
||||
#define MAX_IRQS_PER_TABLE_512 BIT(DTE_INTTABLEN_VALUE_512)
|
||||
#define DTE_INTTABLEN_VALUE_2K 11ULL
|
||||
#define DTE_INTTABLEN_2K (DTE_INTTABLEN_VALUE_2K << 1)
|
||||
#define MAX_IRQS_PER_TABLE_2K BIT(DTE_INTTABLEN_VALUE_2K)
|
||||
|
||||
#define PAGE_MODE_NONE 0x00
|
||||
#define PAGE_MODE_1_LEVEL 0x01
|
||||
@@ -492,9 +497,6 @@ extern const struct iommu_ops amd_iommu_ops;
|
||||
/* IVRS indicates that pre-boot remapping was enabled */
|
||||
extern bool amdr_ivrs_remap_support;
|
||||
|
||||
/* kmem_cache to get tables with 128 byte alignement */
|
||||
extern struct kmem_cache *amd_iommu_irq_cache;
|
||||
|
||||
#define PCI_SBDF_TO_SEGID(sbdf) (((sbdf) >> 16) & 0xffff)
|
||||
#define PCI_SBDF_TO_DEVID(sbdf) ((sbdf) & 0xffff)
|
||||
#define PCI_SEG_DEVID_TO_SBDF(seg, devid) ((((u32)(seg) & 0xffff) << 16) | \
|
||||
@@ -851,6 +853,7 @@ struct iommu_dev_data {
|
||||
struct device *dev;
|
||||
u16 devid; /* PCI Device ID */
|
||||
|
||||
unsigned int max_irqs; /* Maximum IRQs supported by device */
|
||||
u32 max_pasids; /* Max supported PASIDs */
|
||||
u32 flags; /* Holds AMD_IOMMU_DEVICE_FLAG_<*> */
|
||||
int ats_qdep;
|
||||
@@ -928,9 +931,6 @@ struct unity_map_entry {
|
||||
* Data structures for device handling
|
||||
*/
|
||||
|
||||
/* size of the dma_ops aperture as power of 2 */
|
||||
extern unsigned amd_iommu_aperture_order;
|
||||
|
||||
extern bool amd_iommu_force_isolation;
|
||||
|
||||
/* Max levels of glxval supported */
|
||||
|
||||
+28
-41
@@ -12,7 +12,6 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/msi.h>
|
||||
@@ -219,7 +218,6 @@ static bool __initdata cmdline_maps;
|
||||
static enum iommu_init_state init_state = IOMMU_START_STATE;
|
||||
|
||||
static int amd_iommu_enable_interrupts(void);
|
||||
static int __init iommu_go_to_state(enum iommu_init_state state);
|
||||
static void init_device_table_dma(struct amd_iommu_pci_seg *pci_seg);
|
||||
|
||||
static bool amd_iommu_pre_enabled = true;
|
||||
@@ -412,33 +410,26 @@ static void iommu_set_device_table(struct amd_iommu *iommu)
|
||||
&entry, sizeof(entry));
|
||||
}
|
||||
|
||||
/* Generic functions to enable/disable certain features of the IOMMU. */
|
||||
void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
|
||||
static void iommu_feature_set(struct amd_iommu *iommu, u64 val, u64 mask, u8 shift)
|
||||
{
|
||||
u64 ctrl;
|
||||
|
||||
ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||
ctrl |= (1ULL << bit);
|
||||
mask <<= shift;
|
||||
ctrl &= ~mask;
|
||||
ctrl |= (val << shift) & mask;
|
||||
writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||
}
|
||||
|
||||
/* Generic functions to enable/disable certain features of the IOMMU. */
|
||||
void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
|
||||
{
|
||||
iommu_feature_set(iommu, 1ULL, 1ULL, bit);
|
||||
}
|
||||
|
||||
static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
|
||||
{
|
||||
u64 ctrl;
|
||||
|
||||
ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||
ctrl &= ~(1ULL << bit);
|
||||
writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||
}
|
||||
|
||||
static void iommu_set_inv_tlb_timeout(struct amd_iommu *iommu, int timeout)
|
||||
{
|
||||
u64 ctrl;
|
||||
|
||||
ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||
ctrl &= ~CTRL_INV_TO_MASK;
|
||||
ctrl |= (timeout << CONTROL_INV_TIMEOUT) & CTRL_INV_TO_MASK;
|
||||
writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||
iommu_feature_set(iommu, 0ULL, 1ULL, bit);
|
||||
}
|
||||
|
||||
/* Function to enable the hardware */
|
||||
@@ -1069,7 +1060,8 @@ static bool __copy_device_table(struct amd_iommu *iommu)
|
||||
int_tab_len = old_devtb[devid].data[2] & DTE_INTTABLEN_MASK;
|
||||
if (irq_v && (int_ctl || int_tab_len)) {
|
||||
if ((int_ctl != DTE_IRQ_REMAP_INTCTL) ||
|
||||
(int_tab_len != DTE_INTTABLEN)) {
|
||||
(int_tab_len != DTE_INTTABLEN_512 &&
|
||||
int_tab_len != DTE_INTTABLEN_2K)) {
|
||||
pr_err("Wrong old irq remapping flag: %#x\n", devid);
|
||||
memunmap(old_devtb);
|
||||
return false;
|
||||
@@ -2652,7 +2644,7 @@ static void iommu_init_flags(struct amd_iommu *iommu)
|
||||
iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
|
||||
|
||||
/* Set IOTLB invalidation timeout to 1s */
|
||||
iommu_set_inv_tlb_timeout(iommu, CTRL_INV_TO_1S);
|
||||
iommu_feature_set(iommu, CTRL_INV_TO_1S, CTRL_INV_TO_MASK, CONTROL_INV_TIMEOUT);
|
||||
|
||||
/* Enable Enhanced Peripheral Page Request Handling */
|
||||
if (check_feature(FEATURE_EPHSUP))
|
||||
@@ -2745,6 +2737,17 @@ static void iommu_enable_irtcachedis(struct amd_iommu *iommu)
|
||||
iommu->irtcachedis_enabled ? "disabled" : "enabled");
|
||||
}
|
||||
|
||||
static void iommu_enable_2k_int(struct amd_iommu *iommu)
|
||||
{
|
||||
if (!FEATURE_NUM_INT_REMAP_SUP_2K(amd_iommu_efr2))
|
||||
return;
|
||||
|
||||
iommu_feature_set(iommu,
|
||||
CONTROL_NUM_INT_REMAP_MODE_2K,
|
||||
CONTROL_NUM_INT_REMAP_MODE_MASK,
|
||||
CONTROL_NUM_INT_REMAP_MODE);
|
||||
}
|
||||
|
||||
static void early_enable_iommu(struct amd_iommu *iommu)
|
||||
{
|
||||
iommu_disable(iommu);
|
||||
@@ -2757,6 +2760,7 @@ static void early_enable_iommu(struct amd_iommu *iommu)
|
||||
iommu_enable_ga(iommu);
|
||||
iommu_enable_xt(iommu);
|
||||
iommu_enable_irtcachedis(iommu);
|
||||
iommu_enable_2k_int(iommu);
|
||||
iommu_enable(iommu);
|
||||
amd_iommu_flush_all_caches(iommu);
|
||||
}
|
||||
@@ -2813,6 +2817,7 @@ static void early_enable_iommus(void)
|
||||
iommu_enable_ga(iommu);
|
||||
iommu_enable_xt(iommu);
|
||||
iommu_enable_irtcachedis(iommu);
|
||||
iommu_enable_2k_int(iommu);
|
||||
iommu_set_device_table(iommu);
|
||||
amd_iommu_flush_all_caches(iommu);
|
||||
}
|
||||
@@ -2939,9 +2944,6 @@ static struct syscore_ops amd_iommu_syscore_ops = {
|
||||
|
||||
static void __init free_iommu_resources(void)
|
||||
{
|
||||
kmem_cache_destroy(amd_iommu_irq_cache);
|
||||
amd_iommu_irq_cache = NULL;
|
||||
|
||||
free_iommu_all();
|
||||
free_pci_segments();
|
||||
}
|
||||
@@ -3040,7 +3042,7 @@ static void __init ivinfo_init(void *ivrs)
|
||||
static int __init early_amd_iommu_init(void)
|
||||
{
|
||||
struct acpi_table_header *ivrs_base;
|
||||
int remap_cache_sz, ret;
|
||||
int ret;
|
||||
acpi_status status;
|
||||
|
||||
if (!amd_iommu_detected)
|
||||
@@ -3102,22 +3104,7 @@ static int __init early_amd_iommu_init(void)
|
||||
|
||||
if (amd_iommu_irq_remap) {
|
||||
struct amd_iommu_pci_seg *pci_seg;
|
||||
/*
|
||||
* Interrupt remapping enabled, create kmem_cache for the
|
||||
* remapping tables.
|
||||
*/
|
||||
ret = -ENOMEM;
|
||||
if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir))
|
||||
remap_cache_sz = MAX_IRQS_PER_TABLE * sizeof(u32);
|
||||
else
|
||||
remap_cache_sz = MAX_IRQS_PER_TABLE * (sizeof(u64) * 2);
|
||||
amd_iommu_irq_cache = kmem_cache_create("irq_remap_cache",
|
||||
remap_cache_sz,
|
||||
DTE_INTTAB_ALIGNMENT,
|
||||
0, NULL);
|
||||
if (!amd_iommu_irq_cache)
|
||||
goto out;
|
||||
|
||||
for_each_pci_segment(pci_seg) {
|
||||
if (alloc_irq_lookup_table(pci_seg))
|
||||
goto out;
|
||||
|
||||
@@ -47,13 +47,6 @@ static u64 *first_pte_l7(u64 *pte, unsigned long *page_size,
|
||||
return fpte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* The functions below are used the create the page table mappings for
|
||||
* unity mapped regions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void free_pt_page(u64 *pt, struct list_head *freelist)
|
||||
{
|
||||
struct page *p = virt_to_page(pt);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user