Skip to content

Commit 019d6be

Browse files
author
Martin Schwidefsky
committed
s390/zcore: simplify memcpy_hsa
Replace the three part copy logic int memcpy_hsa with a single loop around sclp_sdias_copy with appropriate offset and size calculations, and inline memcpy_hsa into memcpy_hsa_user and memcpy_hsa_kernel. Acked-by: Michael Holzheu <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent df9694c commit 019d6be

File tree

1 file changed

+33
-68
lines changed

1 file changed

+33
-68
lines changed

drivers/s390/char/zcore.c

Lines changed: 33 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434

3535
#define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
3636

37-
#define TO_USER 1
38-
#define TO_KERNEL 0
3937
#define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */
4038

4139
enum arch_id {
@@ -56,88 +54,38 @@ static struct dentry *zcore_reipl_file;
5654
static struct dentry *zcore_hsa_file;
5755
static struct ipl_parameter_block *ipl_block;
5856

57+
static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE);
58+
5959
/*
60-
* Copy memory from HSA to kernel or user memory (not reentrant):
60+
* Copy memory from HSA to user memory (not reentrant):
6161
*
62-
* @dest: Kernel or user buffer where memory should be copied to
62+
* @dest: User buffer where memory should be copied to
6363
* @src: Start address within HSA where data should be copied
6464
* @count: Size of buffer, which should be copied
65-
* @mode: Either TO_KERNEL or TO_USER
6665
*/
67-
static int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode)
66+
int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
6867
{
69-
int offs, blk_num;
70-
static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
68+
unsigned long offset, bytes;
7169

7270
if (!hsa_available)
7371
return -ENODATA;
74-
if (count == 0)
75-
return 0;
76-
77-
/* copy first block */
78-
offs = 0;
79-
if ((src % PAGE_SIZE) != 0) {
80-
blk_num = src / PAGE_SIZE + 2;
81-
if (sclp_sdias_copy(buf, blk_num, 1)) {
82-
TRACE("sclp_sdias_copy() failed\n");
83-
return -EIO;
84-
}
85-
offs = min((PAGE_SIZE - (src % PAGE_SIZE)), count);
86-
if (mode == TO_USER) {
87-
if (copy_to_user((__force __user void*) dest,
88-
buf + (src % PAGE_SIZE), offs))
89-
return -EFAULT;
90-
} else
91-
memcpy(dest, buf + (src % PAGE_SIZE), offs);
92-
}
93-
if (offs == count)
94-
goto out;
9572

96-
/* copy middle */
97-
for (; (offs + PAGE_SIZE) <= count; offs += PAGE_SIZE) {
98-
blk_num = (src + offs) / PAGE_SIZE + 2;
99-
if (sclp_sdias_copy(buf, blk_num, 1)) {
73+
while (count) {
74+
if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
10075
TRACE("sclp_sdias_copy() failed\n");
10176
return -EIO;
10277
}
103-
if (mode == TO_USER) {
104-
if (copy_to_user((__force __user void*) dest + offs,
105-
buf, PAGE_SIZE))
106-
return -EFAULT;
107-
} else
108-
memcpy(dest + offs, buf, PAGE_SIZE);
109-
}
110-
if (offs == count)
111-
goto out;
112-
113-
/* copy last block */
114-
blk_num = (src + offs) / PAGE_SIZE + 2;
115-
if (sclp_sdias_copy(buf, blk_num, 1)) {
116-
TRACE("sclp_sdias_copy() failed\n");
117-
return -EIO;
118-
}
119-
if (mode == TO_USER) {
120-
if (copy_to_user((__force __user void*) dest + offs, buf,
121-
count - offs))
78+
offset = src % PAGE_SIZE;
79+
bytes = min(PAGE_SIZE - offset, count);
80+
if (copy_to_user(dest, hsa_buf + offset, bytes))
12281
return -EFAULT;
123-
} else
124-
memcpy(dest + offs, buf, count - offs);
125-
out:
82+
src += bytes;
83+
dest += bytes;
84+
count -= bytes;
85+
}
12686
return 0;
12787
}
12888

129-
/*
130-
* Copy memory from HSA to user memory (not reentrant):
131-
*
132-
* @dest: Kernel or user buffer where memory should be copied to
133-
* @src: Start address within HSA where data should be copied
134-
* @count: Size of buffer, which should be copied
135-
*/
136-
int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
137-
{
138-
return memcpy_hsa((void __force *) dest, src, count, TO_USER);
139-
}
140-
14189
/*
14290
* Copy memory from HSA to kernel memory (not reentrant):
14391
*
@@ -147,7 +95,24 @@ int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
14795
*/
14896
int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
14997
{
150-
return memcpy_hsa(dest, src, count, TO_KERNEL);
98+
unsigned long offset, bytes;
99+
100+
if (!hsa_available)
101+
return -ENODATA;
102+
103+
while (count) {
104+
if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
105+
TRACE("sclp_sdias_copy() failed\n");
106+
return -EIO;
107+
}
108+
offset = src % PAGE_SIZE;
109+
bytes = min(PAGE_SIZE - offset, count);
110+
memcpy(dest, hsa_buf + offset, bytes);
111+
src += bytes;
112+
dest += bytes;
113+
count -= bytes;
114+
}
115+
return 0;
151116
}
152117

153118
static int __init init_cpu_info(void)

0 commit comments

Comments
 (0)