Commit 6df0e6c5 authored by Dave Jiang's avatar Dave Jiang Committed by Vinod Koul

dmaengine: idxd: clear MSIX permission entry on shutdown

Add disabling/clearing of MSIX permission entries on device shutdown to
mirror the enabling of the MSIX entries on probe. Current code left the
MSIX enabled and the pasid entries still programmed at device shutdown.

Fixes: 8e50d392 ("dmaengine: idxd: Add shared workqueue support")
Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/161824457969.882533.6020239898682672311.stgit@djiang5-desk3.ch.intel.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 07503e6a
...@@ -574,6 +574,36 @@ void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid) ...@@ -574,6 +574,36 @@ void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid)
} }
/* Device configuration bits */ /* Device configuration bits */
void idxd_msix_perm_setup(struct idxd_device *idxd)
{
union msix_perm mperm;
int i, msixcnt;
msixcnt = pci_msix_vec_count(idxd->pdev);
if (msixcnt < 0)
return;
mperm.bits = 0;
mperm.pasid = idxd->pasid;
mperm.pasid_en = device_pasid_enabled(idxd);
for (i = 1; i < msixcnt; i++)
iowrite32(mperm.bits, idxd->reg_base + idxd->msix_perm_offset + i * 8);
}
void idxd_msix_perm_clear(struct idxd_device *idxd)
{
union msix_perm mperm;
int i, msixcnt;
msixcnt = pci_msix_vec_count(idxd->pdev);
if (msixcnt < 0)
return;
mperm.bits = 0;
for (i = 1; i < msixcnt; i++)
iowrite32(mperm.bits, idxd->reg_base + idxd->msix_perm_offset + i * 8);
}
static void idxd_group_config_write(struct idxd_group *group) static void idxd_group_config_write(struct idxd_group *group)
{ {
struct idxd_device *idxd = group->idxd; struct idxd_device *idxd = group->idxd;
......
...@@ -316,6 +316,8 @@ void idxd_unregister_driver(void); ...@@ -316,6 +316,8 @@ void idxd_unregister_driver(void);
struct bus_type *idxd_get_bus_type(struct idxd_device *idxd); struct bus_type *idxd_get_bus_type(struct idxd_device *idxd);
/* device interrupt control */ /* device interrupt control */
void idxd_msix_perm_setup(struct idxd_device *idxd);
void idxd_msix_perm_clear(struct idxd_device *idxd);
irqreturn_t idxd_irq_handler(int vec, void *data); irqreturn_t idxd_irq_handler(int vec, void *data);
irqreturn_t idxd_misc_thread(int vec, void *data); irqreturn_t idxd_misc_thread(int vec, void *data);
irqreturn_t idxd_wq_thread(int irq, void *data); irqreturn_t idxd_wq_thread(int irq, void *data);
......
...@@ -65,7 +65,6 @@ static int idxd_setup_interrupts(struct idxd_device *idxd) ...@@ -65,7 +65,6 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
struct idxd_irq_entry *irq_entry; struct idxd_irq_entry *irq_entry;
int i, msixcnt; int i, msixcnt;
int rc = 0; int rc = 0;
union msix_perm mperm;
msixcnt = pci_msix_vec_count(pdev); msixcnt = pci_msix_vec_count(pdev);
if (msixcnt < 0) { if (msixcnt < 0) {
...@@ -144,14 +143,7 @@ static int idxd_setup_interrupts(struct idxd_device *idxd) ...@@ -144,14 +143,7 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
} }
idxd_unmask_error_interrupts(idxd); idxd_unmask_error_interrupts(idxd);
idxd_msix_perm_setup(idxd);
/* Setup MSIX permission table */
mperm.bits = 0;
mperm.pasid = idxd->pasid;
mperm.pasid_en = device_pasid_enabled(idxd);
for (i = 1; i < msixcnt; i++)
iowrite32(mperm.bits, idxd->reg_base + idxd->msix_perm_offset + i * 8);
return 0; return 0;
err_no_irq: err_no_irq:
...@@ -510,6 +502,7 @@ static void idxd_shutdown(struct pci_dev *pdev) ...@@ -510,6 +502,7 @@ static void idxd_shutdown(struct pci_dev *pdev)
idxd_flush_work_list(irq_entry); idxd_flush_work_list(irq_entry);
} }
idxd_msix_perm_clear(idxd);
destroy_workqueue(idxd->wq); destroy_workqueue(idxd->wq);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment