@@ -57,6 +57,11 @@ DECLARE_EWMA(pkt_len, 0, 64)
57
57
58
58
#define VIRTNET_DRIVER_VERSION "1.0.0"
59
59
60
+ const unsigned long guest_offloads [] = { VIRTIO_NET_F_GUEST_TSO4 ,
61
+ VIRTIO_NET_F_GUEST_TSO6 ,
62
+ VIRTIO_NET_F_GUEST_ECN ,
63
+ VIRTIO_NET_F_GUEST_UFO };
64
+
60
65
struct virtnet_stats {
61
66
struct u64_stats_sync tx_syncp ;
62
67
struct u64_stats_sync rx_syncp ;
@@ -164,10 +169,13 @@ struct virtnet_info {
164
169
u8 ctrl_promisc ;
165
170
u8 ctrl_allmulti ;
166
171
u16 ctrl_vid ;
172
+ u64 ctrl_offloads ;
167
173
168
174
/* Ethtool settings */
169
175
u8 duplex ;
170
176
u32 speed ;
177
+
178
+ unsigned long guest_offloads ;
171
179
};
172
180
173
181
struct padded_vnet_hdr {
@@ -1897,6 +1905,47 @@ static int virtnet_restore_up(struct virtio_device *vdev)
1897
1905
return err ;
1898
1906
}
1899
1907
1908
+ static int virtnet_set_guest_offloads (struct virtnet_info * vi , u64 offloads )
1909
+ {
1910
+ struct scatterlist sg ;
1911
+ vi -> ctrl_offloads = cpu_to_virtio64 (vi -> vdev , offloads );
1912
+
1913
+ sg_init_one (& sg , & vi -> ctrl_offloads , sizeof (vi -> ctrl_offloads ));
1914
+
1915
+ if (!virtnet_send_command (vi , VIRTIO_NET_CTRL_GUEST_OFFLOADS ,
1916
+ VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET , & sg )) {
1917
+ dev_warn (& vi -> dev -> dev , "Fail to set guest offload. \n" );
1918
+ return - EINVAL ;
1919
+ }
1920
+
1921
+ return 0 ;
1922
+ }
1923
+
1924
+ static int virtnet_clear_guest_offloads (struct virtnet_info * vi )
1925
+ {
1926
+ u64 offloads = 0 ;
1927
+
1928
+ if (!vi -> guest_offloads )
1929
+ return 0 ;
1930
+
1931
+ if (virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_CSUM ))
1932
+ offloads = 1ULL << VIRTIO_NET_F_GUEST_CSUM ;
1933
+
1934
+ return virtnet_set_guest_offloads (vi , offloads );
1935
+ }
1936
+
1937
+ static int virtnet_restore_guest_offloads (struct virtnet_info * vi )
1938
+ {
1939
+ u64 offloads = vi -> guest_offloads ;
1940
+
1941
+ if (!vi -> guest_offloads )
1942
+ return 0 ;
1943
+ if (virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_CSUM ))
1944
+ offloads |= 1ULL << VIRTIO_NET_F_GUEST_CSUM ;
1945
+
1946
+ return virtnet_set_guest_offloads (vi , offloads );
1947
+ }
1948
+
1900
1949
static int virtnet_xdp_set (struct net_device * dev , struct bpf_prog * prog ,
1901
1950
struct netlink_ext_ack * extack )
1902
1951
{
@@ -1906,10 +1955,11 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
1906
1955
u16 xdp_qp = 0 , curr_qp ;
1907
1956
int i , err ;
1908
1957
1909
- if (virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_TSO4 ) ||
1910
- virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_TSO6 ) ||
1911
- virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_ECN ) ||
1912
- virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_UFO )) {
1958
+ if (!virtio_has_feature (vi -> vdev , VIRTIO_NET_F_CTRL_GUEST_OFFLOADS )
1959
+ && (virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_TSO4 ) ||
1960
+ virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_TSO6 ) ||
1961
+ virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_ECN ) ||
1962
+ virtio_has_feature (vi -> vdev , VIRTIO_NET_F_GUEST_UFO ))) {
1913
1963
NL_SET_ERR_MSG_MOD (extack , "Can't set XDP while host is implementing LRO, disable LRO first" );
1914
1964
return - EOPNOTSUPP ;
1915
1965
}
@@ -1956,6 +2006,12 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
1956
2006
for (i = 0 ; i < vi -> max_queue_pairs ; i ++ ) {
1957
2007
old_prog = rtnl_dereference (vi -> rq [i ].xdp_prog );
1958
2008
rcu_assign_pointer (vi -> rq [i ].xdp_prog , prog );
2009
+ if (i == 0 ) {
2010
+ if (!old_prog )
2011
+ virtnet_clear_guest_offloads (vi );
2012
+ if (!prog )
2013
+ virtnet_restore_guest_offloads (vi );
2014
+ }
1959
2015
if (old_prog )
1960
2016
bpf_prog_put (old_prog );
1961
2017
virtnet_napi_enable (vi -> rq [i ].vq , & vi -> rq [i ].napi );
@@ -2591,6 +2647,10 @@ static int virtnet_probe(struct virtio_device *vdev)
2591
2647
netif_carrier_on (dev );
2592
2648
}
2593
2649
2650
+ for (i = 0 ; i < ARRAY_SIZE (guest_offloads ); i ++ )
2651
+ if (virtio_has_feature (vi -> vdev , guest_offloads [i ]))
2652
+ set_bit (guest_offloads [i ], & vi -> guest_offloads );
2653
+
2594
2654
pr_debug ("virtnet: registered device %s with %d RX and TX vq's\n" ,
2595
2655
dev -> name , max_queue_pairs );
2596
2656
@@ -2687,7 +2747,7 @@ static struct virtio_device_id id_table[] = {
2687
2747
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
2688
2748
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
2689
2749
VIRTIO_NET_F_CTRL_MAC_ADDR, \
2690
- VIRTIO_NET_F_MTU
2750
+ VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
2691
2751
2692
2752
static unsigned int features [] = {
2693
2753
VIRTNET_FEATURES ,
0 commit comments