From a06b1dae4706fccb9394b35e88d1905dabec85e7 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Tue, 27 Sep 2016 15:43:37 +0200 Subject: virtio-serial: enable virtio console emergency write feature Add support for enabling the virtio 1.0 "emergency write" (VIRTIO_CONSOLE_F_EMERG_WRITE) feature. The previous patch introduced the plumbing required for this; now we expose the virtio feature to the guest. The feature is disabled for compatibility machines to avoid exposing a new feature to existing guests. As required by the virtio 1.0 spec, the emergency write functionality is available to the guest even if the guest doesn't negotatiate the feature, as well as before feature negotation. Reviewed-by: Cornelia Huck Signed-off-by: Sascha Silbe Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/compat.h | 4 ++++ include/hw/virtio/virtio-serial.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'include') diff --git a/include/hw/compat.h b/include/hw/compat.h index 46412b2..ef3fae3 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -7,6 +7,10 @@ .property = "page-per-vq",\ .value = "on",\ },{\ + .driver = "virtio-serial-device",\ + .property = "emergency-write",\ + .value = "off",\ + },{\ .driver = "ioapic",\ .property = "version",\ .value = "0x11",\ diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index 730c88d..b19c447 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -184,6 +184,8 @@ struct VirtIOSerial { struct VirtIOSerialPostLoad *post_load; virtio_serial_conf serial; + + uint64_t host_features; }; /* Interface to the virtio-serial bus */ -- cgit v1.1 From 6bea1ddf8b411dcb0ba5d3a83c4479492185a409 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 5 Oct 2016 17:51:23 +0200 Subject: numa: reduce code duplication by adding helper numa_get_node_for_cpu() Replace repeated pattern for (i = 0; i < nb_numa_nodes; i++) { if (test_bit(idx, numa_info[i].node_cpu)) { ... break; with a helper function to lookup numa node index for cpu. Suggested-by: Michael S. Tsirkin Signed-off-by: Igor Mammedov Reviewed-by: David Gibson Reviewed-by: Shannon Zhao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/sysemu/numa.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h index bb184c9..4da808a 100644 --- a/include/sysemu/numa.h +++ b/include/sysemu/numa.h @@ -32,4 +32,7 @@ void numa_set_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node); void numa_unset_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node); uint32_t numa_get_node(ram_addr_t addr, Error **errp); +/* on success returns node index in numa_info, + * on failure returns nb_numa_nodes */ +int numa_get_node_for_cpu(int idx); #endif -- cgit v1.1 From 2640d2a5ff08978d67bd87518d05d6b499488c9a Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Mon, 19 Sep 2016 14:28:03 +0100 Subject: virtio: add virtio_detach_element() During device reset or similar situations a VirtQueueElement needs to be freed without pushing it onto the used ring or rewinding the virtqueue. Extract a new function to do this. Later patches add virtio_detach_element() calls to existing device so that scatter-gather lists are unmapped and vq->inuse goes back to zero during device reset. Currently some devices don't bother and simply call g_free(elem) which is not a clean way to throw away a VirtQueueElement. Signed-off-by: Stefan Hajnoczi Acked-by: Greg Kurz Reviewed-by: Ladi Prosek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 888c8de..e25ec4f 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -155,6 +155,8 @@ void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num); void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len); void virtqueue_flush(VirtQueue *vq, unsigned int count); +void virtqueue_detach_element(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len); void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len); bool virtqueue_rewind(VirtQueue *vq, unsigned int num); -- cgit v1.1 From d14dde5ec7a38df2e00a6f1b58e96ba38359dbb0 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 30 Sep 2016 17:12:50 +0200 Subject: virtio-blk: make some functions static Some functions that were called from the dataplane code are now only used locally: virtio_blk_init_request() virtio_blk_handle_request() virtio_blk_submit_multireq() since commit "03de2f527499 virtio-blk: do not use vring in dataplane", and virtio_blk_free_request() since commit "6aa46d8ff1ee virtio: move VirtQueueElement at the beginning of the structs". This patch converts them to static. Signed-off-by: Greg Kurz Reviewed-by: Stefan Hajnoczi Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio-blk.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 180bd8d..9734b4c 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -80,14 +80,6 @@ typedef struct MultiReqBuffer { bool is_write; } MultiReqBuffer; -void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq, - VirtIOBlockReq *req); -void virtio_blk_free_request(VirtIOBlockReq *req); - -void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb); - -void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb); - void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq); #endif -- cgit v1.1 From 0a73336d96397c80881219d080518fac6f1ecacb Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 7 Oct 2016 13:18:34 +0100 Subject: net: don't poke at chardev internal QemuOpts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vhost-user & colo code is poking at the QemuOpts instance in the CharDriverState struct, not realizing that it is valid for this to be NULL. e.g. the following crash shows a codepath where it will be NULL: Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000055baf6ab4adc in qemu_opt_foreach (opts=0x0, func=0x55baf696b650 , opaque=0x7ffc51368c00, errp=0x7ffc51368e48) at util/qemu-option.c:617 617 QTAILQ_FOREACH(opt, &opts->head, next) { [Current thread is 1 (Thread 0x7f1d4970bb40 (LWP 6603))] (gdb) bt #0 0x000055baf6ab4adc in qemu_opt_foreach (opts=0x0, func=0x55baf696b650 , opaque=0x7ffc51368c00, errp=0x7ffc51368e48) at util/qemu-option.c:617 #1 0x000055baf696b7da in net_vhost_parse_chardev (opts=0x55baf8ff9260, errp=0x7ffc51368e48) at net/vhost-user.c:314 #2 0x000055baf696b985 in net_init_vhost_user (netdev=0x55baf8ff9250, name=0x55baf879d270 "hostnet2", peer=0x0, errp=0x7ffc51368e48) at net/vhost-user.c:360 #3 0x000055baf6960216 in net_client_init1 (object=0x55baf8ff9250, is_netdev=true, errp=0x7ffc51368e48) at net/net.c:1051 #4 0x000055baf6960518 in net_client_init (opts=0x55baf776e7e0, is_netdev=true, errp=0x7ffc51368f00) at net/net.c:1108 #5 0x000055baf696083f in netdev_add (opts=0x55baf776e7e0, errp=0x7ffc51368f00) at net/net.c:1186 #6 0x000055baf69608c7 in qmp_netdev_add (qdict=0x55baf7afaf60, ret=0x7ffc51368f50, errp=0x7ffc51368f48) at net/net.c:1205 #7 0x000055baf6622135 in handle_qmp_command (parser=0x55baf77fb590, tokens=0x7f1d24011960) at /path/to/qemu.git/monitor.c:3978 #8 0x000055baf6a9d099 in json_message_process_token (lexer=0x55baf77fb598, input=0x55baf75acd20, type=JSON_RCURLY, x=113, y=19) at qobject/json-streamer.c:105 #9 0x000055baf6abf7aa in json_lexer_feed_char (lexer=0x55baf77fb598, ch=125 '}', flush=false) at qobject/json-lexer.c:319 #10 0x000055baf6abf8f2 in json_lexer_feed (lexer=0x55baf77fb598, buffer=0x7ffc51369170 "}R\204\367\272U", size=1) at qobject/json-lexer.c:369 #11 0x000055baf6a9d13c in json_message_parser_feed (parser=0x55baf77fb590, buffer=0x7ffc51369170 "}R\204\367\272U", size=1) at qobject/json-streamer.c:124 #12 0x000055baf66221f7 in monitor_qmp_read (opaque=0x55baf77fb530, buf=0x7ffc51369170 "}R\204\367\272U", size=1) at /path/to/qemu.git/monitor.c:3994 #13 0x000055baf6757014 in qemu_chr_be_write_impl (s=0x55baf7610a40, buf=0x7ffc51369170 "}R\204\367\272U", len=1) at qemu-char.c:387 #14 0x000055baf6757076 in qemu_chr_be_write (s=0x55baf7610a40, buf=0x7ffc51369170 "}R\204\367\272U", len=1) at qemu-char.c:399 #15 0x000055baf675b3b0 in tcp_chr_read (chan=0x55baf90244b0, cond=G_IO_IN, opaque=0x55baf7610a40) at qemu-char.c:2927 #16 0x000055baf6a5d655 in qio_channel_fd_source_dispatch (source=0x55baf7610df0, callback=0x55baf675b25a , user_data=0x55baf7610a40) at io/channel-watch.c:84 #17 0x00007f1d3e80cbbd in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0 #18 0x000055baf69d3720 in glib_pollfds_poll () at main-loop.c:213 #19 0x000055baf69d37fd in os_host_main_loop_wait (timeout=126000000) at main-loop.c:258 #20 0x000055baf69d38ad in main_loop_wait (nonblocking=0) at main-loop.c:506 #21 0x000055baf676587b in main_loop () at vl.c:1908 #22 0x000055baf676d3bf in main (argc=101, argv=0x7ffc5136a6c8, envp=0x7ffc5136a9f8) at vl.c:4604 (gdb) p opts $1 = (QemuOpts *) 0x0 The crash occurred when attaching vhost-user net via QMP: { "execute": "chardev-add", "arguments": { "id": "charnet2", "backend": { "type": "socket", "data": { "addr": { "type": "unix", "data": { "path": "/var/run/openvswitch/vhost-user1" } }, "wait": false, "server": false } } }, "id": "libvirt-19" } { "return": { }, "id": "libvirt-19" } { "execute": "netdev_add", "arguments": { "type": "vhost-user", "chardev": "charnet2", "id": "hostnet2" }, "id": "libvirt-20" } Code using chardevs should not be poking at the internals of the CharDriverState struct. What vhost-user wants is a chardev that is operating as reconnectable network service, along with the ability to do FD passing over the connection. The colo code simply wants a network service. Add a feature concept to the char drivers so that chardev users can query the actual features they wish to have supported. The QemuOpts member is removed to prevent future mistakes in this area. Signed-off-by: Daniel P. Berrange Reviewed-by: Marc-André Lureau Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/sysemu/char.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 0d0465a..19dad3f 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -9,6 +9,7 @@ #include "qapi/qmp/qobject.h" #include "qapi/qmp/qstring.h" #include "qemu/main-loop.h" +#include "qemu/bitmap.h" /* character device */ @@ -58,6 +59,20 @@ struct ParallelIOArg { typedef void IOEventHandler(void *opaque, int event); +typedef enum { + /* Whether the chardev peer is able to close and + * reopen the data channel, thus requiring support + * for qemu_chr_wait_connected() to wait for a + * valid connection */ + QEMU_CHAR_FEATURE_RECONNECTABLE, + /* Whether it is possible to send/recv file descriptors + * over the data channel */ + QEMU_CHAR_FEATURE_FD_PASS, + + QEMU_CHAR_FEATURE_LAST, +} CharDriverFeature; + + struct CharDriverState { QemuMutex chr_write_lock; void (*init)(struct CharDriverState *s); @@ -93,8 +108,8 @@ struct CharDriverState { int avail_connections; int is_mux; guint fd_in_tag; - QemuOpts *opts; bool replay; + DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); QTAILQ_ENTRY(CharDriverState) next; }; @@ -437,6 +452,10 @@ int qemu_chr_add_client(CharDriverState *s, int fd); CharDriverState *qemu_chr_find(const char *name); bool chr_is_ringbuf(const CharDriverState *chr); +bool qemu_chr_has_feature(CharDriverState *chr, + CharDriverFeature feature); +void qemu_chr_set_feature(CharDriverState *chr, + CharDriverFeature feature); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); void register_char_driver(const char *name, ChardevBackendKind kind, -- cgit v1.1 From 1a665855d7144bb3df382630a2b5e4039e95e466 Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Thu, 6 Oct 2016 14:55:39 +0200 Subject: virtio: prepare change VMSTATE_VIRTIO_DEVICE macro In most cases the functions passed to VMSTATE_VIRTIO_DEVICE only call the virtio_load and virtio_save wrappers. Some include some pre- and post- massaging too. The massaging is better expressed as such in the VMStateDescription. Let us prepare for changing the semantic of the VMSTATE_VIRTIO_DEVICE macro so that it is more similar to the other VMSTATE_*_DEVICE macros in a sense that it is a field definition. The preprocessor conditionals are going to be removed as soon as every usage is converted to the new semantic. Signed-off-by: Halil Pasic Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include') diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index e25ec4f..929fa92 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -179,6 +179,20 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); void virtio_save(VirtIODevice *vdev, QEMUFile *f); void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size); +extern const VMStateInfo virtio_vmstate_info; + +#ifdef VMSTATE_VIRTIO_DEVICE_USE_NEW + +#define VMSTATE_VIRTIO_DEVICE \ + { \ + .name = "virtio", \ + .info = &virtio_vmstate_info, \ + .flags = VMS_SINGLE, \ + } + +#else +/* TODO remove conditional as soon as all users are converted */ + #define VMSTATE_VIRTIO_DEVICE(devname, v, getf, putf) \ static const VMStateDescription vmstate_virtio_ ## devname = { \ .name = "virtio-" #devname , \ @@ -198,6 +212,8 @@ void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size); } \ } +#endif + int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id); void virtio_notify_config(VirtIODevice *vdev); -- cgit v1.1 From 5705653ff8666ffb247971361904f902aa033351 Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Thu, 6 Oct 2016 14:55:50 +0200 Subject: virtio: cleanup VMSTATE_VIRTIO_DEVICE Now all the usages of the old version of VMSTATE_VIRTIO_DEVICE are gone, so we can get rid of the conditionals, and the old macro. Signed-off-by: Halil Pasic Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio.h | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 929fa92..b913aac 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -177,12 +177,9 @@ bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq); void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); void virtio_save(VirtIODevice *vdev, QEMUFile *f); -void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size); extern const VMStateInfo virtio_vmstate_info; -#ifdef VMSTATE_VIRTIO_DEVICE_USE_NEW - #define VMSTATE_VIRTIO_DEVICE \ { \ .name = "virtio", \ @@ -190,30 +187,6 @@ extern const VMStateInfo virtio_vmstate_info; .flags = VMS_SINGLE, \ } -#else -/* TODO remove conditional as soon as all users are converted */ - -#define VMSTATE_VIRTIO_DEVICE(devname, v, getf, putf) \ - static const VMStateDescription vmstate_virtio_ ## devname = { \ - .name = "virtio-" #devname , \ - .minimum_version_id = v, \ - .version_id = v, \ - .fields = (VMStateField[]) { \ - { \ - .name = "virtio", \ - .info = &(const VMStateInfo) {\ - .name = "virtio", \ - .get = getf, \ - .put = putf, \ - }, \ - .flags = VMS_SINGLE, \ - }, \ - VMSTATE_END_OF_LIST() \ - } \ - } - -#endif - int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id); void virtio_notify_config(VirtIODevice *vdev); -- cgit v1.1