Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94fb175c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dmaengine fixes from Dan Williams:

1/ regression fix for Xen as it now trips over a broken assumption
   about the dma address size on 32-bit builds

2/ new quirk for netdma to ignore dma channels that cannot meet
   netdma alignment requirements

3/ fixes for two long standing issues in ioatdma (ring size overflow)
   and iop-adma (potential stack corruption)

* tag 'dmaengine-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/dmaengine:
  netdma: adding alignment check for NETDMA ops
  ioatdma: DMA copy alignment needed to address IOAT DMA silicon errata
  ioat: ring size variables need to be 32bit to avoid overflow
  iop-adma: Corrected array overflow in RAID6 Xscale(R) test.
  ioat: fix size of 'completion' for Xen
parents a9e1e53b a2bd1140
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -332,6 +332,20 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
}
EXPORT_SYMBOL(dma_find_channel);

/*
 * net_dma_find_channel - find a channel for net_dma
 * net_dma has alignment requirements
 */
struct dma_chan *net_dma_find_channel(void)
{
	struct dma_chan *chan = dma_find_channel(DMA_MEMCPY);
	if (chan && !is_dma_copy_aligned(chan->device, 1, 1, 1))
		return NULL;

	return chan;
}
EXPORT_SYMBOL(net_dma_find_channel);

/**
 * dma_issue_pending_all - flush all pending operations across all channels
 */
+8 −8
Original line number Diff line number Diff line
@@ -546,9 +546,9 @@ void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
			   PCI_DMA_TODEVICE, flags, 0);
}

unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan)
{
	unsigned long phys_complete;
	dma_addr_t phys_complete;
	u64 completion;

	completion = *chan->completion;
@@ -569,7 +569,7 @@ unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
}

bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
			   unsigned long *phys_complete)
			   dma_addr_t *phys_complete)
{
	*phys_complete = ioat_get_current_completion(chan);
	if (*phys_complete == chan->last_completion)
@@ -580,14 +580,14 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
	return true;
}

static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete)
{
	struct ioat_chan_common *chan = &ioat->base;
	struct list_head *_desc, *n;
	struct dma_async_tx_descriptor *tx;

	dev_dbg(to_dev(chan), "%s: phys_complete: %lx\n",
		 __func__, phys_complete);
	dev_dbg(to_dev(chan), "%s: phys_complete: %llx\n",
		 __func__, (unsigned long long) phys_complete);
	list_for_each_safe(_desc, n, &ioat->used_desc) {
		struct ioat_desc_sw *desc;

@@ -652,7 +652,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
static void ioat1_cleanup(struct ioat_dma_chan *ioat)
{
	struct ioat_chan_common *chan = &ioat->base;
	unsigned long phys_complete;
	dma_addr_t phys_complete;

	prefetch(chan->completion);

@@ -698,7 +698,7 @@ static void ioat1_timer_event(unsigned long data)
		mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
		spin_unlock_bh(&ioat->desc_lock);
	} else if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
		unsigned long phys_complete;
		dma_addr_t phys_complete;

		spin_lock_bh(&ioat->desc_lock);
		/* if we haven't made progress and we have already
+3 −3
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ struct ioatdma_device {
struct ioat_chan_common {
	struct dma_chan common;
	void __iomem *reg_base;
	unsigned long last_completion;
	dma_addr_t last_completion;
	spinlock_t cleanup_lock;
	unsigned long state;
	#define IOAT_COMPLETION_PENDING 0
@@ -310,7 +310,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device);
void __devexit ioat_dma_remove(struct ioatdma_device *device);
struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev,
					      void __iomem *iobase);
unsigned long ioat_get_current_completion(struct ioat_chan_common *chan);
dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan);
void ioat_init_channel(struct ioatdma_device *device,
		       struct ioat_chan_common *chan, int idx);
enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
@@ -318,7 +318,7 @@ enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
		    size_t len, struct ioat_dma_descriptor *hw);
bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
			   unsigned long *phys_complete);
			   dma_addr_t *phys_complete);
void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
void ioat_kobject_del(struct ioatdma_device *device);
extern const struct sysfs_ops ioat_sysfs_ops;
+6 −6
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ static void ioat2_start_null_desc(struct ioat2_dma_chan *ioat)
	spin_unlock_bh(&ioat->prep_lock);
}

static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete)
{
	struct ioat_chan_common *chan = &ioat->base;
	struct dma_async_tx_descriptor *tx;
@@ -179,7 +179,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
static void ioat2_cleanup(struct ioat2_dma_chan *ioat)
{
	struct ioat_chan_common *chan = &ioat->base;
	unsigned long phys_complete;
	dma_addr_t phys_complete;

	spin_lock_bh(&chan->cleanup_lock);
	if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -260,7 +260,7 @@ int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo)
static void ioat2_restart_channel(struct ioat2_dma_chan *ioat)
{
	struct ioat_chan_common *chan = &ioat->base;
	unsigned long phys_complete;
	dma_addr_t phys_complete;

	ioat2_quiesce(chan, 0);
	if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -275,7 +275,7 @@ void ioat2_timer_event(unsigned long data)
	struct ioat_chan_common *chan = &ioat->base;

	if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
		unsigned long phys_complete;
		dma_addr_t phys_complete;
		u64 status;

		status = ioat_chansts(chan);
@@ -572,9 +572,9 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order)
	 */
	struct ioat_chan_common *chan = &ioat->base;
	struct dma_chan *c = &chan->common;
	const u16 curr_size = ioat2_ring_size(ioat);
	const u32 curr_size = ioat2_ring_size(ioat);
	const u16 active = ioat2_ring_active(ioat);
	const u16 new_size = 1 << order;
	const u32 new_size = 1 << order;
	struct ioat_ring_ent **ring;
	u16 i;

+2 −2
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c)
	return container_of(chan, struct ioat2_dma_chan, base);
}

static inline u16 ioat2_ring_size(struct ioat2_dma_chan *ioat)
static inline u32 ioat2_ring_size(struct ioat2_dma_chan *ioat)
{
	return 1 << ioat->alloc_order;
}
@@ -91,7 +91,7 @@ static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat)
	return CIRC_CNT(ioat->head, ioat->issued, ioat2_ring_size(ioat));
}

static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat)
static inline u32 ioat2_ring_space(struct ioat2_dma_chan *ioat)
{
	return ioat2_ring_size(ioat) - ioat2_ring_active(ioat);
}
Loading