rtl8187: fix crashes on mips caused by misaligned DMA and cache issues

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 39570
This commit is contained in:
Felix Fietkau 2014-02-11 15:00:36 +00:00
parent 4fd88fa081
commit 8e43f3443e

View file

@ -1,3 +1,43 @@
commit d4426800f71e972feaa33e04c5801fc730627bdd
Author: Stanislaw Gruszka <stf_xl@wp.pl>
Date: Mon Feb 10 22:38:28 2014 +0100
rtl8187: fix regression on MIPS without coherent DMA
This patch fixes regression caused by commit a16dad77634 "MIPS: Fix
potencial corruption". That commit fixes one corruption scenario in
cost of adding another one, which actually start to cause crashes
on Yeeloong laptop when rtl8187 driver is used.
For correct DMA read operation on machines without DMA coherence, kernel
have to invalidate cache, such it will refill later with new data that
device wrote to memory, when that data is needed to process. We can only
invalidate full cache line. Hence when cache line includes both dma
buffer and some other data (written in cache, but not yet in main
memory), the other data can not hit memory due to invalidation. That
happen on rtl8187 where struct rtl8187_priv fields are located just
before and after small buffers that are passed to USB layer and DMA
is performed on them.
To fix the problem we align buffers and reserve space after them to make
them match cache line.
This patch does not resolve all possible MIPS problems entirely, for
that we have to assure that we always map cache aligned buffers for DMA,
what can be complex or even not possible. But patch fixes visible and
reproducible regression and seems other possible corruptions do not
happen in practice, since Yeeloong laptop works stable without rtl8187
driver.
Bug report:
https://bugzilla.kernel.org/show_bug.cgi?id=54391
Reported-by: Petr Pisar <petr.pisar@atlas.cz>
Bisected-by: Tom Li <biergaizi2009@gmail.com>
Reported-and-tested-by: Tom Li <biergaizi2009@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442 commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com> Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Date: Fri Feb 7 10:29:55 2014 +0530 Date: Fri Feb 7 10:29:55 2014 +0530
@ -2632,3 +2672,36 @@ Date: Thu Jan 23 20:06:34 2014 +0100
/* Revert chainmask to runtime parameters */ /* Revert chainmask to runtime parameters */
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
@@ -15,6 +15,8 @@
#ifndef RTL8187_H
#define RTL8187_H
+#include <linux/cache.h>
+
#include "rtl818x.h"
#include "leds.h"
@@ -139,7 +141,10 @@ struct rtl8187_priv {
u8 aifsn[4];
u8 rfkill_mask;
struct {
- __le64 buf;
+ union {
+ __le64 buf;
+ u8 dummy1[L1_CACHE_BYTES];
+ } ____cacheline_aligned;
struct sk_buff_head queue;
} b_tx_status; /* This queue is used by both -b and non-b devices */
struct mutex io_mutex;
@@ -147,7 +152,8 @@ struct rtl8187_priv {
u8 bits8;
__le16 bits16;
__le32 bits32;
- } *io_dmabuf;
+ u8 dummy2[L1_CACHE_BYTES];
+ } *io_dmabuf ____cacheline_aligned;
bool rfkill_off;
u16 seqno;
};