aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-10-28 05:34:36 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2014-10-30 20:32:15 -0400
commit04ed9dfe499965b641b69575137af9f41a78e609 (patch)
treecd94ee6fac9700e2832fac83446dc60b38b6b521 /drivers/net
parentc011b281591bb21e4006200a1f51ec4f67b46a74 (diff)
ath10k: fix possible bmi crash
While testing other things I've found that CE items aren't cleared properly. This could lead to null dereferences in BMI. To prevent that make sure CE revoking clears the nbytes value (which is used as a buffer completion indication) and memset the entire CE ring data shared between host and target when (re)initializing. Also make sure to check BMI xfer pointer and print a splat instead of crashing the kernel. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c7
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c3
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 878e1ec775da..a156e6e48708 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -558,6 +558,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
558 558
559 /* sanity */ 559 /* sanity */
560 dest_ring->per_transfer_context[sw_index] = NULL; 560 dest_ring->per_transfer_context[sw_index] = NULL;
561 desc->nbytes = 0;
561 562
562 /* Update sw_index */ 563 /* Update sw_index */
563 sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); 564 sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
@@ -835,6 +836,9 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
835 836
836 nentries = roundup_pow_of_two(attr->src_nentries); 837 nentries = roundup_pow_of_two(attr->src_nentries);
837 838
839 memset(src_ring->base_addr_owner_space, 0,
840 nentries * sizeof(struct ce_desc));
841
838 src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); 842 src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
839 src_ring->sw_index &= src_ring->nentries_mask; 843 src_ring->sw_index &= src_ring->nentries_mask;
840 src_ring->hw_index = src_ring->sw_index; 844 src_ring->hw_index = src_ring->sw_index;
@@ -869,6 +873,9 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
869 873
870 nentries = roundup_pow_of_two(attr->dest_nentries); 874 nentries = roundup_pow_of_two(attr->dest_nentries);
871 875
876 memset(dest_ring->base_addr_owner_space, 0,
877 nentries * sizeof(struct ce_desc));
878
872 dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); 879 dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
873 dest_ring->sw_index &= dest_ring->nentries_mask; 880 dest_ring->sw_index &= dest_ring->nentries_mask;
874 dest_ring->write_index = 881 dest_ring->write_index =
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 63f374ed6f6a..f5e426ea2570 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1442,6 +1442,9 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
1442 &nbytes, &transfer_id, &flags)) 1442 &nbytes, &transfer_id, &flags))
1443 return; 1443 return;
1444 1444
1445 if (WARN_ON_ONCE(!xfer))
1446 return;
1447
1445 if (!xfer->wait_for_resp) { 1448 if (!xfer->wait_for_resp) {
1446 ath10k_warn(ar, "unexpected: BMI data received; ignoring\n"); 1449 ath10k_warn(ar, "unexpected: BMI data received; ignoring\n");
1447 return; 1450 return;