diff options
author | Sasha Levin <sasha.levin@oracle.com> | 2013-05-03 16:29:13 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2015-06-01 16:39:54 +0100 |
commit | 8c0ae74dd37b6cfef929ba468e6d11e5b749ead0 (patch) | |
tree | e1eb38b68b8a16c85bb7c85b06c2ee0dfba960a7 | |
parent | 04b53c1615e8dc2bded7a445ef7e9abae6f92afc (diff) | |
download | kvmtool-8c0ae74dd37b6cfef929ba468e6d11e5b749ead0.tar.gz |
kvm tools: init network devices only when the virtio driver is ready to go
We may need to know what features are supported before we can init the
network on the host side.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r-- | virtio/net.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/virtio/net.c b/virtio/net.c index bef00392..2dbca09a 100644 --- a/virtio/net.c +++ b/virtio/net.c @@ -58,6 +58,8 @@ struct net_dev { struct uip_info info; struct net_dev_operations *ops; struct kvm *kvm; + + struct virtio_net_params *params; }; static LIST_HEAD(ndevs); @@ -207,13 +209,13 @@ static void virtio_net_handle_callback(struct kvm *kvm, struct net_dev *ndev, in mutex_unlock(&ndev->io_lock[queue]); } -static bool virtio_net__tap_init(const struct virtio_net_params *params, - struct net_dev *ndev) +static bool virtio_net__tap_init(struct net_dev *ndev) { int sock = socket(AF_INET, SOCK_STREAM, 0); int pid, status, offload, hdr_len; struct sockaddr_in sin = {0}; struct ifreq ifr; + const struct virtio_net_params *params = ndev->params; /* Did the user already gave us the FD? */ if (params->fd) { @@ -496,6 +498,8 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } +static void notify_status(struct kvm *kvm, void *dev, u8 status); + static struct virtio_ops net_dev_virtio_ops = (struct virtio_ops) { .get_config = get_config, .get_host_features = get_host_features, @@ -507,6 +511,7 @@ static struct virtio_ops net_dev_virtio_ops = (struct virtio_ops) { .notify_vq = notify_vq, .notify_vq_gsi = notify_vq_gsi, .notify_vq_eventfd = notify_vq_eventfd, + .notify_status = notify_status, }; static void virtio_net__vhost_init(struct kvm *kvm, struct net_dev *ndev) @@ -652,6 +657,7 @@ static int virtio_net__init_one(struct virtio_net_params *params) list_add_tail(&ndev->list, &ndevs); ndev->kvm = params->kvm; + ndev->params = params; mutex_init(&ndev->mutex); ndev->queue_pairs = max(1, min(VIRTIO_NET_NUM_QUEUES, params->mq)); @@ -667,8 +673,6 @@ static int virtio_net__init_one(struct virtio_net_params *params) ndev->mode = params->mode; if (ndev->mode == NET_MODE_TAP) { - if (!virtio_net__tap_init(params, ndev)) - die_perror("You have requested a TAP device, but creation of one has failed because"); ndev->ops = &tap_ops; } else { ndev->info.host_ip = ntohl(inet_addr(params->host_ip)); @@ -676,7 +680,6 @@ static int virtio_net__init_one(struct virtio_net_params *params) ndev->info.guest_netmask = ntohl(inet_addr("255.255.255.0")); ndev->info.buf_nr = 20, ndev->info.vnet_hdr_len = sizeof(struct virtio_net_hdr); - uip_init(&ndev->info); ndev->ops = &uip_ops; } @@ -696,6 +699,21 @@ static int virtio_net__init_one(struct virtio_net_params *params) return 0; } +static void notify_status(struct kvm *kvm, void *dev, u8 status) +{ + struct net_dev *ndev = dev; + + if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) + return; + + if (ndev->mode == NET_MODE_TAP) { + if (!virtio_net__tap_init(ndev)) + die_perror("You have requested a TAP device, but creation of one has failed because"); + } else { + uip_init(&ndev->info); + } +} + int virtio_net__init(struct kvm *kvm) { int i; @@ -706,7 +724,7 @@ int virtio_net__init(struct kvm *kvm) } if (kvm->cfg.num_net_devices == 0 && kvm->cfg.no_net == 0) { - struct virtio_net_params net_params; + static struct virtio_net_params net_params; net_params = (struct virtio_net_params) { .guest_ip = kvm->cfg.guest_ip, |