34
34
35
35
#define TRACE (x ...) debug_sprintf_event(zcore_dbf, 1, x)
36
36
37
- #define TO_USER 1
38
- #define TO_KERNEL 0
39
37
#define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */
40
38
41
39
enum arch_id {
@@ -56,88 +54,38 @@ static struct dentry *zcore_reipl_file;
56
54
static struct dentry * zcore_hsa_file ;
57
55
static struct ipl_parameter_block * ipl_block ;
58
56
57
+ static char hsa_buf [PAGE_SIZE ] __aligned (PAGE_SIZE );
58
+
59
59
/*
60
- * Copy memory from HSA to kernel or user memory (not reentrant):
60
+ * Copy memory from HSA to user memory (not reentrant):
61
61
*
62
- * @dest: Kernel or user buffer where memory should be copied to
62
+ * @dest: User buffer where memory should be copied to
63
63
* @src: Start address within HSA where data should be copied
64
64
* @count: Size of buffer, which should be copied
65
- * @mode: Either TO_KERNEL or TO_USER
66
65
*/
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 )
68
67
{
69
- int offs , blk_num ;
70
- static char buf [PAGE_SIZE ] __attribute__((__aligned__ (PAGE_SIZE )));
68
+ unsigned long offset , bytes ;
71
69
72
70
if (!hsa_available )
73
71
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 ;
95
72
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 )) {
100
75
TRACE ("sclp_sdias_copy() failed\n" );
101
76
return - EIO ;
102
77
}
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 ))
122
81
return - EFAULT ;
123
- } else
124
- memcpy (dest + offs , buf , count - offs );
125
- out :
82
+ src += bytes ;
83
+ dest += bytes ;
84
+ count -= bytes ;
85
+ }
126
86
return 0 ;
127
87
}
128
88
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
-
141
89
/*
142
90
* Copy memory from HSA to kernel memory (not reentrant):
143
91
*
@@ -147,7 +95,24 @@ int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
147
95
*/
148
96
int memcpy_hsa_kernel (void * dest , unsigned long src , size_t count )
149
97
{
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 ;
151
116
}
152
117
153
118
static int __init init_cpu_info (void )
0 commit comments