diff options
Diffstat (limited to 'drivers/s390/char/zcore.c')
-rw-r--r-- | drivers/s390/char/zcore.c | 38 |
1 files changed, 4 insertions, 34 deletions
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 3438658b66b7..7217966f7d31 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 13 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/slab.h> | ||
16 | #include <linux/miscdevice.h> | 17 | #include <linux/miscdevice.h> |
17 | #include <linux/debugfs.h> | 18 | #include <linux/debugfs.h> |
18 | #include <asm/asm-offsets.h> | 19 | #include <asm/asm-offsets.h> |
@@ -141,33 +142,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) | |||
141 | return memcpy_hsa(dest, src, count, TO_KERNEL); | 142 | return memcpy_hsa(dest, src, count, TO_KERNEL); |
142 | } | 143 | } |
143 | 144 | ||
144 | static int memcpy_real(void *dest, unsigned long src, size_t count) | ||
145 | { | ||
146 | unsigned long flags; | ||
147 | int rc = -EFAULT; | ||
148 | register unsigned long _dest asm("2") = (unsigned long) dest; | ||
149 | register unsigned long _len1 asm("3") = (unsigned long) count; | ||
150 | register unsigned long _src asm("4") = src; | ||
151 | register unsigned long _len2 asm("5") = (unsigned long) count; | ||
152 | |||
153 | if (count == 0) | ||
154 | return 0; | ||
155 | flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */ | ||
156 | asm volatile ( | ||
157 | "0: mvcle %1,%2,0x0\n" | ||
158 | "1: jo 0b\n" | ||
159 | " lhi %0,0x0\n" | ||
160 | "2:\n" | ||
161 | EX_TABLE(1b,2b) | ||
162 | : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1), | ||
163 | "+d" (_len2), "=m" (*((long*)dest)) | ||
164 | : "m" (*((long*)src)) | ||
165 | : "cc", "memory"); | ||
166 | __raw_local_irq_ssm(flags); | ||
167 | |||
168 | return rc; | ||
169 | } | ||
170 | |||
171 | static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) | 145 | static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) |
172 | { | 146 | { |
173 | static char buf[4096]; | 147 | static char buf[4096]; |
@@ -175,7 +149,7 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) | |||
175 | 149 | ||
176 | while (offs < count) { | 150 | while (offs < count) { |
177 | size = min(sizeof(buf), count - offs); | 151 | size = min(sizeof(buf), count - offs); |
178 | if (memcpy_real(buf, src + offs, size)) | 152 | if (memcpy_real(buf, (void *) src + offs, size)) |
179 | return -EFAULT; | 153 | return -EFAULT; |
180 | if (copy_to_user(dest + offs, buf, size)) | 154 | if (copy_to_user(dest + offs, buf, size)) |
181 | return -EFAULT; | 155 | return -EFAULT; |
@@ -663,12 +637,8 @@ static int __init zcore_reipl_init(void) | |||
663 | if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE) | 637 | if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE) |
664 | rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); | 638 | rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); |
665 | else | 639 | else |
666 | rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE); | 640 | rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE); |
667 | if (rc) { | 641 | if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) != |
668 | free_page((unsigned long) ipl_block); | ||
669 | return rc; | ||
670 | } | ||
671 | if (csum_partial(ipl_block, ipl_block->hdr.len, 0) != | ||
672 | ipib_info.checksum) { | 642 | ipib_info.checksum) { |
673 | TRACE("Checksum does not match\n"); | 643 | TRACE("Checksum does not match\n"); |
674 | free_page((unsigned long) ipl_block); | 644 | free_page((unsigned long) ipl_block); |