diff options
| author | Jason Baron <jbaron@akamai.com> | 2014-07-04 07:27:04 -0400 |
|---|---|---|
| committer | Borislav Petkov <bp@suse.de> | 2014-07-04 07:27:30 -0400 |
| commit | 3a044178cccfeb8664423c2950c499c3a209ed9f (patch) | |
| tree | 8e9f4ba1747353932ed218157d05915b28b920c7 /include/asm-generic | |
| parent | 6866b390562b2c948c6f6fc2a5c103f090a02e01 (diff) | |
readq/writeq: Add explicit lo_hi_[read|write]_q and hi_lo_[read|write]_q
Even on x86-64, I've found the need to break up a readq() into 2 readl()
calls. According to the Intel datasheet for the E3-1200 processor:
"
Software must not access B0/D0/F0 32-bit memory-mapped registers with
requests that cross a DW boundary.
"
(http://www.intel.com/content/www/us/en/processors/xeon/xeon-e3-1200-family-vol-2-datasheet.html p. 16)
I can confirm this is true via several hard machine lockups.
Thus, add explicit hi_lo_[readq|write]_q and lo_hi_[read|write]_q so that these
uses are spelled out.
Signed-off-by: Jason Baron <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/281f09da7ad01e5cea99737ec34d2399bdbbbf63.1403818526.git.jbaron@akamai.com
Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'include/asm-generic')
| -rw-r--r-- | include/asm-generic/io-64-nonatomic-hi-lo.h | 14 | ||||
| -rw-r--r-- | include/asm-generic/io-64-nonatomic-lo-hi.h | 14 |
2 files changed, 18 insertions, 10 deletions
diff --git a/include/asm-generic/io-64-nonatomic-hi-lo.h b/include/asm-generic/io-64-nonatomic-hi-lo.h index a6806a94250d..2e29d13fc154 100644 --- a/include/asm-generic/io-64-nonatomic-hi-lo.h +++ b/include/asm-generic/io-64-nonatomic-hi-lo.h | |||
| @@ -4,8 +4,7 @@ | |||
| 4 | #include <linux/io.h> | 4 | #include <linux/io.h> |
| 5 | #include <asm-generic/int-ll64.h> | 5 | #include <asm-generic/int-ll64.h> |
| 6 | 6 | ||
| 7 | #ifndef readq | 7 | static inline __u64 hi_lo_readq(const volatile void __iomem *addr) |
| 8 | static inline __u64 readq(const volatile void __iomem *addr) | ||
| 9 | { | 8 | { |
| 10 | const volatile u32 __iomem *p = addr; | 9 | const volatile u32 __iomem *p = addr; |
| 11 | u32 low, high; | 10 | u32 low, high; |
| @@ -15,14 +14,19 @@ static inline __u64 readq(const volatile void __iomem *addr) | |||
| 15 | 14 | ||
| 16 | return low + ((u64)high << 32); | 15 | return low + ((u64)high << 32); |
| 17 | } | 16 | } |
| 18 | #endif | ||
| 19 | 17 | ||
| 20 | #ifndef writeq | 18 | static inline void hi_lo_writeq(__u64 val, volatile void __iomem *addr) |
| 21 | static inline void writeq(__u64 val, volatile void __iomem *addr) | ||
| 22 | { | 19 | { |
| 23 | writel(val >> 32, addr + 4); | 20 | writel(val >> 32, addr + 4); |
| 24 | writel(val, addr); | 21 | writel(val, addr); |
| 25 | } | 22 | } |
| 23 | |||
| 24 | #ifndef readq | ||
| 25 | #define readq hi_lo_readq | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #ifndef writeq | ||
| 29 | #define writeq hi_lo_writeq | ||
| 26 | #endif | 30 | #endif |
| 27 | 31 | ||
| 28 | #endif /* _ASM_IO_64_NONATOMIC_HI_LO_H_ */ | 32 | #endif /* _ASM_IO_64_NONATOMIC_HI_LO_H_ */ |
diff --git a/include/asm-generic/io-64-nonatomic-lo-hi.h b/include/asm-generic/io-64-nonatomic-lo-hi.h index ca546b1ff8b5..0efacff0a1ce 100644 --- a/include/asm-generic/io-64-nonatomic-lo-hi.h +++ b/include/asm-generic/io-64-nonatomic-lo-hi.h | |||
| @@ -4,8 +4,7 @@ | |||
| 4 | #include <linux/io.h> | 4 | #include <linux/io.h> |
| 5 | #include <asm-generic/int-ll64.h> | 5 | #include <asm-generic/int-ll64.h> |
| 6 | 6 | ||
| 7 | #ifndef readq | 7 | static inline __u64 lo_hi_readq(const volatile void __iomem *addr) |
| 8 | static inline __u64 readq(const volatile void __iomem *addr) | ||
| 9 | { | 8 | { |
| 10 | const volatile u32 __iomem *p = addr; | 9 | const volatile u32 __iomem *p = addr; |
| 11 | u32 low, high; | 10 | u32 low, high; |
| @@ -15,14 +14,19 @@ static inline __u64 readq(const volatile void __iomem *addr) | |||
| 15 | 14 | ||
| 16 | return low + ((u64)high << 32); | 15 | return low + ((u64)high << 32); |
| 17 | } | 16 | } |
| 18 | #endif | ||
| 19 | 17 | ||
| 20 | #ifndef writeq | 18 | static inline void lo_hi_writeq(__u64 val, volatile void __iomem *addr) |
| 21 | static inline void writeq(__u64 val, volatile void __iomem *addr) | ||
| 22 | { | 19 | { |
| 23 | writel(val, addr); | 20 | writel(val, addr); |
| 24 | writel(val >> 32, addr + 4); | 21 | writel(val >> 32, addr + 4); |
| 25 | } | 22 | } |
| 23 | |||
| 24 | #ifndef readq | ||
| 25 | #define readq lo_hi_readq | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #ifndef writeq | ||
| 29 | #define writeq lo_hi_writeq | ||
| 26 | #endif | 30 | #endif |
| 27 | 31 | ||
| 28 | #endif /* _ASM_IO_64_NONATOMIC_LO_HI_H_ */ | 32 | #endif /* _ASM_IO_64_NONATOMIC_LO_HI_H_ */ |
