@@ -56,6 +56,13 @@ static unsigned long um_pci_msi_used[BITS_TO_LONGS(MAX_MSI_VECTORS)];
5656
5757#define UM_VIRT_PCI_MAXDELAY 40000
5858
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+
5966static int um_pci_send_cmd (struct um_pci_device * dev ,
6067 struct virtio_pcidev_msg * cmd ,
6168 unsigned int cmd_size ,
@@ -68,11 +75,12 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
6875 [1 ] = extra ? & extra_sg : & in_sg ,
6976 [2 ] = extra ? & in_sg : NULL ,
7077 };
78+ struct um_pci_message_buffer * buf ;
7179 int delay_count = 0 ;
7280 int ret , len ;
7381 bool posted ;
7482
75- if (WARN_ON (cmd_size < sizeof (* cmd )))
83+ if (WARN_ON (cmd_size < sizeof (* cmd ) || cmd_size > sizeof ( * buf ) ))
7684 return - EINVAL ;
7785
7886 switch (cmd -> op ) {
@@ -88,6 +96,9 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
8896 break ;
8997 }
9098
99+ buf = get_cpu_var (um_pci_msg_bufs );
100+ memcpy (buf , cmd , cmd_size );
101+
91102 if (posted ) {
92103 u8 * ncmd = kmalloc (cmd_size + extra_size , GFP_ATOMIC );
93104
@@ -102,7 +113,10 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
102113 } else {
103114 /* try without allocating memory */
104115 posted = false;
116+ cmd = (void * )buf ;
105117 }
118+ } else {
119+ cmd = (void * )buf ;
106120 }
107121
108122 sg_init_one (& out_sg , cmd , cmd_size );
@@ -118,11 +132,12 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
118132 posted ? cmd : HANDLE_NO_FREE (cmd ),
119133 GFP_ATOMIC );
120134 if (ret )
121- return ret ;
135+ goto out ;
122136
123137 if (posted ) {
124138 virtqueue_kick (dev -> cmd_vq );
125- return 0 ;
139+ ret = 0 ;
140+ goto out ;
126141 }
127142
128143 /* 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,
148163 }
149164 clear_bit (UM_PCI_STAT_WAITING , & dev -> status );
150165
166+ out :
167+ put_cpu_var (um_pci_msg_bufs );
151168 return ret ;
152169}
153170
@@ -161,12 +178,17 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
161178 .size = size ,
162179 .addr = offset ,
163180 };
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 ;
166185
167186 if (!dev )
168187 return ~0ULL ;
169188
189+ buf = get_cpu_var (um_pci_msg_bufs );
190+ data = buf -> data ;
191+
170192 memset (data , 0xff , sizeof (data ));
171193
172194 switch (size ) {
@@ -179,27 +201,34 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
179201 break ;
180202 default :
181203 WARN (1 , "invalid config space read size %d\n" , size );
182- return ~ 0ULL ;
204+ goto out ;
183205 }
184206
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 ;
188209
189210 switch (size ) {
190211 case 1 :
191- return data [0 ];
212+ ret = data [0 ];
213+ break ;
192214 case 2 :
193- return le16_to_cpup ((void * )data );
215+ ret = le16_to_cpup ((void * )data );
216+ break ;
194217 case 4 :
195- return le32_to_cpup ((void * )data );
218+ ret = le32_to_cpup ((void * )data );
219+ break ;
196220#ifdef CONFIG_64BIT
197221 case 8 :
198- return le64_to_cpup ((void * )data );
222+ ret = le64_to_cpup ((void * )data );
223+ break ;
199224#endif
200225 default :
201- return ~ 0ULL ;
226+ break ;
202227 }
228+
229+ out :
230+ put_cpu_var (um_pci_msg_bufs );
231+ return ret ;
203232}
204233
205234static 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,
272301static unsigned long um_pci_bar_read (void * priv , unsigned int offset ,
273302 int size )
274303{
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 ;
277311
278312 switch (size ) {
279313 case 1 :
@@ -285,25 +319,33 @@ static unsigned long um_pci_bar_read(void *priv, unsigned int offset,
285319 break ;
286320 default :
287321 WARN (1 , "invalid config space read size %d\n" , size );
288- return ~ 0ULL ;
322+ goto out ;
289323 }
290324
291325 um_pci_bar_copy_from (priv , data , offset , size );
292326
293327 switch (size ) {
294328 case 1 :
295- return data [0 ];
329+ ret = data [0 ];
330+ break ;
296331 case 2 :
297- return le16_to_cpup ((void * )data );
332+ ret = le16_to_cpup ((void * )data );
333+ break ;
298334 case 4 :
299- return le32_to_cpup ((void * )data );
335+ ret = le32_to_cpup ((void * )data );
336+ break ;
300337#ifdef CONFIG_64BIT
301338 case 8 :
302- return le64_to_cpup ((void * )data );
339+ ret = le64_to_cpup ((void * )data );
340+ break ;
303341#endif
304342 default :
305- return ~ 0ULL ;
343+ break ;
306344 }
345+
346+ out :
347+ put_cpu_var (um_pci_msg_bufs );
348+ return ret ;
307349}
308350
309351static void um_pci_bar_copy_to (void * priv , unsigned int offset ,
@@ -810,7 +852,7 @@ void *pci_root_bus_fwnode(struct pci_bus *bus)
810852 return um_pci_fwnode ;
811853}
812854
813- int um_pci_init (void )
855+ static int um_pci_init (void )
814856{
815857 int err , i ;
816858
@@ -823,10 +865,16 @@ int um_pci_init(void)
823865 "No virtio device ID configured for PCI - no PCI support\n" ))
824866 return 0 ;
825867
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 )
828870 return - ENOMEM ;
829871
872+ bridge = pci_alloc_host_bridge (0 );
873+ if (!bridge ) {
874+ err = - ENOMEM ;
875+ goto free ;
876+ }
877+
830878 um_pci_fwnode = irq_domain_alloc_named_fwnode ("um-pci" );
831879 if (!um_pci_fwnode ) {
832880 err = - ENOMEM ;
@@ -878,18 +926,22 @@ int um_pci_init(void)
878926 irq_domain_remove (um_pci_inner_domain );
879927 if (um_pci_fwnode )
880928 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 );
883934 return err ;
884935}
885936module_init (um_pci_init );
886937
887- void um_pci_exit (void )
938+ static void um_pci_exit (void )
888939{
889940 unregister_virtio_driver (& um_pci_virtio_driver );
890941 irq_domain_remove (um_pci_msi_domain );
891942 irq_domain_remove (um_pci_inner_domain );
892943 pci_free_resource_list (& bridge -> windows );
893944 pci_free_host_bridge (bridge );
945+ free_percpu (um_pci_msg_bufs );
894946}
895947module_exit (um_pci_exit );
0 commit comments