@@ -2230,14 +2230,8 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
22302230#define MIN_MTU ETH_MIN_MTU
22312231#define MAX_MTU ETH_MAX_MTU
22322232
2233- static int virtnet_probe (struct virtio_device * vdev )
2233+ static int virtnet_validate (struct virtio_device * vdev )
22342234{
2235- int i , err ;
2236- struct net_device * dev ;
2237- struct virtnet_info * vi ;
2238- u16 max_queue_pairs ;
2239- int mtu ;
2240-
22412235 if (!vdev -> config -> get ) {
22422236 dev_err (& vdev -> dev , "%s failure: config access disabled\n" ,
22432237 __func__ );
@@ -2247,6 +2241,25 @@ static int virtnet_probe(struct virtio_device *vdev)
22472241 if (!virtnet_validate_features (vdev ))
22482242 return - EINVAL ;
22492243
2244+ if (virtio_has_feature (vdev , VIRTIO_NET_F_MTU )) {
2245+ int mtu = virtio_cread16 (vdev ,
2246+ offsetof(struct virtio_net_config ,
2247+ mtu ));
2248+ if (mtu < MIN_MTU )
2249+ __virtio_clear_bit (vdev , VIRTIO_NET_F_MTU );
2250+ }
2251+
2252+ return 0 ;
2253+ }
2254+
2255+ static int virtnet_probe (struct virtio_device * vdev )
2256+ {
2257+ int i , err ;
2258+ struct net_device * dev ;
2259+ struct virtnet_info * vi ;
2260+ u16 max_queue_pairs ;
2261+ int mtu ;
2262+
22502263 /* Find if host supports multiqueue virtio_net device */
22512264 err = virtio_cread_feature (vdev , VIRTIO_NET_F_MQ ,
22522265 struct virtio_net_config ,
@@ -2362,12 +2375,17 @@ static int virtnet_probe(struct virtio_device *vdev)
23622375 offsetof(struct virtio_net_config ,
23632376 mtu ));
23642377 if (mtu < dev -> min_mtu ) {
2365- __virtio_clear_bit (vdev , VIRTIO_NET_F_MTU );
2366- } else {
2367- dev -> mtu = mtu ;
2368- dev -> max_mtu = mtu ;
2378+ /* Should never trigger: MTU was previously validated
2379+ * in virtnet_validate.
2380+ */
2381+ dev_err (& vdev -> dev , "device MTU appears to have changed "
2382+ "it is now %d < %d" , mtu , dev -> min_mtu );
2383+ goto free_stats ;
23692384 }
23702385
2386+ dev -> mtu = mtu ;
2387+ dev -> max_mtu = mtu ;
2388+
23712389 /* TODO: size buffers correctly in this case. */
23722390 if (dev -> mtu > ETH_DATA_LEN )
23732391 vi -> big_packets = true;
@@ -2548,6 +2566,7 @@ static struct virtio_driver virtio_net_driver = {
25482566 .driver .name = KBUILD_MODNAME ,
25492567 .driver .owner = THIS_MODULE ,
25502568 .id_table = id_table ,
2569+ .validate = virtnet_validate ,
25512570 .probe = virtnet_probe ,
25522571 .remove = virtnet_remove ,
25532572 .config_changed = virtnet_config_changed ,
0 commit comments