diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-04-16 08:17:15 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-04-17 08:07:38 -0400 |
commit | b170bad40dab1a1684d629b37cb65a5281d35bd8 (patch) | |
tree | 40f24811118d28edda9a99b40599f59913f01615 /arch/s390/pci | |
parent | f0bacb7fc4f7defb15a6575d92f8ea4342f8f09e (diff) |
s390/pci: do not read data after failed load
If a pci load instruction fails the content of the register where the
data is stored is possibly unchanged. Fix the inline assembly wrapper
__pcilg to not return stale data. Additionally fix the callers of this
function who access uninitialized variables.
Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/pci')
-rw-r--r-- | arch/s390/pci/pci.c | 8 | ||||
-rw-r--r-- | arch/s390/pci/pci_insn.c | 4 |
2 files changed, 7 insertions, 5 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 2b21749cc2b3..51d16f1fb5ea 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -281,11 +281,11 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) | |||
281 | int rc; | 281 | int rc; |
282 | 282 | ||
283 | rc = s390pci_load(&data, req, offset); | 283 | rc = s390pci_load(&data, req, offset); |
284 | data = data << ((8 - len) * 8); | 284 | if (!rc) { |
285 | data = le64_to_cpu(data); | 285 | data = data << ((8 - len) * 8); |
286 | if (!rc) | 286 | data = le64_to_cpu(data); |
287 | *val = (u32) data; | 287 | *val = (u32) data; |
288 | else | 288 | } else |
289 | *val = 0xffffffff; | 289 | *val = 0xffffffff; |
290 | return rc; | 290 | return rc; |
291 | } | 291 | } |
diff --git a/arch/s390/pci/pci_insn.c b/arch/s390/pci/pci_insn.c index 4bc32f368f7d..22eeb9d7ffeb 100644 --- a/arch/s390/pci/pci_insn.c +++ b/arch/s390/pci/pci_insn.c | |||
@@ -103,7 +103,9 @@ static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status) | |||
103 | : "d" (__offset) | 103 | : "d" (__offset) |
104 | : "cc"); | 104 | : "cc"); |
105 | *status = __req >> 24 & 0xff; | 105 | *status = __req >> 24 & 0xff; |
106 | *data = __data; | 106 | if (!cc) |
107 | *data = __data; | ||
108 | |||
107 | return cc; | 109 | return cc; |
108 | } | 110 | } |
109 | 111 | ||