@@ -56,6 +56,13 @@ static unsigned long um_pci_msi_used[BITS_TO_LONGS(MAX_MSI_VECTORS)];
56
56
57
57
#define UM_VIRT_PCI_MAXDELAY 40000
58
58
59
+ struct um_pci_message_buffer {
60
+ struct virtio_pcidev_msg hdr ;
61
+ u8 data [8 ];
62
+ };
63
+
64
+ static struct um_pci_message_buffer __percpu * um_pci_msg_bufs ;
65
+
59
66
static int um_pci_send_cmd (struct um_pci_device * dev ,
60
67
struct virtio_pcidev_msg * cmd ,
61
68
unsigned int cmd_size ,
@@ -68,11 +75,12 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
68
75
[1 ] = extra ? & extra_sg : & in_sg ,
69
76
[2 ] = extra ? & in_sg : NULL ,
70
77
};
78
+ struct um_pci_message_buffer * buf ;
71
79
int delay_count = 0 ;
72
80
int ret , len ;
73
81
bool posted ;
74
82
75
- if (WARN_ON (cmd_size < sizeof (* cmd )))
83
+ if (WARN_ON (cmd_size < sizeof (* cmd ) || cmd_size > sizeof ( * buf ) ))
76
84
return - EINVAL ;
77
85
78
86
switch (cmd -> op ) {
@@ -88,6 +96,9 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
88
96
break ;
89
97
}
90
98
99
+ buf = get_cpu_var (um_pci_msg_bufs );
100
+ memcpy (buf , cmd , cmd_size );
101
+
91
102
if (posted ) {
92
103
u8 * ncmd = kmalloc (cmd_size + extra_size , GFP_ATOMIC );
93
104
@@ -102,7 +113,10 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
102
113
} else {
103
114
/* try without allocating memory */
104
115
posted = false;
116
+ cmd = (void * )buf ;
105
117
}
118
+ } else {
119
+ cmd = (void * )buf ;
106
120
}
107
121
108
122
sg_init_one (& out_sg , cmd , cmd_size );
@@ -118,11 +132,12 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
118
132
posted ? cmd : HANDLE_NO_FREE (cmd ),
119
133
GFP_ATOMIC );
120
134
if (ret )
121
- return ret ;
135
+ goto out ;
122
136
123
137
if (posted ) {
124
138
virtqueue_kick (dev -> cmd_vq );
125
- return 0 ;
139
+ ret = 0 ;
140
+ goto out ;
126
141
}
127
142
128
143
/* kick and poll for getting a response on the queue */
@@ -148,6 +163,8 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
148
163
}
149
164
clear_bit (UM_PCI_STAT_WAITING , & dev -> status );
150
165
166
+ out :
167
+ put_cpu_var (um_pci_msg_bufs );
151
168
return ret ;
152
169
}
153
170
@@ -161,12 +178,17 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
161
178
.size = size ,
162
179
.addr = offset ,
163
180
};
164
- /* maximum size - we may only use parts of it */
165
- u8 data [8 ];
181
+ /* buf->data is maximum size - we may only use parts of it */
182
+ struct um_pci_message_buffer * buf ;
183
+ u8 * data ;
184
+ unsigned long ret = ~0ULL ;
166
185
167
186
if (!dev )
168
187
return ~0ULL ;
169
188
189
+ buf = get_cpu_var (um_pci_msg_bufs );
190
+ data = buf -> data ;
191
+
170
192
memset (data , 0xff , sizeof (data ));
171
193
172
194
switch (size ) {
@@ -179,27 +201,34 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
179
201
break ;
180
202
default :
181
203
WARN (1 , "invalid config space read size %d\n" , size );
182
- return ~ 0ULL ;
204
+ goto out ;
183
205
}
184
206
185
- if (um_pci_send_cmd (dev , & hdr , sizeof (hdr ), NULL , 0 ,
186
- data , sizeof (data )))
187
- return ~0ULL ;
207
+ if (um_pci_send_cmd (dev , & hdr , sizeof (hdr ), NULL , 0 , data , 8 ))
208
+ goto out ;
188
209
189
210
switch (size ) {
190
211
case 1 :
191
- return data [0 ];
212
+ ret = data [0 ];
213
+ break ;
192
214
case 2 :
193
- return le16_to_cpup ((void * )data );
215
+ ret = le16_to_cpup ((void * )data );
216
+ break ;
194
217
case 4 :
195
- return le32_to_cpup ((void * )data );
218
+ ret = le32_to_cpup ((void * )data );
219
+ break ;
196
220
#ifdef CONFIG_64BIT
197
221
case 8 :
198
- return le64_to_cpup ((void * )data );
222
+ ret = le64_to_cpup ((void * )data );
223
+ break ;
199
224
#endif
200
225
default :
201
- return ~ 0ULL ;
226
+ break ;
202
227
}
228
+
229
+ out :
230
+ put_cpu_var (um_pci_msg_bufs );
231
+ return ret ;
203
232
}
204
233
205
234
static void um_pci_cfgspace_write (void * priv , unsigned int offset , int size ,
@@ -272,8 +301,13 @@ static void um_pci_bar_copy_from(void *priv, void *buffer,
272
301
static unsigned long um_pci_bar_read (void * priv , unsigned int offset ,
273
302
int size )
274
303
{
275
- /* maximum size - we may only use parts of it */
276
- u8 data [8 ];
304
+ /* buf->data is maximum size - we may only use parts of it */
305
+ struct um_pci_message_buffer * buf ;
306
+ u8 * data ;
307
+ unsigned long ret = ~0ULL ;
308
+
309
+ buf = get_cpu_var (um_pci_msg_bufs );
310
+ data = buf -> data ;
277
311
278
312
switch (size ) {
279
313
case 1 :
@@ -285,25 +319,33 @@ static unsigned long um_pci_bar_read(void *priv, unsigned int offset,
285
319
break ;
286
320
default :
287
321
WARN (1 , "invalid config space read size %d\n" , size );
288
- return ~ 0ULL ;
322
+ goto out ;
289
323
}
290
324
291
325
um_pci_bar_copy_from (priv , data , offset , size );
292
326
293
327
switch (size ) {
294
328
case 1 :
295
- return data [0 ];
329
+ ret = data [0 ];
330
+ break ;
296
331
case 2 :
297
- return le16_to_cpup ((void * )data );
332
+ ret = le16_to_cpup ((void * )data );
333
+ break ;
298
334
case 4 :
299
- return le32_to_cpup ((void * )data );
335
+ ret = le32_to_cpup ((void * )data );
336
+ break ;
300
337
#ifdef CONFIG_64BIT
301
338
case 8 :
302
- return le64_to_cpup ((void * )data );
339
+ ret = le64_to_cpup ((void * )data );
340
+ break ;
303
341
#endif
304
342
default :
305
- return ~ 0ULL ;
343
+ break ;
306
344
}
345
+
346
+ out :
347
+ put_cpu_var (um_pci_msg_bufs );
348
+ return ret ;
307
349
}
308
350
309
351
static void um_pci_bar_copy_to (void * priv , unsigned int offset ,
@@ -823,10 +865,16 @@ static int um_pci_init(void)
823
865
"No virtio device ID configured for PCI - no PCI support\n" ))
824
866
return 0 ;
825
867
826
- bridge = pci_alloc_host_bridge ( 0 );
827
- if (!bridge )
868
+ um_pci_msg_bufs = alloc_percpu ( struct um_pci_message_buffer );
869
+ if (!um_pci_msg_bufs )
828
870
return - ENOMEM ;
829
871
872
+ bridge = pci_alloc_host_bridge (0 );
873
+ if (!bridge ) {
874
+ err = - ENOMEM ;
875
+ goto free ;
876
+ }
877
+
830
878
um_pci_fwnode = irq_domain_alloc_named_fwnode ("um-pci" );
831
879
if (!um_pci_fwnode ) {
832
880
err = - ENOMEM ;
@@ -878,8 +926,11 @@ static int um_pci_init(void)
878
926
irq_domain_remove (um_pci_inner_domain );
879
927
if (um_pci_fwnode )
880
928
irq_domain_free_fwnode (um_pci_fwnode );
881
- pci_free_resource_list (& bridge -> windows );
882
- pci_free_host_bridge (bridge );
929
+ if (bridge ) {
930
+ pci_free_resource_list (& bridge -> windows );
931
+ pci_free_host_bridge (bridge );
932
+ }
933
+ free_percpu (um_pci_msg_bufs );
883
934
return err ;
884
935
}
885
936
module_init (um_pci_init );
@@ -891,5 +942,6 @@ static void um_pci_exit(void)
891
942
irq_domain_remove (um_pci_inner_domain );
892
943
pci_free_resource_list (& bridge -> windows );
893
944
pci_free_host_bridge (bridge );
945
+ free_percpu (um_pci_msg_bufs );
894
946
}
895
947
module_exit (um_pci_exit );
0 commit comments