Skip to content

Commit 77bfc8b

Browse files
linuswarndb
authored andcommitted
parisc: Remove 64bit access on 32bit machines
The parisc was using some readq/writeq accessors without special considerations as to what will happen on 32bit CPUs if you do this. Maybe we have been lucky that it "just worked" on 32bit due to the compiler behaviour, or the code paths were never executed. Fix the two offending code sites like this: arch/parisc/lib/iomap.c: - Put ifdefs around the 64bit accessors and make sure that ioread64, ioread64be, iowrite64 and iowrite64be are not available on 32bit builds. - Also fold in a bug fix where 64bit access was by mistake using 32bit writel() accessors rather than 64bit writeq(). drivers/parisc/sba_iommu.c: - Access any 64bit registers using _lo_hi-semantics by way of the readq and writeq operations provided by <linux/io-64-nonatomic-lo-hi.h> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Cc: James E.J. Bottomley <James.Bottomley@HansenPartnership.com> Cc: Helge Deller <deller@gmx.de> Cc: linux-parisc@vger.kernel.org Cc: linux-arch@vger.kernel.org Cc: Arnd Bergmann <arnd@arndb.de> Cc: John David Anglin <dave.anglin@bell.net> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
1 parent 2c23043 commit 77bfc8b

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

arch/parisc/lib/iomap.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,19 @@ struct iomap_ops {
4848
unsigned int (*read16be)(const void __iomem *);
4949
unsigned int (*read32)(const void __iomem *);
5050
unsigned int (*read32be)(const void __iomem *);
51+
#ifdef CONFIG_64BIT
5152
u64 (*read64)(const void __iomem *);
5253
u64 (*read64be)(const void __iomem *);
54+
#endif
5355
void (*write8)(u8, void __iomem *);
5456
void (*write16)(u16, void __iomem *);
5557
void (*write16be)(u16, void __iomem *);
5658
void (*write32)(u32, void __iomem *);
5759
void (*write32be)(u32, void __iomem *);
60+
#ifdef CONFIG_64BIT
5861
void (*write64)(u64, void __iomem *);
5962
void (*write64be)(u64, void __iomem *);
63+
#endif
6064
void (*read8r)(const void __iomem *, void *, unsigned long);
6165
void (*read16r)(const void __iomem *, void *, unsigned long);
6266
void (*read32r)(const void __iomem *, void *, unsigned long);
@@ -175,6 +179,7 @@ static unsigned int iomem_read32be(const void __iomem *addr)
175179
return __raw_readl(addr);
176180
}
177181

182+
#ifdef CONFIG_64BIT
178183
static u64 iomem_read64(const void __iomem *addr)
179184
{
180185
return readq(addr);
@@ -184,6 +189,7 @@ static u64 iomem_read64be(const void __iomem *addr)
184189
{
185190
return __raw_readq(addr);
186191
}
192+
#endif
187193

188194
static void iomem_write8(u8 datum, void __iomem *addr)
189195
{
@@ -210,15 +216,17 @@ static void iomem_write32be(u32 datum, void __iomem *addr)
210216
__raw_writel(datum, addr);
211217
}
212218

219+
#ifdef CONFIG_64BIT
213220
static void iomem_write64(u64 datum, void __iomem *addr)
214221
{
215-
writel(datum, addr);
222+
writeq(datum, addr);
216223
}
217224

218225
static void iomem_write64be(u64 datum, void __iomem *addr)
219226
{
220-
__raw_writel(datum, addr);
227+
__raw_writeq(datum, addr);
221228
}
229+
#endif
222230

223231
static void iomem_read8r(const void __iomem *addr, void *dst, unsigned long count)
224232
{
@@ -274,15 +282,19 @@ static const struct iomap_ops iomem_ops = {
274282
.read16be = iomem_read16be,
275283
.read32 = iomem_read32,
276284
.read32be = iomem_read32be,
285+
#ifdef CONFIG_64BIT
277286
.read64 = iomem_read64,
278287
.read64be = iomem_read64be,
288+
#endif
279289
.write8 = iomem_write8,
280290
.write16 = iomem_write16,
281291
.write16be = iomem_write16be,
282292
.write32 = iomem_write32,
283293
.write32be = iomem_write32be,
294+
#ifdef CONFIG_64BIT
284295
.write64 = iomem_write64,
285296
.write64be = iomem_write64be,
297+
#endif
286298
.read8r = iomem_read8r,
287299
.read16r = iomem_read16r,
288300
.read32r = iomem_read32r,
@@ -332,6 +344,7 @@ unsigned int ioread32be(const void __iomem *addr)
332344
return *((u32 *)addr);
333345
}
334346

347+
#ifdef CONFIG_64BIT
335348
u64 ioread64(const void __iomem *addr)
336349
{
337350
if (unlikely(INDIRECT_ADDR(addr)))
@@ -345,6 +358,7 @@ u64 ioread64be(const void __iomem *addr)
345358
return iomap_ops[ADDR_TO_REGION(addr)]->read64be(addr);
346359
return *((u64 *)addr);
347360
}
361+
#endif
348362

349363
u64 ioread64_lo_hi(const void __iomem *addr)
350364
{
@@ -411,6 +425,7 @@ void iowrite32be(u32 datum, void __iomem *addr)
411425
}
412426
}
413427

428+
#ifdef CONFIG_64BIT
414429
void iowrite64(u64 datum, void __iomem *addr)
415430
{
416431
if (unlikely(INDIRECT_ADDR(addr))) {
@@ -428,6 +443,7 @@ void iowrite64be(u64 datum, void __iomem *addr)
428443
*((u64 *)addr) = datum;
429444
}
430445
}
446+
#endif
431447

432448
void iowrite64_lo_hi(u64 val, void __iomem *addr)
433449
{
@@ -544,17 +560,21 @@ EXPORT_SYMBOL(ioread16);
544560
EXPORT_SYMBOL(ioread16be);
545561
EXPORT_SYMBOL(ioread32);
546562
EXPORT_SYMBOL(ioread32be);
563+
#ifdef CONFIG_64BIT
547564
EXPORT_SYMBOL(ioread64);
548565
EXPORT_SYMBOL(ioread64be);
566+
#endif
549567
EXPORT_SYMBOL(ioread64_lo_hi);
550568
EXPORT_SYMBOL(ioread64_hi_lo);
551569
EXPORT_SYMBOL(iowrite8);
552570
EXPORT_SYMBOL(iowrite16);
553571
EXPORT_SYMBOL(iowrite16be);
554572
EXPORT_SYMBOL(iowrite32);
555573
EXPORT_SYMBOL(iowrite32be);
574+
#ifdef CONFIG_64BIT
556575
EXPORT_SYMBOL(iowrite64);
557576
EXPORT_SYMBOL(iowrite64be);
577+
#endif
558578
EXPORT_SYMBOL(iowrite64_lo_hi);
559579
EXPORT_SYMBOL(iowrite64_hi_lo);
560580
EXPORT_SYMBOL(ioread8_rep);

drivers/parisc/sba_iommu.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
#include <linux/dma-map-ops.h>
2929
#include <linux/scatterlist.h>
3030
#include <linux/iommu-helper.h>
31+
/*
32+
* The semantics of 64 register access on 32bit systems can't be guaranteed
33+
* by the C standard, we hope the _lo_hi() macros defining readq and writeq
34+
* here will behave as expected.
35+
*/
36+
#include <linux/io-64-nonatomic-lo-hi.h>
3137

3238
#include <asm/byteorder.h>
3339
#include <asm/io.h>

0 commit comments

Comments
 (0)