Skip to content

Commit 4d3b066

Browse files
Michael HolzheuMartin Schwidefsky
authored andcommitted
s390: Allow vmalloc target buffers for copy_from_oldmem()
Currently copy_from_oldmem() is not able to copy to virtual memory. When using kexec pre-allocated ELF header, copy_from_oldmem() is used to copy the ELF notes information to vmalloc buffers. So fix this and use the new function copy_from_realmem() that allows copying also to vmalloc memory. Signed-off-by: Michael Holzheu <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 22bfda6 commit 4d3b066

File tree

1 file changed

+20
-22
lines changed

1 file changed

+20
-22
lines changed

arch/s390/kernel/crash_dump.c

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,26 @@ static inline void *load_real_addr(void *addr)
4040
}
4141

4242
/*
43-
* Copy up to one page to vmalloc or real memory
43+
* Copy real to virtual or real memory
4444
*/
45-
static ssize_t copy_page_real(void *buf, void *src, size_t csize)
45+
static int copy_from_realmem(void *dest, void *src, size_t count)
4646
{
47-
size_t size;
47+
unsigned long size;
48+
int rc;
4849

49-
if (is_vmalloc_addr(buf)) {
50-
BUG_ON(csize >= PAGE_SIZE);
51-
/* If buf is not page aligned, copy first part */
52-
size = min(roundup(__pa(buf), PAGE_SIZE) - __pa(buf), csize);
53-
if (size) {
54-
if (memcpy_real(load_real_addr(buf), src, size))
55-
return -EFAULT;
56-
buf += size;
57-
src += size;
58-
}
59-
/* Copy second part */
60-
size = csize - size;
61-
return (size) ? memcpy_real(load_real_addr(buf), src, size) : 0;
62-
} else {
63-
return memcpy_real(buf, src, csize);
64-
}
50+
if (!count)
51+
return 0;
52+
if (!is_vmalloc_or_module_addr(dest))
53+
return memcpy_real(dest, src, count);
54+
do {
55+
size = min(count, PAGE_SIZE - (__pa(dest) & ~PAGE_MASK));
56+
if (memcpy_real(load_real_addr(dest), src, size))
57+
return -EFAULT;
58+
count -= size;
59+
dest += size;
60+
src += size;
61+
} while (count);
62+
return 0;
6563
}
6664

6765
/*
@@ -114,7 +112,7 @@ static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize,
114112
rc = copy_to_user_real((void __force __user *) buf,
115113
(void *) src, csize);
116114
else
117-
rc = copy_page_real(buf, (void *) src, csize);
115+
rc = copy_from_realmem(buf, (void *) src, csize);
118116
return (rc == 0) ? rc : csize;
119117
}
120118

@@ -210,7 +208,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count)
210208
if (OLDMEM_BASE) {
211209
if ((unsigned long) src < OLDMEM_SIZE) {
212210
copied = min(count, OLDMEM_SIZE - (unsigned long) src);
213-
rc = memcpy_real(dest, src + OLDMEM_BASE, copied);
211+
rc = copy_from_realmem(dest, src + OLDMEM_BASE, copied);
214212
if (rc)
215213
return rc;
216214
}
@@ -223,7 +221,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count)
223221
return rc;
224222
}
225223
}
226-
return memcpy_real(dest + copied, src + copied, count - copied);
224+
return copy_from_realmem(dest + copied, src + copied, count - copied);
227225
}
228226

229227
/*

0 commit comments

Comments
 (0)