aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkos Chandras <markos.chandras@imgtec.com>2014-04-02 04:53:24 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-11-24 01:45:42 -0500
commit0845bb721ebb7b88da4dfe3f3ece67963efc006f (patch)
tree358a4a79c7c35f5e2cdd38db85349977cb12f4c8
parentd98aefc384763813b3085a4a9eff2c6281cb5f56 (diff)
MIPS: iomap: Use __mem_{read,write}{b,w,l} for MMIO
Using the __raw_{read,write}{b,w,l} functions to perform repeatable MMIO could result in problems if the host bus does not match the endianness of the PCI/ISA. This problem is visible on big-endian SEAD3 configurations after commit 2925f6c0c7af32720dcbadc586463aeceb6baa22 "net: smc911x: use io{read,write}*_rep accessors". This effectively moves away from using the __mem_* variants to __raw_* ones and causes a kernel bug as follows: Call Trace: CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 00000000, ra == 8012b3b0 Oops[#1]: Cpu 0 $ 0 : 00000000 00000065 00000000 00000004 $ 4 : 00000000 00000000 9a82dd60 00000000 $ 8 : 00000000 00000000 a00ae278 00000007 $12 : 0000000e 00000011 804c4228 ffff9411 $16 : 00000100 00000000 80560000 807fc6d0 $20 : 807fc8d0 807fcad0 807fbec0 00000100 $24 : 00009150 80109be0 $28 : 9a82c000 9a82dd28 00000001 8012b3b0 Hi : 00000000 Lo : 00000000 epc : 00000000 (null) Not tainted ra : 8012b3b0 call_timer_fn.isra.39+0x24/0x84 Status: 10009503 KERNEL EXL IE Cause : 00800808 BadVA : 00000000 PrId : 00019c20 (MIPS M14Kc) Modules linked in: Process swapper (pid: 1, threadinfo=9a82c000, task=9a82ba18, tls=00000000) Stack : 00000040 00000000 00000007 8056732c 80580000 00000001 9a82dd60 00200200 80560000 8012b598 8056732c 80580000 00000001 00000000 9a82dd60 9a82dd60 00000000 807fbd44 807fbd40 805664e0 0000000a 80800000 00000004 80125924 0000fda0 000007f0 80000000 00000001 80800000 007f0000 00200140 80166338 00000000 8100fda0 0000fda0 000007f0 80000000 00000001 80800000 007f0000 ... Call Trace: [<8012b598>] run_timer_softirq+0x188/0x1f4 [<80125924>] __do_softirq+0xc4/0x18c [<80166338>] handle_percpu_irq+0x54/0x84 [<80125aa4>] do_softirq+0x68/0x70 [<80103b50>] do_IRQ+0x18/0x28 [<80125d1c>] irq_exit+0x94/0xc0 [<80125aa4>] do_softirq+0x68/0x70 [<80102130>] ret_from_irq+0x0/0x4 [<80102130>] ret_from_irq+0x0/0x4 [<80125d1c>] irq_exit+0x94/0xc0 [<803165b0>] __bzero+0xd4/0x164 [<80346d0c>] mem32_serial_out+0x0/0x1c [<8010d4ac>] free_init_pages+0x98/0xfc [<80180a08>] free_hot_cold_page+0x2c/0x1c4 [<80180bd8>] __free_pages+0x38/0x98 [<8010d4a0>] free_init_pages+0x8c/0xfc [<8010d4ac>] free_init_pages+0x98/0xfc [<8049fb04>] kernel_init+0x28/0x15c [<80147484>] schedule_tail+0x1c/0x60 [<8049fadc>] kernel_init+0x0/0x15c [<80102178>] ret_from_kernel_thread+0x14/0x1c [<8040a06f>] skb_pad+0xe7/0x13c Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Cc: Steve Glendinning <steve.glendinning@shawell.net> Cc: Ben Boeckel <mathstuf@gmail.com> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Cc: David S. Miller <davem@davemloft.net> Cc: netdev@vger.kernel.org Cc: Jeffrey Deans <Jeffrey.Deans@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6672/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/lib/iomap.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c
index e3acb2dad33a..8e7e378ce51c 100644
--- a/arch/mips/lib/iomap.c
+++ b/arch/mips/lib/iomap.c
@@ -97,14 +97,14 @@ EXPORT_SYMBOL(iowrite32be);
97 97
98/* 98/*
99 * These are the "repeat MMIO read/write" functions. 99 * These are the "repeat MMIO read/write" functions.
100 * Note the "__raw" accesses, since we don't want to 100 * Note the "__mem" accesses, since we want to convert
101 * convert to CPU byte order. We write in "IO byte 101 * to CPU byte order if the host bus happens to not match the
102 * order" (we also don't have IO barriers). 102 * endianness of PCI/ISA (see mach-generic/mangle-port.h).
103 */ 103 */
104static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) 104static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
105{ 105{
106 while (--count >= 0) { 106 while (--count >= 0) {
107 u8 data = __raw_readb(addr); 107 u8 data = __mem_readb(addr);
108 *dst = data; 108 *dst = data;
109 dst++; 109 dst++;
110 } 110 }
@@ -113,7 +113,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
113static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) 113static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
114{ 114{
115 while (--count >= 0) { 115 while (--count >= 0) {
116 u16 data = __raw_readw(addr); 116 u16 data = __mem_readw(addr);
117 *dst = data; 117 *dst = data;
118 dst++; 118 dst++;
119 } 119 }
@@ -122,7 +122,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
122static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) 122static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
123{ 123{
124 while (--count >= 0) { 124 while (--count >= 0) {
125 u32 data = __raw_readl(addr); 125 u32 data = __mem_readl(addr);
126 *dst = data; 126 *dst = data;
127 dst++; 127 dst++;
128 } 128 }
@@ -131,7 +131,7 @@ static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
131static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) 131static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
132{ 132{
133 while (--count >= 0) { 133 while (--count >= 0) {
134 __raw_writeb(*src, addr); 134 __mem_writeb(*src, addr);
135 src++; 135 src++;
136 } 136 }
137} 137}
@@ -139,7 +139,7 @@ static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
139static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) 139static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
140{ 140{
141 while (--count >= 0) { 141 while (--count >= 0) {
142 __raw_writew(*src, addr); 142 __mem_writew(*src, addr);
143 src++; 143 src++;
144 } 144 }
145} 145}
@@ -147,7 +147,7 @@ static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
147static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) 147static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
148{ 148{
149 while (--count >= 0) { 149 while (--count >= 0) {
150 __raw_writel(*src, addr); 150 __mem_writel(*src, addr);
151 src++; 151 src++;
152 } 152 }
153} 153}