ath10k: fix possible bmi crash
authorMichal Kazior <michal.kazior@tieto.com>
Tue, 28 Oct 2014 09:34:36 +0000 (10:34 +0100)
committerKalle Valo <kvalo@qca.qualcomm.com>
Fri, 31 Oct 2014 00:32:15 +0000 (02:32 +0200)
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>
drivers/net/wireless/ath/ath10k/ce.c
drivers/net/wireless/ath/ath10k/pci.c

index 878e1ec775daab274a67e11ec12ab830e5cbf3b8..a156e6e48708f96bada8aec2aa17f43d4e052690 100644 (file)
@@ -558,6 +558,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
 
                /* sanity */
                dest_ring->per_transfer_context[sw_index] = NULL;
+               desc->nbytes = 0;
 
                /* Update sw_index */
                sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
@@ -835,6 +836,9 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 
        nentries = roundup_pow_of_two(attr->src_nentries);
 
+       memset(src_ring->base_addr_owner_space, 0,
+              nentries * sizeof(struct ce_desc));
+
        src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
        src_ring->sw_index &= src_ring->nentries_mask;
        src_ring->hw_index = src_ring->sw_index;
@@ -869,6 +873,9 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
 
        nentries = roundup_pow_of_two(attr->dest_nentries);
 
+       memset(dest_ring->base_addr_owner_space, 0,
+              nentries * sizeof(struct ce_desc));
+
        dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
        dest_ring->sw_index &= dest_ring->nentries_mask;
        dest_ring->write_index =
index 63f374ed6f6ab3cdd22cb429f9a700a3960cc456..f5e426ea2570eedb08e54935366c56ca0a565eb3 100644 (file)
@@ -1442,6 +1442,9 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
                                          &nbytes, &transfer_id, &flags))
                return;
 
+       if (WARN_ON_ONCE(!xfer))
+               return;
+
        if (!xfer->wait_for_resp) {
                ath10k_warn(ar, "unexpected: BMI data received; ignoring\n");
                return;