Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1328159
| From | Alexandre Bounine <alexandre.bounine@idt.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 04/30] rapidio/tsi721: add check for overlapped IB window mappings |
| Date | 2016-02-06 00:40 +0100 |
| Message-ID | <qYY8P-75F-35@gated-at.bofh.it> (permalink) |
| References | <qYXZ7-6YG-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
Add check for attempts to request mapping of inbound RapidIO address space
that overlaps with existing active mapping windows.
Tsi721 device does not support overlapped inbound windows and SRIO address
decoding behavior is not defined in such cases.
This patch is applicable to kernel versions starting from v3.7.
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Andre van Herk <andre.van.herk@prodrive-technologies.com>
Cc: linux-kernel@vger.kernel.org
---
drivers/rapidio/devices/tsi721.c | 72 +++++++++++++++++++++++++++-----------
drivers/rapidio/devices/tsi721.h | 11 ++++++
2 files changed, 62 insertions(+), 21 deletions(-)
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index f57ee9d..b96f0b9 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -885,26 +885,52 @@ static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
u64 rstart, u32 size, u32 flags)
{
struct tsi721_device *priv = mport->priv;
- int i;
+ int i, avail = -1;
u32 regval;
+ struct tsi721_ib_win *ib_win;
+ int ret = -EBUSY;
if (!is_power_of_2(size) || size < 0x1000 ||
((u64)lstart & (size - 1)) || (rstart & (size - 1)))
return -EINVAL;
- /* Search for free inbound translation window */
+ spin_lock(&priv->win_lock);
+ /*
+ * Scan for overlapping with active regions and mark the first available
+ * IB window at the same time.
+ */
for (i = 0; i < TSI721_IBWIN_NUM; i++) {
- regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
- if (!(regval & TSI721_IBWIN_LB_WEN))
+ ib_win = &priv->ib_win[i];
+ if (!ib_win->active) {
+ if (avail == -1) {
+ avail = i;
+ ret = 0;
+ }
+ } else if (rstart < (ib_win->rstart + ib_win->size) &&
+ (rstart + size) > ib_win->rstart) {
+ ret = -EFAULT;
break;
+ }
}
- if (i >= TSI721_IBWIN_NUM) {
- dev_err(&priv->pdev->dev,
- "Unable to find free inbound window\n");
- return -EBUSY;
+ if (ret)
+ goto err_out;
+ i = avail;
+
+ /* Sanity check: available IB window must be disabled at this point */
+ regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
+ if (WARN_ON(regval & TSI721_IBWIN_LB_WEN)) {
+ ret = -EIO;
+ goto err_out;
}
+ ib_win = &priv->ib_win[i];
+ ib_win->active = true;
+ ib_win->rstart = rstart;
+ ib_win->lstart = lstart;
+ ib_win->size = size;
+ spin_unlock(&priv->win_lock);
+
iowrite32(TSI721_IBWIN_SIZE(size) << 8,
priv->regs + TSI721_IBWIN_SZ(i));
@@ -920,6 +946,9 @@ static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
i, rstart, (unsigned long long)lstart);
return 0;
+err_out:
+ spin_unlock(&priv->win_lock);
+ return ret;
}
/**
@@ -931,25 +960,25 @@ static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport,
dma_addr_t lstart)
{
struct tsi721_device *priv = mport->priv;
+ struct tsi721_ib_win *ib_win;
int i;
- u64 addr;
- u32 regval;
/* Search for matching active inbound translation window */
+ spin_lock(&priv->win_lock);
for (i = 0; i < TSI721_IBWIN_NUM; i++) {
- regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
- if (regval & TSI721_IBWIN_LB_WEN) {
- regval = ioread32(priv->regs + TSI721_IBWIN_TUA(i));
- addr = (u64)regval << 32;
- regval = ioread32(priv->regs + TSI721_IBWIN_TLA(i));
- addr |= regval & TSI721_IBWIN_TLA_ADD;
-
- if (addr == (u64)lstart) {
- iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
- break;
- }
+ ib_win = &priv->ib_win[i];
+ if (ib_win->active && ib_win->lstart == lstart) {
+ iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
+ ib_win->active = false;
+ break;
}
}
+ spin_unlock(&priv->win_lock);
+
+ if (i == TSI721_IBWIN_NUM)
+ dev_err(&priv->pdev->dev,
+ "IB window mapped to %llx not found\n",
+ (unsigned long long)lstart);
}
/**
@@ -966,6 +995,7 @@ static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv)
/* Disable all SR2PC inbound windows */
for (i = 0; i < TSI721_IBWIN_NUM; i++)
iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
+ spin_lock_init(&priv->win_lock);
}
/**
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index 9d25025..355f356 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -808,6 +808,13 @@ struct msix_irq {
};
#endif /* CONFIG_PCI_MSI */
+struct tsi721_ib_win {
+ u64 rstart;
+ u32 size;
+ dma_addr_t lstart;
+ bool active;
+};
+
struct tsi721_device {
struct pci_dev *pdev;
struct rio_mport *mport;
@@ -843,6 +850,10 @@ struct tsi721_device {
/* Outbound Messaging */
int omsg_init[TSI721_OMSG_CHNUM];
struct tsi721_omsg_ring omsg_ring[TSI721_OMSG_CHNUM];
+
+ /* Inbound Mapping Windows */
+ struct tsi721_ib_win ib_win[TSI721_IBWIN_NUM];
+ spinlock_t win_lock;
};
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
--
1.7.8.4
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 00/30] rapidio: mport character driver and subsystem updates Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 23/30] rapidio/tsi721: fix locking in OB_MSG processing Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 12/30] rapidio: rework common RIO device add/delete routines Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 03/30] rapidio/tsi721: fix hardcoded MRRS setting Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 17/30] rapidio/rionet: add locking into add/remove device Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 08/30] rapidio/tsi721: add query_mport callback Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 06/30] rapidio/tsi721_dma: fix pending transaction queue handling Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 11/30] rapidio/rionet: add shutdown event handling Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 02/30] rapidio/rionet: add capability to change MTU Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 10/30] rapidio/tsi721: add shutdown notification callback Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 04/30] rapidio/tsi721: add check for overlapped IB window mappings Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 19/30] rapidio: add lock protection for doorbell list Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 25/30] rapidio/tsi721: add outbound windows mapping support Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100 [PATCH 24/30] rapidio: add outbound window support Alexandre Bounine <alexandre.bounine@idt.com> - 2016-02-06 00:40 +0100
csiph-web