Commit dbee8a0affd5e6eaa5d7c816c4bc233f6f110f50
x86: remove 32-bit versions of readq()/writeq()
The presense of a writeq() implementation on 32-bit x86 that splits the 64-bit write into two 32-bit writes turns out to break the mpt2sas driver (and in general is risky for drivers as was discussed in <http://lkml.kernel.org/r/adaab6c1h7c.fsf@cisco.com>). To fix this, revert 2c5643b1c5c7 ("x86: provide readq()/writeq() on 32-bit too") and follow-on cleanups. This unfortunately leads to pushing non-atomic definitions of readq() and write() to various x86-only drivers that in the meantime started using the definitions in the x86 version of <asm/io.h>. However as discussed exhaustively, this is actually the right thing to do, because the right way to split a 64-bit transaction is hardware dependent and therefore belongs in the hardware driver (eg mpt2sas needs a spinlock to make sure no other accesses occur in between the two halves of the access). Build tested on 32- and 64-bit x86 allmodconfig. Link: http://lkml.kernel.org/r/x86-32-writeq-is-broken@mdm.bga.com Acked-by: Hitoshi Mitake <h.mitake@gmail.com> Cc: Kashyap Desai <Kashyap.Desai@lsi.com> Cc: Len Brown <lenb@kernel.org> Cc: Ravi Anand <ravi.anand@qlogic.com> Cc: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Cc: Matthew Garrett <mjg@redhat.com> Cc: Jason Uhlenkott <juhlenko@akamai.com> Acked-by: James Bottomley <James.Bottomley@parallels.com> Acked-by: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Signed-off-by: Roland Dreier <roland@purestorage.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 8 changed files with 74 additions and 24 deletions Side-by-side Diff
... | ... | @@ -38,7 +38,6 @@ |
38 | 38 | |
39 | 39 | #include <linux/string.h> |
40 | 40 | #include <linux/compiler.h> |
41 | -#include <asm-generic/int-ll64.h> | |
42 | 41 | #include <asm/page.h> |
43 | 42 | |
44 | 43 | #include <xen/xen.h> |
... | ... | @@ -87,27 +86,6 @@ |
87 | 86 | build_mmio_read(readq, "q", unsigned long, "=r", :"memory") |
88 | 87 | build_mmio_write(writeq, "q", unsigned long, "r", :"memory") |
89 | 88 | |
90 | -#else | |
91 | - | |
92 | -static inline __u64 readq(const volatile void __iomem *addr) | |
93 | -{ | |
94 | - const volatile u32 __iomem *p = addr; | |
95 | - u32 low, high; | |
96 | - | |
97 | - low = readl(p); | |
98 | - high = readl(p + 1); | |
99 | - | |
100 | - return low + ((u64)high << 32); | |
101 | -} | |
102 | - | |
103 | -static inline void writeq(__u64 val, volatile void __iomem *addr) | |
104 | -{ | |
105 | - writel(val, addr); | |
106 | - writel(val >> 32, addr+4); | |
107 | -} | |
108 | - | |
109 | -#endif | |
110 | - | |
111 | 89 | #define readq_relaxed(a) readq(a) |
112 | 90 | |
113 | 91 | #define __raw_readq(a) readq(a) |
... | ... | @@ -116,6 +94,8 @@ |
116 | 94 | /* Let people know that we have them */ |
117 | 95 | #define readq readq |
118 | 96 | #define writeq writeq |
97 | + | |
98 | +#endif | |
119 | 99 | |
120 | 100 | /** |
121 | 101 | * virt_to_phys - map virtual addresses to physical |
... | ... | @@ -101,6 +101,14 @@ |
101 | 101 | |
102 | 102 | static struct einj_parameter *einj_param; |
103 | 103 | |
104 | +#ifndef writeq | |
105 | +static inline void writeq(__u64 val, volatile void __iomem *addr) | |
106 | +{ | |
107 | + writel(val, addr); | |
108 | + writel(val >> 32, addr+4); | |
109 | +} | |
110 | +#endif | |
111 | + | |
104 | 112 | static void einj_exec_ctx_init(struct apei_exec_context *ctx) |
105 | 113 | { |
106 | 114 | apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), |
... | ... | @@ -280,9 +280,11 @@ |
280 | 280 | case 32: |
281 | 281 | *val = readl(addr); |
282 | 282 | break; |
283 | +#ifdef readq | |
283 | 284 | case 64: |
284 | 285 | *val = readq(addr); |
285 | 286 | break; |
287 | +#endif | |
286 | 288 | default: |
287 | 289 | return -EINVAL; |
288 | 290 | } |
289 | 291 | |
... | ... | @@ -307,9 +309,11 @@ |
307 | 309 | case 32: |
308 | 310 | writel(val, addr); |
309 | 311 | break; |
312 | +#ifdef writeq | |
310 | 313 | case 64: |
311 | 314 | writeq(val, addr); |
312 | 315 | break; |
316 | +#endif | |
313 | 317 | default: |
314 | 318 | return -EINVAL; |
315 | 319 | } |
... | ... | @@ -101,6 +101,19 @@ |
101 | 101 | |
102 | 102 | static int nr_channels; |
103 | 103 | |
104 | +#ifndef readq | |
105 | +static inline __u64 readq(const volatile void __iomem *addr) | |
106 | +{ | |
107 | + const volatile u32 __iomem *p = addr; | |
108 | + u32 low, high; | |
109 | + | |
110 | + low = readl(p); | |
111 | + high = readl(p + 1); | |
112 | + | |
113 | + return low + ((u64)high << 32); | |
114 | +} | |
115 | +#endif | |
116 | + | |
104 | 117 | static int how_many_channels(struct pci_dev *pdev) |
105 | 118 | { |
106 | 119 | unsigned char capid0_8b; /* 8th byte of CAPID0 */ |
... | ... | @@ -81,6 +81,19 @@ |
81 | 81 | static u8 rtl_cmd_type; |
82 | 82 | static u8 rtl_cmd_width; |
83 | 83 | |
84 | +#ifndef readq | |
85 | +static inline __u64 readq(const volatile void __iomem *addr) | |
86 | +{ | |
87 | + const volatile u32 __iomem *p = addr; | |
88 | + u32 low, high; | |
89 | + | |
90 | + low = readl(p); | |
91 | + high = readl(p + 1); | |
92 | + | |
93 | + return low + ((u64)high << 32); | |
94 | +} | |
95 | +#endif | |
96 | + | |
84 | 97 | static void __iomem *rtl_port_map(phys_addr_t addr, unsigned long len) |
85 | 98 | { |
86 | 99 | if (rtl_cmd_type == RTL_ADDR_TYPE_MMIO) |
... | ... | @@ -344,6 +344,19 @@ |
344 | 344 | static bool |
345 | 345 | ips_gpu_turbo_enabled(struct ips_driver *ips); |
346 | 346 | |
347 | +#ifndef readq | |
348 | +static inline __u64 readq(const volatile void __iomem *addr) | |
349 | +{ | |
350 | + const volatile u32 __iomem *p = addr; | |
351 | + u32 low, high; | |
352 | + | |
353 | + low = readl(p); | |
354 | + high = readl(p + 1); | |
355 | + | |
356 | + return low + ((u64)high << 32); | |
357 | +} | |
358 | +#endif | |
359 | + | |
347 | 360 | /** |
348 | 361 | * ips_cpu_busy - is CPU busy? |
349 | 362 | * @ips: IPS driver struct |
... | ... | @@ -655,6 +655,27 @@ |
655 | 655 | return 0; |
656 | 656 | } |
657 | 657 | |
658 | +#ifndef readq | |
659 | +static inline __u64 readq(const volatile void __iomem *addr) | |
660 | +{ | |
661 | + const volatile u32 __iomem *p = addr; | |
662 | + u32 low, high; | |
663 | + | |
664 | + low = readl(p); | |
665 | + high = readl(p + 1); | |
666 | + | |
667 | + return low + ((u64)high << 32); | |
668 | +} | |
669 | +#endif | |
670 | + | |
671 | +#ifndef writeq | |
672 | +static inline void writeq(__u64 val, volatile void __iomem *addr) | |
673 | +{ | |
674 | + writel(val, addr); | |
675 | + writel(val >> 32, addr+4); | |
676 | +} | |
677 | +#endif | |
678 | + | |
658 | 679 | static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha, |
659 | 680 | u64 off, void *data, int size) |
660 | 681 | { |
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79
-
mentioned in commit 797a79