Skip to content

Commit

Permalink
Merge branches 'arm/mediatek', 'arm/msm', 'arm/renesas', 'arm/rockchi…
Browse files Browse the repository at this point in the history
…p', 'arm/smmu', 'x86/vt-d' and 'x86/amd' into next
  • Loading branch information
Joerg Roedel committed Mar 8, 2022
8 parents ffb217a + 4f23f6d + a063158 + ae684ca + 6efd3b8 + e38432c + 97f2f2c + 9f968fc commit e17c6de
Show file tree
Hide file tree
Showing 41 changed files with 662 additions and 2,251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ properties:
- renesas,ipmmu-r8a77990 # R-Car E3
- renesas,ipmmu-r8a77995 # R-Car D3
- renesas,ipmmu-r8a779a0 # R-Car V3U
- items:
- enum:
- renesas,ipmmu-r8a779f0 # R-Car S4-8
- const: renesas,rcar-gen4-ipmmu-vmsa # R-Car Gen4

reg:
maxItems: 1
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
* or equal to the system's PAGE_SIZE, with a preference if
* both are equal.
*/
pgsize_bitmap = tdev->iommu.domain->ops->pgsize_bitmap;
pgsize_bitmap = tdev->iommu.domain->pgsize_bitmap;
if (pgsize_bitmap & PAGE_SIZE) {
tdev->iommu.pgshift = PAGE_SHIFT;
} else {
Expand Down
4 changes: 1 addition & 3 deletions drivers/iommu/amd/amd_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ extern irqreturn_t amd_iommu_int_thread(int irq, void *data);
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
extern void amd_iommu_apply_erratum_63(u16 devid);
extern void amd_iommu_restart_event_logging(struct amd_iommu *iommu);
extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
extern int amd_iommu_init_devices(void);
extern void amd_iommu_uninit_devices(void);
extern void amd_iommu_init_notifier(void);
Expand Down Expand Up @@ -117,8 +116,7 @@ void amd_iommu_domain_clr_pt_root(struct protection_domain *domain)


extern bool translation_pre_enabled(struct amd_iommu *iommu);
extern bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
struct device *dev);
extern bool amd_iommu_is_attach_deferred(struct device *dev);
extern int __init add_special_device(u8 type, u8 id, u16 *devid,
bool cmd_line);

Expand Down
18 changes: 14 additions & 4 deletions drivers/iommu/amd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ void amd_iommu_restart_event_logging(struct amd_iommu *iommu)
* This function resets the command buffer if the IOMMU stopped fetching
* commands from it.
*/
void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu)
static void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu)
{
iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);

Expand Down Expand Up @@ -990,6 +990,7 @@ static bool copy_device_table(void)
get_order(dev_table_size));
if (old_dev_tbl_cpy == NULL) {
pr_err("Failed to allocate memory for copying old device table!\n");
memunmap(old_devtb);
return false;
}

Expand Down Expand Up @@ -1020,6 +1021,7 @@ static bool copy_device_table(void)
if ((int_ctl != DTE_IRQ_REMAP_INTCTL) ||
(int_tab_len != DTE_INTTABLEN)) {
pr_err("Wrong old irq remapping flag: %#x\n", devid);
memunmap(old_devtb);
return false;
}

Expand Down Expand Up @@ -1953,9 +1955,11 @@ static int __init amd_iommu_init_pci(void)

for_each_iommu(iommu) {
ret = iommu_init_pci(iommu);
if (ret)
break;

if (ret) {
pr_err("IOMMU%d: Failed to initialize IOMMU Hardware (error=%d)!\n",
iommu->index, ret);
goto out;
}
/* Need to setup range after PCI init */
iommu_set_cwwb_range(iommu);
}
Expand All @@ -1971,6 +1975,11 @@ static int __init amd_iommu_init_pci(void)
* active.
*/
ret = amd_iommu_init_api();
if (ret) {
pr_err("IOMMU: Failed to initialize IOMMU-API interface (error=%d)!\n",
ret);
goto out;
}

init_device_table_dma();

Expand All @@ -1980,6 +1989,7 @@ static int __init amd_iommu_init_pci(void)
if (!ret)
print_iommu_info();

out:
return ret;
}

Expand Down
23 changes: 12 additions & 11 deletions drivers/iommu/amd/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2221,8 +2221,7 @@ static void amd_iommu_get_resv_regions(struct device *dev,
list_add_tail(&region->list, head);
}

bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
struct device *dev)
bool amd_iommu_is_attach_deferred(struct device *dev)
{
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);

Expand Down Expand Up @@ -2275,13 +2274,6 @@ static int amd_iommu_def_domain_type(struct device *dev)
const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.domain_alloc = amd_iommu_domain_alloc,
.domain_free = amd_iommu_domain_free,
.attach_dev = amd_iommu_attach_device,
.detach_dev = amd_iommu_detach_device,
.map = amd_iommu_map,
.iotlb_sync_map = amd_iommu_iotlb_sync_map,
.unmap = amd_iommu_unmap,
.iova_to_phys = amd_iommu_iova_to_phys,
.probe_device = amd_iommu_probe_device,
.release_device = amd_iommu_release_device,
.probe_finalize = amd_iommu_probe_finalize,
Expand All @@ -2290,9 +2282,18 @@ const struct iommu_ops amd_iommu_ops = {
.put_resv_regions = generic_iommu_put_resv_regions,
.is_attach_deferred = amd_iommu_is_attach_deferred,
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
.flush_iotlb_all = amd_iommu_flush_iotlb_all,
.iotlb_sync = amd_iommu_iotlb_sync,
.def_domain_type = amd_iommu_def_domain_type,
.default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = amd_iommu_attach_device,
.detach_dev = amd_iommu_detach_device,
.map = amd_iommu_map,
.unmap = amd_iommu_unmap,
.iotlb_sync_map = amd_iommu_iotlb_sync_map,
.iova_to_phys = amd_iommu_iova_to_phys,
.flush_iotlb_all = amd_iommu_flush_iotlb_all,
.iotlb_sync = amd_iommu_iotlb_sync,
.free = amd_iommu_domain_free,
}
};

/*****************************************************************************
Expand Down
37 changes: 18 additions & 19 deletions drivers/iommu/amd/iommu_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Joerg Roedel <jroedel@suse.de>");

#define MAX_DEVICES 0x10000
#define PRI_QUEUE_SIZE 512

struct pri_queue {
Expand Down Expand Up @@ -71,7 +70,6 @@ struct fault {
struct pasid_state *state;
struct mm_struct *mm;
u64 address;
u16 devid;
u32 pasid;
u16 tag;
u16 finish;
Expand Down Expand Up @@ -125,6 +123,15 @@ static void free_device_state(struct device_state *dev_state)
{
struct iommu_group *group;

/* Get rid of any remaining pasid states */
free_pasid_states(dev_state);

/*
* Wait until the last reference is dropped before freeing
* the device state.
*/
wait_event(dev_state->wq, !atomic_read(&dev_state->count));

/*
* First detach device from domain - No more PRI requests will arrive
* from that device after it is unbound from the IOMMUv2 domain.
Expand Down Expand Up @@ -537,7 +544,7 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
ret = NOTIFY_DONE;

/* In kdump kernel pci dev is not initialized yet -> send INVALID */
if (amd_iommu_is_attach_deferred(NULL, &pdev->dev)) {
if (amd_iommu_is_attach_deferred(&pdev->dev)) {
amd_iommu_complete_ppr(pdev, iommu_fault->pasid,
PPR_INVALID, tag);
goto out;
Expand Down Expand Up @@ -850,15 +857,7 @@ void amd_iommu_free_device(struct pci_dev *pdev)

spin_unlock_irqrestore(&state_lock, flags);

/* Get rid of any remaining pasid states */
free_pasid_states(dev_state);

put_device_state(dev_state);
/*
* Wait until the last reference is dropped before freeing
* the device state.
*/
wait_event(dev_state->wq, !atomic_read(&dev_state->count));
free_device_state(dev_state);
}
EXPORT_SYMBOL(amd_iommu_free_device);
Expand Down Expand Up @@ -955,8 +954,8 @@ static int __init amd_iommu_v2_init(void)

static void __exit amd_iommu_v2_exit(void)
{
struct device_state *dev_state;
int i;
struct device_state *dev_state, *next;
unsigned long flags;

if (!amd_iommu_v2_supported())
return;
Expand All @@ -969,18 +968,18 @@ static void __exit amd_iommu_v2_exit(void)
* The loop below might call flush_workqueue(), so call
* destroy_workqueue() after it
*/
for (i = 0; i < MAX_DEVICES; ++i) {
dev_state = get_device_state(i);

if (dev_state == NULL)
continue;
spin_lock_irqsave(&state_lock, flags);

list_for_each_entry_safe(dev_state, next, &state_list, list) {
WARN_ON_ONCE(1);

put_device_state(dev_state);
amd_iommu_free_device(dev_state->pdev);
list_del(&dev_state->list);
free_device_state(dev_state);
}

spin_unlock_irqrestore(&state_lock, flags);

destroy_workqueue(iommu_wq);
}

Expand Down
20 changes: 11 additions & 9 deletions drivers/iommu/apple-dart.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,15 +765,6 @@ static void apple_dart_get_resv_regions(struct device *dev,

static const struct iommu_ops apple_dart_iommu_ops = {
.domain_alloc = apple_dart_domain_alloc,
.domain_free = apple_dart_domain_free,
.attach_dev = apple_dart_attach_dev,
.detach_dev = apple_dart_detach_dev,
.map_pages = apple_dart_map_pages,
.unmap_pages = apple_dart_unmap_pages,
.flush_iotlb_all = apple_dart_flush_iotlb_all,
.iotlb_sync = apple_dart_iotlb_sync,
.iotlb_sync_map = apple_dart_iotlb_sync_map,
.iova_to_phys = apple_dart_iova_to_phys,
.probe_device = apple_dart_probe_device,
.release_device = apple_dart_release_device,
.device_group = apple_dart_device_group,
Expand All @@ -782,6 +773,17 @@ static const struct iommu_ops apple_dart_iommu_ops = {
.get_resv_regions = apple_dart_get_resv_regions,
.put_resv_regions = generic_iommu_put_resv_regions,
.pgsize_bitmap = -1UL, /* Restricted during dart probe */
.default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = apple_dart_attach_dev,
.detach_dev = apple_dart_detach_dev,
.map_pages = apple_dart_map_pages,
.unmap_pages = apple_dart_unmap_pages,
.flush_iotlb_all = apple_dart_flush_iotlb_all,
.iotlb_sync = apple_dart_iotlb_sync,
.iotlb_sync_map = apple_dart_iotlb_sync_map,
.iova_to_phys = apple_dart_iova_to_phys,
.free = apple_dart_domain_free,
}
};

static irqreturn_t apple_dart_irq(int irq, void *dev)
Expand Down
45 changes: 18 additions & 27 deletions drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
dev_info(smmu->dev, "\t0x%016llx\n",
(unsigned long long)evt[i]);

cond_resched();
}

/*
Expand Down Expand Up @@ -2841,17 +2842,9 @@ static int arm_smmu_dev_disable_feature(struct device *dev,
static struct iommu_ops arm_smmu_ops = {
.capable = arm_smmu_capable,
.domain_alloc = arm_smmu_domain_alloc,
.domain_free = arm_smmu_domain_free,
.attach_dev = arm_smmu_attach_dev,
.map_pages = arm_smmu_map_pages,
.unmap_pages = arm_smmu_unmap_pages,
.flush_iotlb_all = arm_smmu_flush_iotlb_all,
.iotlb_sync = arm_smmu_iotlb_sync,
.iova_to_phys = arm_smmu_iova_to_phys,
.probe_device = arm_smmu_probe_device,
.release_device = arm_smmu_release_device,
.device_group = arm_smmu_device_group,
.enable_nesting = arm_smmu_enable_nesting,
.of_xlate = arm_smmu_of_xlate,
.get_resv_regions = arm_smmu_get_resv_regions,
.put_resv_regions = generic_iommu_put_resv_regions,
Expand All @@ -2865,6 +2858,16 @@ static struct iommu_ops arm_smmu_ops = {
.page_response = arm_smmu_page_response,
.pgsize_bitmap = -1UL, /* Restricted during device attach */
.owner = THIS_MODULE,
.default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = arm_smmu_attach_dev,
.map_pages = arm_smmu_map_pages,
.unmap_pages = arm_smmu_unmap_pages,
.flush_iotlb_all = arm_smmu_flush_iotlb_all,
.iotlb_sync = arm_smmu_iotlb_sync,
.iova_to_phys = arm_smmu_iova_to_phys,
.enable_nesting = arm_smmu_enable_nesting,
.free = arm_smmu_domain_free,
}
};

/* Probing and initialisation functions */
Expand Down Expand Up @@ -2911,32 +2914,20 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
return 0;
}

static void arm_smmu_cmdq_free_bitmap(void *data)
{
unsigned long *bitmap = data;
bitmap_free(bitmap);
}

static int arm_smmu_cmdq_init(struct arm_smmu_device *smmu)
{
int ret = 0;
struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
unsigned int nents = 1 << cmdq->q.llq.max_n_shift;
atomic_long_t *bitmap;

atomic_set(&cmdq->owner_prod, 0);
atomic_set(&cmdq->lock, 0);

bitmap = (atomic_long_t *)bitmap_zalloc(nents, GFP_KERNEL);
if (!bitmap) {
dev_err(smmu->dev, "failed to allocate cmdq bitmap\n");
ret = -ENOMEM;
} else {
cmdq->valid_map = bitmap;
devm_add_action(smmu->dev, arm_smmu_cmdq_free_bitmap, bitmap);
}
cmdq->valid_map = (atomic_long_t *)devm_bitmap_zalloc(smmu->dev, nents,
GFP_KERNEL);
if (!cmdq->valid_map)
return -ENOMEM;

return ret;
return 0;
}

static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
Expand Down Expand Up @@ -2981,10 +2972,10 @@ static int arm_smmu_init_l1_strtab(struct arm_smmu_device *smmu)
{
unsigned int i;
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
size_t size = sizeof(*cfg->l1_desc) * cfg->num_l1_ents;
void *strtab = smmu->strtab_cfg.strtab;

cfg->l1_desc = devm_kzalloc(smmu->dev, size, GFP_KERNEL);
cfg->l1_desc = devm_kcalloc(smmu->dev, cfg->num_l1_ents,
sizeof(*cfg->l1_desc), GFP_KERNEL);
if (!cfg->l1_desc)
return -ENOMEM;

Expand Down
Loading

0 comments on commit e17c6de

Please sign in to comment.