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
4139enum arch_id {
@@ -56,88 +54,38 @@ static struct dentry *zcore_reipl_file;
5654static struct dentry * zcore_hsa_file ;
5755static 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 */
14896int 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
153118static int __init init_cpu_info (void )
0 commit comments