From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LVCpX-00015i-PM for qemu-devel@nongnu.org; Thu, 05 Feb 2009 17:36:19 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LVCpW-00013X-Ds for qemu-devel@nongnu.org; Thu, 05 Feb 2009 17:36:19 -0500 Received: from [199.232.76.173] (port=44148 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LVCpV-00012x-S7 for qemu-devel@nongnu.org; Thu, 05 Feb 2009 17:36:17 -0500 Received: from savannah.gnu.org ([199.232.41.3]:56505 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LVCpV-0005qM-Fl for qemu-devel@nongnu.org; Thu, 05 Feb 2009 17:36:17 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1LVCpU-0000S5-Gx for qemu-devel@nongnu.org; Thu, 05 Feb 2009 22:36:16 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1LVCpU-0000S1-Bw for qemu-devel@nongnu.org; Thu, 05 Feb 2009 22:36:16 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Thu, 05 Feb 2009 22:36:16 +0000 Subject: [Qemu-devel] [6536] qemu:virtio-net: Add a virtqueue for control commands from the guest (Alex Williamson) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 6536 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6536 Author: aliguori Date: 2009-02-05 22:36:16 +0000 (Thu, 05 Feb 2009) Log Message: ----------- qemu:virtio-net: Add a virtqueue for control commands from the guest (Alex Williamson) This will be used for RX mode, MAC table, VLAN table control, etc... The control transaction consists of one or more "out" sg entries and one or more "in" sg entries. The first out entry contains a header defining the class and command. Additional out entries may provide data for the command. A response via the ack entry is required and the guest will typically be waiting for it. Signed-off-by: Alex Williamson Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/hw/virtio-net.c trunk/hw/virtio-net.h Modified: trunk/hw/virtio-net.c =================================================================== --- trunk/hw/virtio-net.c 2009-02-05 22:36:12 UTC (rev 6535) +++ trunk/hw/virtio-net.c 2009-02-05 22:36:16 UTC (rev 6536) @@ -25,6 +25,7 @@ uint16_t status; VirtQueue *rx_vq; VirtQueue *tx_vq; + VirtQueue *ctrl_vq; VLANClientState *vc; QEMUTimer *tx_timer; int tx_timer_active; @@ -79,7 +80,9 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev) { - uint32_t features = (1 << VIRTIO_NET_F_MAC) | (1 << VIRTIO_NET_F_STATUS); + uint32_t features = (1 << VIRTIO_NET_F_MAC) | + (1 << VIRTIO_NET_F_STATUS) | + (1 << VIRTIO_NET_F_CTRL_VQ); return features; } @@ -91,6 +94,34 @@ n->mergeable_rx_bufs = !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)); } +static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) +{ + struct virtio_net_ctrl_hdr ctrl; + virtio_net_ctrl_ack status = VIRTIO_NET_ERR; + VirtQueueElement elem; + + while (virtqueue_pop(vq, &elem)) { + if ((elem.in_num < 1) || (elem.out_num < 1)) { + fprintf(stderr, "virtio-net ctrl missing headers\n"); + exit(1); + } + + if (elem.out_sg[0].iov_len < sizeof(ctrl) || + elem.out_sg[elem.in_num - 1].iov_len < sizeof(status)) { + fprintf(stderr, "virtio-net ctrl header not in correct element\n"); + exit(1); + } + + ctrl.class = ldub_p(elem.out_sg[0].iov_base); + ctrl.cmd = ldub_p(elem.out_sg[0].iov_base + sizeof(ctrl.class)); + + stb_p(elem.in_sg[elem.in_num - 1].iov_base, status); + + virtqueue_push(vq, &elem, sizeof(status)); + virtio_notify(vdev, vq); + } +} + /* RX */ static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq) @@ -356,6 +387,7 @@ n->vdev.set_features = virtio_net_set_features; n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx); + n->ctrl_vq = virtio_add_queue(&n->vdev, 16, virtio_net_handle_ctrl); memcpy(n->mac, nd->macaddr, ETH_ALEN); n->status = VIRTIO_NET_S_LINK_UP; n->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, Modified: trunk/hw/virtio-net.h =================================================================== --- trunk/hw/virtio-net.h 2009-02-05 22:36:12 UTC (rev 6535) +++ trunk/hw/virtio-net.h 2009-02-05 22:36:16 UTC (rev 6536) @@ -40,6 +40,7 @@ #define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ #define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ #define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */ +#define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ @@ -84,4 +85,21 @@ void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn); +/* + * Control virtqueue data structures + * + * The control virtqueue expects a header in the first sg entry + * and an ack/status response in the last entry. Data for the + * command goes in between. + */ +struct virtio_net_ctrl_hdr { + uint8_t class; + uint8_t cmd; +}; + +typedef uint8_t virtio_net_ctrl_ack; + +#define VIRTIO_NET_OK 0 +#define VIRTIO_NET_ERR 1 + #endif