qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* SCSI max_transfer support for scsi-generic (Eric)
* x86 SMI broadcast (Laszlo)
* Character device QOMification (Marc-André)
* Record/replay improvements (Pavel)
* iscsi fixes (Peter L.)
* "info mtree -f" command (Peter Xu)
* TSC clock rate reporting (Phil)
* DEVICE_CATEGORY_CPU (Thomas)
* Memory sign-extension fix (Ladi)

# gpg: Signature made Fri 27 Jan 2017 17:08:51 GMT
# gpg: using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (41 commits)
memory: don't sign-extend 32-bit writes
chardev: qom-ify
vc: use a common prefix for chr callbacks
baum: use a common prefix for chr callbacks
gtk: overwrite the console.c char driver
char: use error_report()
spice-char: improve error reporting
char: rename TCPChardev and NetChardev
char: rename CharDriverState Chardev
bt: use qemu_chr_alloc()
char: allocate CharDriverState as a single object
char: use a feature bit for replay
char: introduce generic qemu_chr_get_kind()
char: fold single-user functions in caller
char: move callbacks in CharDriver
char: use a static array for backends
char: use a const CharDriver
doc: fix spelling
char: add qemu_chr_fe_add_watch() Returns description
qemu-options: stdio is available on win32
...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+2192 -1448
+1
MAINTAINERS
··· 1642 1642 L: qemu-block@nongnu.org 1643 1643 S: Supported 1644 1644 F: block/iscsi.c 1645 + F: block/iscsi-opts.c 1645 1646 1646 1647 NFS 1647 1648 M: Jeff Cody <jcody@redhat.com>
+53 -49
backends/baum.c
··· 85 85 #define BUF_SIZE 256 86 86 87 87 typedef struct { 88 - CharDriverState *chr; 88 + Chardev parent; 89 89 90 90 brlapi_handle_t *brlapi; 91 91 int brlapi_fd; ··· 98 98 uint8_t out_buf_used, out_buf_ptr; 99 99 100 100 QEMUTimer *cellCount_timer; 101 - } BaumDriverState; 101 + } BaumChardev; 102 + 103 + #define TYPE_CHARDEV_BRAILLE "chardev-braille" 104 + #define BAUM_CHARDEV(obj) OBJECT_CHECK(BaumChardev, (obj), TYPE_CHARDEV_BRAILLE) 102 105 103 106 /* Let's assume NABCC by default */ 104 107 enum way { ··· 223 226 }; 224 227 225 228 /* The guest OS has started discussing with us, finish initializing BrlAPI */ 226 - static int baum_deferred_init(BaumDriverState *baum) 229 + static int baum_deferred_init(BaumChardev *baum) 227 230 { 228 231 int tty = BRLAPI_TTY_DEFAULT; 229 232 QemuConsole *con; ··· 253 256 } 254 257 255 258 /* The serial port can receive more of our data */ 256 - static void baum_accept_input(struct CharDriverState *chr) 259 + static void baum_chr_accept_input(struct Chardev *chr) 257 260 { 258 - BaumDriverState *baum = chr->opaque; 261 + BaumChardev *baum = BAUM_CHARDEV(chr); 259 262 int room, first; 260 263 261 264 if (!baum->out_buf_used) ··· 279 282 } 280 283 281 284 /* We want to send a packet */ 282 - static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len) 285 + static void baum_write_packet(BaumChardev *baum, const uint8_t *buf, int len) 283 286 { 287 + Chardev *chr = CHARDEV(baum); 284 288 uint8_t io_buf[1 + 2 * len], *cur = io_buf; 285 289 int room; 286 290 *cur++ = ESC; 287 291 while (len--) 288 292 if ((*cur++ = *buf++) == ESC) 289 293 *cur++ = ESC; 290 - room = qemu_chr_be_can_write(baum->chr); 294 + room = qemu_chr_be_can_write(chr); 291 295 len = cur - io_buf; 292 296 if (len <= room) { 293 297 /* Fits */ 294 - qemu_chr_be_write(baum->chr, io_buf, len); 298 + qemu_chr_be_write(chr, io_buf, len); 295 299 } else { 296 300 int first; 297 301 uint8_t out; 298 302 /* Can't fit all, send what can be, and store the rest. */ 299 - qemu_chr_be_write(baum->chr, io_buf, room); 303 + qemu_chr_be_write(chr, io_buf, room); 300 304 len -= room; 301 305 cur = io_buf + room; 302 306 if (len > BUF_SIZE - baum->out_buf_used) { ··· 321 325 /* Called when the other end seems to have a wrong idea of our display size */ 322 326 static void baum_cellCount_timer_cb(void *opaque) 323 327 { 324 - BaumDriverState *baum = opaque; 328 + BaumChardev *baum = BAUM_CHARDEV(opaque); 325 329 uint8_t cell_count[] = { BAUM_RSP_CellCount, baum->x * baum->y }; 326 330 DPRINTF("Timeout waiting for DisplayData, sending cell count\n"); 327 331 baum_write_packet(baum, cell_count, sizeof(cell_count)); 328 332 } 329 333 330 334 /* Try to interpret a whole incoming packet */ 331 - static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len) 335 + static int baum_eat_packet(BaumChardev *baum, const uint8_t *buf, int len) 332 336 { 333 337 const uint8_t *cur = buf; 334 338 uint8_t req = 0; ··· 469 473 } 470 474 471 475 /* The other end is writing some data. Store it and try to interpret */ 472 - static int baum_write(CharDriverState *chr, const uint8_t *buf, int len) 476 + static int baum_chr_write(Chardev *chr, const uint8_t *buf, int len) 473 477 { 474 - BaumDriverState *baum = chr->opaque; 478 + BaumChardev *baum = BAUM_CHARDEV(chr); 475 479 int tocopy, cur, eaten, orig_len = len; 476 480 477 481 if (!len) ··· 510 514 } 511 515 512 516 /* Send the key code to the other end */ 513 - static void baum_send_key(BaumDriverState *baum, uint8_t type, uint8_t value) { 517 + static void baum_send_key(BaumChardev *baum, uint8_t type, uint8_t value) 518 + { 514 519 uint8_t packet[] = { type, value }; 515 520 DPRINTF("writing key %x %x\n", type, value); 516 521 baum_write_packet(baum, packet, sizeof(packet)); 517 522 } 518 523 519 - static void baum_send_key2(BaumDriverState *baum, uint8_t type, uint8_t value, 520 - uint8_t value2) { 524 + static void baum_send_key2(BaumChardev *baum, uint8_t type, uint8_t value, 525 + uint8_t value2) 526 + { 521 527 uint8_t packet[] = { type, value, value2 }; 522 528 DPRINTF("writing key %x %x\n", type, value); 523 529 baum_write_packet(baum, packet, sizeof(packet)); ··· 526 532 /* We got some data on the BrlAPI socket */ 527 533 static void baum_chr_read(void *opaque) 528 534 { 529 - BaumDriverState *baum = opaque; 535 + BaumChardev *baum = BAUM_CHARDEV(opaque); 530 536 brlapi_keyCode_t code; 531 537 int ret; 532 538 if (!baum->brlapi) ··· 610 616 } 611 617 } 612 618 613 - static void baum_free(struct CharDriverState *chr) 619 + static void baum_chr_free(Chardev *chr) 614 620 { 615 - BaumDriverState *baum = chr->opaque; 621 + BaumChardev *baum = BAUM_CHARDEV(chr); 616 622 617 623 timer_free(baum->cellCount_timer); 618 624 if (baum->brlapi) { 619 625 brlapi__closeConnection(baum->brlapi); 620 626 g_free(baum->brlapi); 621 627 } 622 - g_free(baum); 623 628 } 624 629 625 - static CharDriverState *chr_baum_init(const char *id, 626 - ChardevBackend *backend, 627 - ChardevReturn *ret, 628 - bool *be_opened, 629 - Error **errp) 630 + static void baum_chr_open(Chardev *chr, 631 + ChardevBackend *backend, 632 + bool *be_opened, 633 + Error **errp) 630 634 { 631 - ChardevCommon *common = backend->u.braille.data; 632 - BaumDriverState *baum; 633 - CharDriverState *chr; 635 + BaumChardev *baum = BAUM_CHARDEV(chr); 634 636 brlapi_handle_t *handle; 635 637 636 - chr = qemu_chr_alloc(common, errp); 637 - if (!chr) { 638 - return NULL; 639 - } 640 - baum = g_malloc0(sizeof(BaumDriverState)); 641 - baum->chr = chr; 642 - 643 - chr->opaque = baum; 644 - chr->chr_write = baum_write; 645 - chr->chr_accept_input = baum_accept_input; 646 - chr->chr_free = baum_free; 647 - 648 638 handle = g_malloc0(brlapi_getHandleSize()); 649 639 baum->brlapi = handle; 650 640 ··· 652 642 if (baum->brlapi_fd == -1) { 653 643 error_setg(errp, "brlapi__openConnection: %s", 654 644 brlapi_strerror(brlapi_error_location())); 655 - goto fail_handle; 645 + g_free(handle); 646 + return; 656 647 } 657 648 baum->deferred_init = 0; 658 649 659 650 baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum); 660 651 661 652 qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum); 653 + } 662 654 663 - return chr; 655 + static void char_braille_class_init(ObjectClass *oc, void *data) 656 + { 657 + ChardevClass *cc = CHARDEV_CLASS(oc); 664 658 665 - fail_handle: 666 - g_free(handle); 667 - g_free(chr); 668 - g_free(baum); 669 - return NULL; 659 + cc->open = baum_chr_open; 660 + cc->chr_write = baum_chr_write; 661 + cc->chr_accept_input = baum_chr_accept_input; 662 + cc->chr_free = baum_chr_free; 670 663 } 671 664 665 + static const TypeInfo char_braille_type_info = { 666 + .name = TYPE_CHARDEV_BRAILLE, 667 + .parent = TYPE_CHARDEV, 668 + .instance_size = sizeof(BaumChardev), 669 + .class_init = char_braille_class_init, 670 + }; 671 + 672 672 static void register_types(void) 673 673 { 674 - register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL, 675 - chr_baum_init); 674 + static const CharDriver driver = { 675 + .kind = CHARDEV_BACKEND_KIND_BRAILLE, 676 + }; 677 + 678 + register_char_driver(&driver); 679 + type_register_static(&char_braille_type_info); 676 680 } 677 681 678 682 type_init(register_types);
+43 -34
backends/msmouse.c
··· 31 31 #define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6) 32 32 33 33 typedef struct { 34 - CharDriverState *chr; 34 + Chardev parent; 35 + 35 36 QemuInputHandlerState *hs; 36 37 int axis[INPUT_AXIS__MAX]; 37 38 bool btns[INPUT_BUTTON__MAX]; 38 39 bool btnc[INPUT_BUTTON__MAX]; 39 40 uint8_t outbuf[32]; 40 41 int outlen; 41 - } MouseState; 42 + } MouseChardev; 42 43 43 - static void msmouse_chr_accept_input(CharDriverState *chr) 44 + #define TYPE_CHARDEV_MSMOUSE "chardev-msmouse" 45 + #define MOUSE_CHARDEV(obj) \ 46 + OBJECT_CHECK(MouseChardev, (obj), TYPE_CHARDEV_MSMOUSE) 47 + 48 + static void msmouse_chr_accept_input(Chardev *chr) 44 49 { 45 - MouseState *mouse = chr->opaque; 50 + MouseChardev *mouse = MOUSE_CHARDEV(chr); 46 51 int len; 47 52 48 53 len = qemu_chr_be_can_write(chr); ··· 60 65 } 61 66 } 62 67 63 - static void msmouse_queue_event(MouseState *mouse) 68 + static void msmouse_queue_event(MouseChardev *mouse) 64 69 { 65 70 unsigned char bytes[4] = { 0x40, 0x00, 0x00, 0x00 }; 66 71 int dx, dy, count = 3; ··· 97 102 static void msmouse_input_event(DeviceState *dev, QemuConsole *src, 98 103 InputEvent *evt) 99 104 { 100 - MouseState *mouse = (MouseState *)dev; 105 + MouseChardev *mouse = MOUSE_CHARDEV(dev); 101 106 InputMoveEvent *move; 102 107 InputBtnEvent *btn; 103 108 ··· 121 126 122 127 static void msmouse_input_sync(DeviceState *dev) 123 128 { 124 - MouseState *mouse = (MouseState *)dev; 129 + MouseChardev *mouse = MOUSE_CHARDEV(dev); 130 + Chardev *chr = CHARDEV(dev); 125 131 126 132 msmouse_queue_event(mouse); 127 - msmouse_chr_accept_input(mouse->chr); 133 + msmouse_chr_accept_input(chr); 128 134 } 129 135 130 - static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len) 136 + static int msmouse_chr_write(struct Chardev *s, const uint8_t *buf, int len) 131 137 { 132 138 /* Ignore writes to mouse port */ 133 139 return len; 134 140 } 135 141 136 - static void msmouse_chr_free(struct CharDriverState *chr) 142 + static void msmouse_chr_free(struct Chardev *chr) 137 143 { 138 - MouseState *mouse = chr->opaque; 144 + MouseChardev *mouse = MOUSE_CHARDEV(chr); 139 145 140 146 qemu_input_handler_unregister(mouse->hs); 141 - g_free(mouse); 142 147 } 143 148 144 149 static QemuInputHandler msmouse_handler = { ··· 148 153 .sync = msmouse_input_sync, 149 154 }; 150 155 151 - static CharDriverState *qemu_chr_open_msmouse(const char *id, 152 - ChardevBackend *backend, 153 - ChardevReturn *ret, 154 - bool *be_opened, 155 - Error **errp) 156 + static void msmouse_chr_open(Chardev *chr, 157 + ChardevBackend *backend, 158 + bool *be_opened, 159 + Error **errp) 156 160 { 157 - ChardevCommon *common = backend->u.msmouse.data; 158 - MouseState *mouse; 159 - CharDriverState *chr; 161 + MouseChardev *mouse = MOUSE_CHARDEV(chr); 160 162 161 - chr = qemu_chr_alloc(common, errp); 162 - if (!chr) { 163 - return NULL; 164 - } 165 - chr->chr_write = msmouse_chr_write; 166 - chr->chr_free = msmouse_chr_free; 167 - chr->chr_accept_input = msmouse_chr_accept_input; 168 163 *be_opened = false; 169 - 170 - mouse = g_new0(MouseState, 1); 171 164 mouse->hs = qemu_input_handler_register((DeviceState *)mouse, 172 165 &msmouse_handler); 166 + } 173 167 174 - mouse->chr = chr; 175 - chr->opaque = mouse; 168 + static void char_msmouse_class_init(ObjectClass *oc, void *data) 169 + { 170 + ChardevClass *cc = CHARDEV_CLASS(oc); 176 171 177 - return chr; 172 + cc->open = msmouse_chr_open; 173 + cc->chr_write = msmouse_chr_write; 174 + cc->chr_accept_input = msmouse_chr_accept_input; 175 + cc->chr_free = msmouse_chr_free; 178 176 } 179 177 178 + static const TypeInfo char_msmouse_type_info = { 179 + .name = TYPE_CHARDEV_MSMOUSE, 180 + .parent = TYPE_CHARDEV, 181 + .instance_size = sizeof(MouseChardev), 182 + .class_init = char_msmouse_class_init, 183 + }; 184 + 180 185 static void register_types(void) 181 186 { 182 - register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL, 183 - qemu_chr_open_msmouse); 187 + static const CharDriver driver = { 188 + .kind = CHARDEV_BACKEND_KIND_MSMOUSE, 189 + }; 190 + 191 + register_char_driver(&driver); 192 + type_register_static(&char_msmouse_type_info); 184 193 } 185 194 186 195 type_init(register_types);
+2 -2
backends/rng-egd.c
··· 86 86 static void rng_egd_opened(RngBackend *b, Error **errp) 87 87 { 88 88 RngEgd *s = RNG_EGD(b); 89 - CharDriverState *chr; 89 + Chardev *chr; 90 90 91 91 if (s->chr_name == NULL) { 92 92 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ··· 125 125 static char *rng_egd_get_chardev(Object *obj, Error **errp) 126 126 { 127 127 RngEgd *s = RNG_EGD(obj); 128 - CharDriverState *chr = qemu_chr_fe_get_driver(&s->chr); 128 + Chardev *chr = qemu_chr_fe_get_driver(&s->chr); 129 129 130 130 if (chr && chr->label) { 131 131 return g_strdup(chr->label);
+25 -28
backends/testdev.c
··· 30 30 #define BUF_SIZE 32 31 31 32 32 typedef struct { 33 - CharDriverState *chr; 33 + Chardev parent; 34 + 34 35 uint8_t in_buf[32]; 35 36 int in_buf_used; 36 - } TestdevCharState; 37 + } TestdevChardev; 38 + 39 + #define TYPE_CHARDEV_TESTDEV "chardev-testdev" 40 + #define TESTDEV_CHARDEV(obj) \ 41 + OBJECT_CHECK(TestdevChardev, (obj), TYPE_CHARDEV_TESTDEV) 37 42 38 43 /* Try to interpret a whole incoming packet */ 39 - static int testdev_eat_packet(TestdevCharState *testdev) 44 + static int testdev_eat_packet(TestdevChardev *testdev) 40 45 { 41 46 const uint8_t *cur = testdev->in_buf; 42 47 int len = testdev->in_buf_used; ··· 77 82 } 78 83 79 84 /* The other end is writing some data. Store it and try to interpret */ 80 - static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len) 85 + static int testdev_chr_write(Chardev *chr, const uint8_t *buf, int len) 81 86 { 82 - TestdevCharState *testdev = chr->opaque; 87 + TestdevChardev *testdev = TESTDEV_CHARDEV(chr); 83 88 int tocopy, eaten, orig_len = len; 84 89 85 90 while (len) { ··· 102 107 return orig_len; 103 108 } 104 109 105 - static void testdev_free(struct CharDriverState *chr) 110 + static void char_testdev_class_init(ObjectClass *oc, void *data) 106 111 { 107 - TestdevCharState *testdev = chr->opaque; 112 + ChardevClass *cc = CHARDEV_CLASS(oc); 108 113 109 - g_free(testdev); 114 + cc->chr_write = testdev_chr_write; 110 115 } 111 116 112 - static CharDriverState *chr_testdev_init(const char *id, 113 - ChardevBackend *backend, 114 - ChardevReturn *ret, 115 - bool *be_opened, 116 - Error **errp) 117 - { 118 - TestdevCharState *testdev; 119 - CharDriverState *chr; 120 - 121 - testdev = g_new0(TestdevCharState, 1); 122 - testdev->chr = chr = g_new0(CharDriverState, 1); 123 - 124 - chr->opaque = testdev; 125 - chr->chr_write = testdev_write; 126 - chr->chr_free = testdev_free; 127 - 128 - return chr; 129 - } 117 + static const TypeInfo char_testdev_type_info = { 118 + .name = TYPE_CHARDEV_TESTDEV, 119 + .parent = TYPE_CHARDEV, 120 + .instance_size = sizeof(TestdevChardev), 121 + .class_init = char_testdev_class_init, 122 + }; 130 123 131 124 static void register_types(void) 132 125 { 133 - register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL, 134 - chr_testdev_init); 126 + static const CharDriver driver = { 127 + .kind = CHARDEV_BACKEND_KIND_TESTDEV, 128 + }; 129 + 130 + register_char_driver(&driver); 131 + type_register_static(&char_testdev_type_info); 135 132 } 136 133 137 134 type_init(register_types);
+1
block/Makefile.objs
··· 14 14 15 15 block-obj-y += nbd.o nbd-client.o sheepdog.o 16 16 block-obj-$(CONFIG_LIBISCSI) += iscsi.o 17 + block-obj-$(if $(CONFIG_LIBISCSI),y,n) += iscsi-opts.o 17 18 block-obj-$(CONFIG_LIBNFS) += nfs.o 18 19 block-obj-$(CONFIG_CURL) += curl.o 19 20 block-obj-$(CONFIG_RBD) += rbd.o
+11 -8
block/file-posix.c
··· 651 651 state->opaque = NULL; 652 652 } 653 653 654 - static int hdev_get_max_transfer_length(int fd) 654 + static int hdev_get_max_transfer_length(BlockDriverState *bs, int fd) 655 655 { 656 656 #ifdef BLKSECTGET 657 - int max_sectors = 0; 658 - if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) { 659 - return max_sectors; 657 + int max_bytes = 0; 658 + short max_sectors = 0; 659 + if (bs->sg && ioctl(fd, BLKSECTGET, &max_bytes) == 0) { 660 + return max_bytes; 661 + } else if (!bs->sg && ioctl(fd, BLKSECTGET, &max_sectors) == 0) { 662 + return max_sectors << BDRV_SECTOR_BITS; 660 663 } else { 661 664 return -errno; 662 665 } ··· 671 674 struct stat st; 672 675 673 676 if (!fstat(s->fd, &st)) { 674 - if (S_ISBLK(st.st_mode)) { 675 - int ret = hdev_get_max_transfer_length(s->fd); 676 - if (ret > 0 && ret <= BDRV_REQUEST_MAX_SECTORS) { 677 - bs->bl.max_transfer = pow2floor(ret << BDRV_SECTOR_BITS); 677 + if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) { 678 + int ret = hdev_get_max_transfer_length(bs, s->fd); 679 + if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) { 680 + bs->bl.max_transfer = pow2floor(ret); 678 681 } 679 682 } 680 683 }
+69
block/iscsi-opts.c
··· 1 + /* 2 + * QEMU Block driver for iSCSI images (static options) 3 + * 4 + * Copyright (c) 2017 Peter Lieven <pl@kamp.de> 5 + * 6 + * Permission is hereby granted, free of charge, to any person obtaining a copy 7 + * of this software and associated documentation files (the "Software"), to deal 8 + * in the Software without restriction, including without limitation the rights 9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 + * copies of the Software, and to permit persons to whom the Software is 11 + * furnished to do so, subject to the following conditions: 12 + * 13 + * The above copyright notice and this permission notice shall be included in 14 + * all copies or substantial portions of the Software. 15 + * 16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 + * THE SOFTWARE. 23 + */ 24 + 25 + #include "qemu/osdep.h" 26 + #include "qemu-common.h" 27 + #include "qemu/config-file.h" 28 + 29 + static QemuOptsList qemu_iscsi_opts = { 30 + .name = "iscsi", 31 + .head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head), 32 + .desc = { 33 + { 34 + .name = "user", 35 + .type = QEMU_OPT_STRING, 36 + .help = "username for CHAP authentication to target", 37 + },{ 38 + .name = "password", 39 + .type = QEMU_OPT_STRING, 40 + .help = "password for CHAP authentication to target", 41 + },{ 42 + .name = "password-secret", 43 + .type = QEMU_OPT_STRING, 44 + .help = "ID of the secret providing password for CHAP " 45 + "authentication to target", 46 + },{ 47 + .name = "header-digest", 48 + .type = QEMU_OPT_STRING, 49 + .help = "HeaderDigest setting. " 50 + "{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}", 51 + },{ 52 + .name = "initiator-name", 53 + .type = QEMU_OPT_STRING, 54 + .help = "Initiator iqn name to use when connecting", 55 + },{ 56 + .name = "timeout", 57 + .type = QEMU_OPT_NUMBER, 58 + .help = "Request timeout in seconds (default 0 = no timeout)", 59 + }, 60 + { /* end of list */ } 61 + }, 62 + }; 63 + 64 + static void iscsi_block_opts_init(void) 65 + { 66 + qemu_add_opts(&qemu_iscsi_opts); 67 + } 68 + 69 + block_init(iscsi_block_opts_init);
+6 -2
block/iscsi.c
··· 499 499 if (allocated) { 500 500 bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded); 501 501 } else { 502 - bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk); 502 + if (nb_cls_shrunk > 0) { 503 + bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk); 504 + } 503 505 } 504 506 505 507 if (iscsilun->allocmap_valid == NULL) { 506 508 return; 507 509 } 508 510 if (valid) { 509 - bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk); 511 + if (nb_cls_shrunk > 0) { 512 + bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk); 513 + } 510 514 } else { 511 515 bitmap_clear(iscsilun->allocmap_valid, cl_num_expanded, 512 516 nb_cls_expanded);
+1 -1
cpu-exec.c
··· 508 508 True when it is, and we should restart on a new TB, 509 509 and via longjmp via cpu_loop_exit. */ 510 510 else { 511 - replay_interrupt(); 512 511 if (cc->cpu_exec_interrupt(cpu, interrupt_request)) { 512 + replay_interrupt(); 513 513 *last_tb = NULL; 514 514 } 515 515 /* The target hook may have updated the 'cpu->interrupt_request';
+16
docs/replay.txt
··· 196 196 events read from the log. Therefore block devices requests are processed 197 197 deterministically. 198 198 199 + Snapshotting 200 + ------------ 201 + 202 + New VM snapshots may be created in replay mode. They can be used later 203 + to recover the desired VM state. All VM states created in replay mode 204 + are associated with the moment of time in the replay scenario. 205 + After recovering the VM state replay will start from that position. 206 + 207 + Default starting snapshot name may be specified with icount field 208 + rrsnapshot as follows: 209 + -icount shift=7,rr=record,rrfile=replay.bin,rrsnapshot=snapshot_name 210 + 211 + This snapshot is created at start of recording and restored at start 212 + of replaying. It also can be loaded while replaying to roll back 213 + the execution. 214 + 199 215 Network devices 200 216 --------------- 201 217
+1 -1
exec.c
··· 2630 2630 break; 2631 2631 case 4: 2632 2632 /* 32 bit write access */ 2633 - val = ldl_p(buf); 2633 + val = (uint32_t)ldl_p(buf); 2634 2634 result |= memory_region_dispatch_write(mr, addr1, val, 4, 2635 2635 attrs); 2636 2636 break;
+37 -8
gdbstub.c
··· 305 305 int running_state; 306 306 #else 307 307 CharBackend chr; 308 - CharDriverState *mon_chr; 308 + Chardev *mon_chr; 309 309 #endif 310 310 char syscall_buf[256]; 311 311 gdb_syscall_complete_cb current_syscall_cb; ··· 1473 1473 GDBState *s; 1474 1474 char buf[4]; 1475 1475 #ifndef CONFIG_USER_ONLY 1476 - CharDriverState *chr; 1476 + Chardev *chr; 1477 1477 #endif 1478 1478 1479 1479 s = gdbserver_state; ··· 1698 1698 put_packet(s, buf); 1699 1699 } 1700 1700 1701 - static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len) 1701 + static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len) 1702 1702 { 1703 1703 const char *p = (const char *)buf; 1704 1704 int max_sz; ··· 1725 1725 } 1726 1726 #endif 1727 1727 1728 + static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend, 1729 + bool *be_opened, Error **errp) 1730 + { 1731 + *be_opened = false; 1732 + } 1733 + 1734 + static void char_gdb_class_init(ObjectClass *oc, void *data) 1735 + { 1736 + ChardevClass *cc = CHARDEV_CLASS(oc); 1737 + 1738 + cc->internal = true; 1739 + cc->open = gdb_monitor_open; 1740 + cc->chr_write = gdb_monitor_write; 1741 + } 1742 + 1743 + #define TYPE_CHARDEV_GDB "chardev-gdb" 1744 + 1745 + static const TypeInfo char_gdb_type_info = { 1746 + .name = TYPE_CHARDEV_GDB, 1747 + .parent = TYPE_CHARDEV, 1748 + .class_init = char_gdb_class_init, 1749 + }; 1750 + 1728 1751 int gdbserver_start(const char *device) 1729 1752 { 1730 1753 GDBState *s; 1731 1754 char gdbstub_device_name[128]; 1732 - CharDriverState *chr = NULL; 1733 - CharDriverState *mon_chr; 1734 - ChardevCommon common = { 0 }; 1755 + Chardev *chr = NULL; 1756 + Chardev *mon_chr; 1735 1757 1736 1758 if (!first_cpu) { 1737 1759 error_report("gdbstub: meaningless to attach gdb to a " ··· 1770 1792 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL); 1771 1793 1772 1794 /* Initialize a monitor terminal for gdb */ 1773 - mon_chr = qemu_chr_alloc(&common, &error_abort); 1774 - mon_chr->chr_write = gdb_monitor_write; 1795 + mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB, 1796 + NULL, &error_abort); 1775 1797 monitor_init(mon_chr, 0); 1776 1798 } else { 1777 1799 if (qemu_chr_fe_get_driver(&s->chr)) { ··· 1794 1816 1795 1817 return 0; 1796 1818 } 1819 + 1820 + static void register_types(void) 1821 + { 1822 + type_register_static(&char_gdb_type_info); 1823 + } 1824 + 1825 + type_init(register_types); 1797 1826 #endif
+3 -3
hmp-commands-info.hx
··· 249 249 250 250 { 251 251 .name = "mtree", 252 - .args_type = "", 253 - .params = "", 254 - .help = "show memory tree", 252 + .args_type = "flatview:-f", 253 + .params = "[-f]", 254 + .help = "show memory tree (-f: dump flat view for address spaces)", 255 255 .cmd = hmp_info_mtree, 256 256 }, 257 257
+1 -1
hw/arm/fsl-imx25.c
··· 118 118 }; 119 119 120 120 if (i < MAX_SERIAL_PORTS) { 121 - CharDriverState *chr; 121 + Chardev *chr; 122 122 123 123 chr = serial_hds[i]; 124 124
+1 -1
hw/arm/fsl-imx31.c
··· 107 107 }; 108 108 109 109 if (i < MAX_SERIAL_PORTS) { 110 - CharDriverState *chr; 110 + Chardev *chr; 111 111 112 112 chr = serial_hds[i]; 113 113
+1 -1
hw/arm/fsl-imx6.c
··· 187 187 }; 188 188 189 189 if (i < MAX_SERIAL_PORTS) { 190 - CharDriverState *chr; 190 + Chardev *chr; 191 191 192 192 chr = serial_hds[i]; 193 193
+1 -1
hw/arm/nseries.c
··· 786 786 787 787 static void n8x0_uart_setup(struct n800_s *s) 788 788 { 789 - CharDriverState *radio = uart_hci_init(); 789 + Chardev *radio = uart_hci_init(); 790 790 791 791 qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO, 792 792 csrhci_pins_get(radio)[csrhci_pin_reset]);
+1 -1
hw/arm/omap2.c
··· 792 792 static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta, 793 793 MemoryRegion *sysmem, 794 794 hwaddr channel_base, qemu_irq irq, omap_clk clk, 795 - CharDriverState *chr) 795 + Chardev *chr) 796 796 { 797 797 struct omap_sti_s *s = g_new0(struct omap_sti_s, 1); 798 798
+1 -1
hw/arm/pxa2xx.c
··· 2024 2024 hwaddr base, 2025 2025 qemu_irq irq, qemu_irq rx_dma, 2026 2026 qemu_irq tx_dma, 2027 - CharDriverState *chr) 2027 + Chardev *chr) 2028 2028 { 2029 2029 DeviceState *dev; 2030 2030 SysBusDevice *sbd;
+1 -1
hw/arm/virt.c
··· 613 613 } 614 614 615 615 static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart, 616 - MemoryRegion *mem, CharDriverState *chr) 616 + MemoryRegion *mem, Chardev *chr) 617 617 { 618 618 char *nodename; 619 619 hwaddr base = vms->memmap[uart].base;
+48 -16
hw/bt/hci-csr.c
··· 26 26 #include "hw/irq.h" 27 27 #include "sysemu/bt.h" 28 28 #include "hw/bt.h" 29 + #include "qapi/error.h" 29 30 30 31 struct csrhci_s { 32 + Chardev parent; 31 33 int enable; 32 34 qemu_irq *pins; 33 35 int pin_state; 34 36 int modem_state; 35 - CharDriverState chr; 36 37 #define FIFO_LEN 4096 37 38 int out_start; 38 39 int out_len; ··· 54 55 struct HCIInfo *hci; 55 56 }; 56 57 58 + #define TYPE_CHARDEV_HCI "chardev-hci" 59 + #define HCI_CHARDEV(obj) OBJECT_CHECK(struct csrhci_s, (obj), TYPE_CHARDEV_HCI) 60 + 57 61 /* H4+ packet types */ 58 62 enum { 59 63 H4_CMD_PKT = 1, ··· 78 82 79 83 static inline void csrhci_fifo_wake(struct csrhci_s *s) 80 84 { 81 - CharBackend *be = s->chr.be; 85 + Chardev *chr = (Chardev *)s; 86 + CharBackend *be = chr->be; 82 87 83 88 if (!s->enable || !s->out_len) 84 89 return; ··· 311 316 s->in_hdr = INT_MAX; 312 317 } 313 318 314 - static int csrhci_write(struct CharDriverState *chr, 319 + static int csrhci_write(struct Chardev *chr, 315 320 const uint8_t *buf, int len) 316 321 { 317 - struct csrhci_s *s = (struct csrhci_s *) chr->opaque; 322 + struct csrhci_s *s = (struct csrhci_s *)chr; 318 323 int total = 0; 319 324 320 325 if (!s->enable) ··· 384 389 csrhci_fifo_wake(s); 385 390 } 386 391 387 - static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg) 392 + static int csrhci_ioctl(struct Chardev *chr, int cmd, void *arg) 388 393 { 389 394 QEMUSerialSetParams *ssp; 390 - struct csrhci_s *s = (struct csrhci_s *) chr->opaque; 395 + struct csrhci_s *s = (struct csrhci_s *) chr; 391 396 int prev_state = s->modem_state; 392 397 393 398 switch (cmd) { ··· 453 458 } 454 459 } 455 460 456 - qemu_irq *csrhci_pins_get(CharDriverState *chr) 461 + qemu_irq *csrhci_pins_get(Chardev *chr) 457 462 { 458 - struct csrhci_s *s = (struct csrhci_s *) chr->opaque; 463 + struct csrhci_s *s = (struct csrhci_s *) chr; 459 464 460 465 return s->pins; 461 466 } 462 467 463 - CharDriverState *uart_hci_init(void) 468 + static void csrhci_open(Chardev *chr, 469 + ChardevBackend *backend, 470 + bool *be_opened, 471 + Error **errp) 464 472 { 465 - struct csrhci_s *s = (struct csrhci_s *) 466 - g_malloc0(sizeof(struct csrhci_s)); 467 - 468 - s->chr.opaque = s; 469 - s->chr.chr_write = csrhci_write; 470 - s->chr.chr_ioctl = csrhci_ioctl; 473 + struct csrhci_s *s = HCI_CHARDEV(chr); 471 474 472 475 s->hci = qemu_next_hci(); 473 476 s->hci->opaque = s; ··· 477 480 s->out_tm = timer_new_ns(QEMU_CLOCK_VIRTUAL, csrhci_out_tick, s); 478 481 s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins); 479 482 csrhci_reset(s); 483 + *be_opened = false; 484 + } 480 485 481 - return &s->chr; 486 + static void char_hci_class_init(ObjectClass *oc, void *data) 487 + { 488 + ChardevClass *cc = CHARDEV_CLASS(oc); 489 + 490 + cc->internal = true; 491 + cc->open = csrhci_open; 492 + cc->chr_write = csrhci_write; 493 + cc->chr_ioctl = csrhci_ioctl; 482 494 } 495 + 496 + static const TypeInfo char_hci_type_info = { 497 + .name = TYPE_CHARDEV_HCI, 498 + .parent = TYPE_CHARDEV, 499 + .instance_size = sizeof(struct csrhci_s), 500 + .class_init = char_hci_class_init, 501 + }; 502 + 503 + Chardev *uart_hci_init(void) 504 + { 505 + return qemu_chardev_new(NULL, TYPE_CHARDEV_HCI, 506 + NULL, &error_abort); 507 + } 508 + 509 + static void register_types(void) 510 + { 511 + type_register_static(&char_hci_type_info); 512 + } 513 + 514 + type_init(register_types);
+1 -1
hw/char/escc.c
··· 689 689 }; 690 690 691 691 MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB, 692 - CharDriverState *chrA, CharDriverState *chrB, 692 + Chardev *chrA, Chardev *chrB, 693 693 int clock, int it_shift) 694 694 { 695 695 DeviceState *dev;
+1 -1
hw/char/exynos4210_uart.c
··· 582 582 DeviceState *exynos4210_uart_create(hwaddr addr, 583 583 int fifo_size, 584 584 int channel, 585 - CharDriverState *chr, 585 + Chardev *chr, 586 586 qemu_irq irq) 587 587 { 588 588 DeviceState *dev;
+1 -1
hw/char/imx_serial.c
··· 170 170 uint64_t value, unsigned size) 171 171 { 172 172 IMXSerialState *s = (IMXSerialState *)opaque; 173 - CharDriverState *chr = qemu_chr_fe_get_driver(&s->chr); 173 + Chardev *chr = qemu_chr_fe_get_driver(&s->chr); 174 174 unsigned char ch; 175 175 176 176 DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n",
+2 -2
hw/char/mcf_uart.c
··· 275 275 mcf_uart_push_byte(s, buf[0]); 276 276 } 277 277 278 - void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) 278 + void *mcf_uart_init(qemu_irq irq, Chardev *chr) 279 279 { 280 280 mcf_uart_state *s; 281 281 ··· 300 300 void mcf_uart_mm_init(MemoryRegion *sysmem, 301 301 hwaddr base, 302 302 qemu_irq irq, 303 - CharDriverState *chr) 303 + Chardev *chr) 304 304 { 305 305 mcf_uart_state *s; 306 306
+3 -3
hw/char/omap_uart.c
··· 54 54 struct omap_uart_s *omap_uart_init(hwaddr base, 55 55 qemu_irq irq, omap_clk fclk, omap_clk iclk, 56 56 qemu_irq txdma, qemu_irq rxdma, 57 - const char *label, CharDriverState *chr) 57 + const char *label, Chardev *chr) 58 58 { 59 59 struct omap_uart_s *s = g_new0(struct omap_uart_s, 1); 60 60 ··· 163 163 struct omap_target_agent_s *ta, 164 164 qemu_irq irq, omap_clk fclk, omap_clk iclk, 165 165 qemu_irq txdma, qemu_irq rxdma, 166 - const char *label, CharDriverState *chr) 166 + const char *label, Chardev *chr) 167 167 { 168 168 hwaddr base = omap_l4_attach(ta, 0, NULL); 169 169 struct omap_uart_s *s = omap_uart_init(base, irq, ··· 178 178 return s; 179 179 } 180 180 181 - void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr) 181 + void omap_uart_attach(struct omap_uart_s *s, Chardev *chr) 182 182 { 183 183 /* TODO: Should reuse or destroy current s->serial */ 184 184 s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq,
+1 -1
hw/char/parallel.c
··· 603 603 /* If fd is zero, it means that the parallel device uses the console */ 604 604 bool parallel_mm_init(MemoryRegion *address_space, 605 605 hwaddr base, int it_shift, qemu_irq irq, 606 - CharDriverState *chr) 606 + Chardev *chr) 607 607 { 608 608 ParallelState *s; 609 609
+1 -1
hw/char/serial-isa.c
··· 121 121 122 122 type_init(serial_register_types) 123 123 124 - static void serial_isa_init(ISABus *bus, int index, CharDriverState *chr) 124 + static void serial_isa_init(ISABus *bus, int index, Chardev *chr) 125 125 { 126 126 DeviceState *dev; 127 127 ISADevice *isadev;
+2 -2
hw/char/serial.c
··· 937 937 }; 938 938 939 939 SerialState *serial_init(int base, qemu_irq irq, int baudbase, 940 - CharDriverState *chr, MemoryRegion *system_io) 940 + Chardev *chr, MemoryRegion *system_io) 941 941 { 942 942 SerialState *s; 943 943 ··· 993 993 SerialState *serial_mm_init(MemoryRegion *address_space, 994 994 hwaddr base, int it_shift, 995 995 qemu_irq irq, int baudbase, 996 - CharDriverState *chr, enum device_endian end) 996 + Chardev *chr, enum device_endian end) 997 997 { 998 998 SerialState *s; 999 999
+1 -1
hw/char/sh_serial.c
··· 356 356 357 357 void sh_serial_init(MemoryRegion *sysmem, 358 358 hwaddr base, int feat, 359 - uint32_t freq, CharDriverState *chr, 359 + uint32_t freq, Chardev *chr, 360 360 qemu_irq eri_source, 361 361 qemu_irq rxi_source, 362 362 qemu_irq txi_source,
+1 -1
hw/char/spapr_vty.c
··· 141 141 return H_SUCCESS; 142 142 } 143 143 144 - void spapr_vty_create(VIOsPAPRBus *bus, CharDriverState *chardev) 144 + void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev) 145 145 { 146 146 DeviceState *dev; 147 147
+1 -1
hw/char/virtio-console.c
··· 168 168 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev); 169 169 VirtConsole *vcon = VIRTIO_CONSOLE(dev); 170 170 VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev); 171 - CharDriverState *chr = qemu_chr_fe_get_driver(&vcon->chr); 171 + Chardev *chr = qemu_chr_fe_get_driver(&vcon->chr); 172 172 173 173 if (port->id == 0 && !k->is_console) { 174 174 error_setg(errp, "Port number 0 on virtio-serial devices reserved "
+2 -2
hw/core/qdev-properties-system.c
··· 179 179 Error *local_err = NULL; 180 180 Property *prop = opaque; 181 181 CharBackend *be = qdev_get_prop_ptr(dev, prop); 182 - CharDriverState *s; 182 + Chardev *s; 183 183 char *str; 184 184 185 185 if (dev->realized) { ··· 411 411 } 412 412 413 413 void qdev_prop_set_chr(DeviceState *dev, const char *name, 414 - CharDriverState *value) 414 + Chardev *value) 415 415 { 416 416 assert(!value || value->label); 417 417 object_property_set_str(OBJECT(dev),
+8
hw/cpu/core.c
··· 72 72 core->nr_threads = smp_threads; 73 73 } 74 74 75 + static void cpu_core_class_init(ObjectClass *oc, void *data) 76 + { 77 + DeviceClass *dc = DEVICE_CLASS(oc); 78 + 79 + set_bit(DEVICE_CATEGORY_CPU, dc->categories); 80 + } 81 + 75 82 static const TypeInfo cpu_core_type_info = { 76 83 .name = TYPE_CPU_CORE, 77 84 .parent = TYPE_DEVICE, 78 85 .abstract = true, 86 + .class_init = cpu_core_class_init, 79 87 .instance_size = sizeof(CPUCore), 80 88 .instance_init = cpu_core_instance_init, 81 89 };
+1 -1
hw/display/milkymist-tmu2.c
··· 85 85 SysBusDevice parent_obj; 86 86 87 87 MemoryRegion regs_region; 88 - CharDriverState *chr; 88 + Chardev *chr; 89 89 qemu_irq irq; 90 90 91 91 uint32_t regs[R_MAX];
+1 -1
hw/display/sm501.c
··· 1392 1392 }; 1393 1393 1394 1394 void sm501_init(MemoryRegion *address_space_mem, uint32_t base, 1395 - uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr) 1395 + uint32_t local_mem_bytes, qemu_irq irq, Chardev *chr) 1396 1396 { 1397 1397 SM501State * s; 1398 1398 DeviceState *dev;
+6
hw/i386/kvmvapic.c
··· 413 413 if (!kvm_enabled()) { 414 414 cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base, 415 415 &current_flags); 416 + /* Account this instruction, because we will exit the tb. 417 + This is the first instruction in the block. Therefore 418 + there is no need in restoring CPU state. */ 419 + if (use_icount) { 420 + --cs->icount_decr.u16.low; 421 + } 416 422 } 417 423 418 424 pause_all_vcpus();
+33
hw/intc/apic_common.c
··· 385 385 return s->wait_for_sipi != 0; 386 386 } 387 387 388 + static bool apic_irq_delivered_needed(void *opaque) 389 + { 390 + APICCommonState *s = APIC_COMMON(opaque); 391 + return s->cpu == X86_CPU(first_cpu) && apic_irq_delivered != 0; 392 + } 393 + 394 + static void apic_irq_delivered_pre_save(void *opaque) 395 + { 396 + APICCommonState *s = APIC_COMMON(opaque); 397 + s->apic_irq_delivered = apic_irq_delivered; 398 + } 399 + 400 + static int apic_irq_delivered_post_load(void *opaque, int version_id) 401 + { 402 + APICCommonState *s = APIC_COMMON(opaque); 403 + apic_irq_delivered = s->apic_irq_delivered; 404 + return 0; 405 + } 406 + 388 407 static const VMStateDescription vmstate_apic_common_sipi = { 389 408 .name = "apic_sipi", 390 409 .version_id = 1, ··· 393 412 .fields = (VMStateField[]) { 394 413 VMSTATE_INT32(sipi_vector, APICCommonState), 395 414 VMSTATE_INT32(wait_for_sipi, APICCommonState), 415 + VMSTATE_END_OF_LIST() 416 + } 417 + }; 418 + 419 + static const VMStateDescription vmstate_apic_irq_delivered = { 420 + .name = "apic_irq_delivered", 421 + .version_id = 1, 422 + .minimum_version_id = 1, 423 + .needed = apic_irq_delivered_needed, 424 + .pre_save = apic_irq_delivered_pre_save, 425 + .post_load = apic_irq_delivered_post_load, 426 + .fields = (VMStateField[]) { 427 + VMSTATE_INT32(apic_irq_delivered, APICCommonState), 396 428 VMSTATE_END_OF_LIST() 397 429 } 398 430 }; ··· 431 463 }, 432 464 .subsections = (const VMStateDescription*[]) { 433 465 &vmstate_apic_common_sipi, 466 + &vmstate_apic_irq_delivered, 434 467 NULL 435 468 } 436 469 };
+1 -1
hw/isa/isa-bus.c
··· 288 288 289 289 type_init(isabus_register_types) 290 290 291 - static void parallel_init(ISABus *bus, int index, CharDriverState *chr) 291 + static void parallel_init(ISABus *bus, int index, Chardev *chr) 292 292 { 293 293 DeviceState *dev; 294 294 ISADevice *isadev;
+90 -1
hw/isa/lpc_ich9.c
··· 48 48 #include "exec/address-spaces.h" 49 49 #include "sysemu/sysemu.h" 50 50 #include "qom/cpu.h" 51 + #include "hw/nvram/fw_cfg.h" 52 + #include "qemu/cutils.h" 51 53 52 54 /*****************************************************************************/ 53 55 /* ICH9 LPC PCI to ISA bridge */ ··· 360 362 } 361 363 } 362 364 365 + static void smi_features_ok_callback(void *opaque) 366 + { 367 + ICH9LPCState *lpc = opaque; 368 + uint64_t guest_features; 369 + 370 + if (lpc->smi_features_ok) { 371 + /* negotiation already complete, features locked */ 372 + return; 373 + } 374 + 375 + memcpy(&guest_features, lpc->smi_guest_features_le, sizeof guest_features); 376 + le64_to_cpus(&guest_features); 377 + if (guest_features & ~lpc->smi_host_features) { 378 + /* guest requests invalid features, leave @features_ok at zero */ 379 + return; 380 + } 381 + 382 + /* valid feature subset requested, lock it down, report success */ 383 + lpc->smi_negotiated_features = guest_features; 384 + lpc->smi_features_ok = 1; 385 + } 386 + 363 387 void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled) 364 388 { 365 389 ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci); 366 390 qemu_irq sci_irq; 391 + FWCfgState *fw_cfg = fw_cfg_find(); 367 392 368 393 sci_irq = qemu_allocate_irq(ich9_set_sci, lpc, 0); 369 394 ich9_pm_init(lpc_pci, &lpc->pm, smm_enabled, sci_irq); 395 + 396 + if (lpc->smi_host_features && fw_cfg) { 397 + uint64_t host_features_le; 398 + 399 + host_features_le = cpu_to_le64(lpc->smi_host_features); 400 + memcpy(lpc->smi_host_features_le, &host_features_le, 401 + sizeof host_features_le); 402 + fw_cfg_add_file(fw_cfg, "etc/smi/supported-features", 403 + lpc->smi_host_features_le, 404 + sizeof lpc->smi_host_features_le); 405 + 406 + /* The other two guest-visible fields are cleared on device reset, we 407 + * just link them into fw_cfg here. 408 + */ 409 + fw_cfg_add_file_callback(fw_cfg, "etc/smi/requested-features", 410 + NULL, NULL, 411 + lpc->smi_guest_features_le, 412 + sizeof lpc->smi_guest_features_le, 413 + false); 414 + fw_cfg_add_file_callback(fw_cfg, "etc/smi/features-ok", 415 + smi_features_ok_callback, lpc, 416 + &lpc->smi_features_ok, 417 + sizeof lpc->smi_features_ok, 418 + true); 419 + } 420 + 370 421 ich9_lpc_reset(&lpc->d.qdev); 371 422 } 372 423 ··· 386 437 387 438 /* SMI_EN = PMBASE + 30. SMI control and enable register */ 388 439 if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) { 389 - cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI); 440 + if (lpc->smi_negotiated_features & 441 + (UINT64_C(1) << ICH9_LPC_SMI_F_BROADCAST_BIT)) { 442 + CPUState *cs; 443 + CPU_FOREACH(cs) { 444 + cpu_interrupt(cs, CPU_INTERRUPT_SMI); 445 + } 446 + } else { 447 + cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI); 448 + } 390 449 } 391 450 } 392 451 ··· 507 566 508 567 lpc->sci_level = 0; 509 568 lpc->rst_cnt = 0; 569 + 570 + memset(lpc->smi_guest_features_le, 0, sizeof lpc->smi_guest_features_le); 571 + lpc->smi_features_ok = 0; 572 + lpc->smi_negotiated_features = 0; 510 573 } 511 574 512 575 /* root complex register block is mapped into memory space */ ··· 668 731 } 669 732 }; 670 733 734 + static bool ich9_smi_feat_needed(void *opaque) 735 + { 736 + ICH9LPCState *lpc = opaque; 737 + 738 + return !buffer_is_zero(lpc->smi_guest_features_le, 739 + sizeof lpc->smi_guest_features_le) || 740 + lpc->smi_features_ok; 741 + } 742 + 743 + static const VMStateDescription vmstate_ich9_smi_feat = { 744 + .name = "ICH9LPC/smi_feat", 745 + .version_id = 1, 746 + .minimum_version_id = 1, 747 + .needed = ich9_smi_feat_needed, 748 + .fields = (VMStateField[]) { 749 + VMSTATE_UINT8_ARRAY(smi_guest_features_le, ICH9LPCState, 750 + sizeof(uint64_t)), 751 + VMSTATE_UINT8(smi_features_ok, ICH9LPCState), 752 + VMSTATE_UINT64(smi_negotiated_features, ICH9LPCState), 753 + VMSTATE_END_OF_LIST() 754 + } 755 + }; 756 + 671 757 static const VMStateDescription vmstate_ich9_lpc = { 672 758 .name = "ICH9LPC", 673 759 .version_id = 1, ··· 683 769 }, 684 770 .subsections = (const VMStateDescription*[]) { 685 771 &vmstate_ich9_rst_cnt, 772 + &vmstate_ich9_smi_feat, 686 773 NULL 687 774 } 688 775 }; 689 776 690 777 static Property ich9_lpc_properties[] = { 691 778 DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, true), 779 + DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features, 780 + ICH9_LPC_SMI_F_BROADCAST_BIT, true), 692 781 DEFINE_PROP_END_OF_LIST(), 693 782 }; 694 783
+1 -1
hw/isa/pc87312.c
··· 268 268 DeviceState *d; 269 269 ISADevice *isa; 270 270 ISABus *bus; 271 - CharDriverState *chr; 271 + Chardev *chr; 272 272 DriveInfo *drive; 273 273 char name[5]; 274 274 int i;
+2 -2
hw/lm32/lm32.h
··· 16 16 return dev; 17 17 } 18 18 19 - static inline DeviceState *lm32_juart_init(CharDriverState *chr) 19 + static inline DeviceState *lm32_juart_init(Chardev *chr) 20 20 { 21 21 DeviceState *dev; 22 22 ··· 29 29 30 30 static inline DeviceState *lm32_uart_create(hwaddr addr, 31 31 qemu_irq irq, 32 - CharDriverState *chr) 32 + Chardev *chr) 33 33 { 34 34 DeviceState *dev; 35 35 SysBusDevice *s;
+1 -1
hw/lm32/milkymist-hw.h
··· 6 6 7 7 static inline DeviceState *milkymist_uart_create(hwaddr base, 8 8 qemu_irq irq, 9 - CharDriverState *chr) 9 + Chardev *chr) 10 10 { 11 11 DeviceState *dev; 12 12
+2 -2
hw/mips/mips_malta.c
··· 551 551 } 552 552 553 553 static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space, 554 - hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr) 554 + hwaddr base, qemu_irq uart_irq, Chardev *uart_chr) 555 555 { 556 556 MaltaFPGAState *s; 557 - CharDriverState *chr; 557 + Chardev *chr; 558 558 559 559 s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState)); 560 560
+1 -1
hw/misc/ivshmem.c
··· 869 869 s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem, 870 870 &error_abort); 871 871 } else { 872 - CharDriverState *chr = qemu_chr_fe_get_driver(&s->server_chr); 872 + Chardev *chr = qemu_chr_fe_get_driver(&s->server_chr); 873 873 assert(chr); 874 874 875 875 IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n",
+1 -1
hw/misc/milkymist-pfpu.c
··· 125 125 SysBusDevice parent_obj; 126 126 127 127 MemoryRegion regs_region; 128 - CharDriverState *chr; 128 + Chardev *chr; 129 129 qemu_irq irq; 130 130 131 131 uint32_t regs[R_MAX];
+3 -2
hw/scsi/scsi-generic.c
··· 246 246 SCSIDevice *s = r->req.dev; 247 247 int ret; 248 248 249 - DPRINTF("scsi_read_data 0x%x\n", req->tag); 249 + DPRINTF("scsi_read_data tag=0x%x\n", req->tag); 250 250 251 251 /* The request is used as the AIO opaque value, so add a ref. */ 252 252 scsi_req_ref(&r->req); ··· 294 294 SCSIDevice *s = r->req.dev; 295 295 int ret; 296 296 297 - DPRINTF("scsi_write_data 0x%x\n", req->tag); 297 + DPRINTF("scsi_write_data tag=0x%x\n", req->tag); 298 298 if (r->len == 0) { 299 299 r->len = r->buflen; 300 300 scsi_req_data(&r->req, r->len); ··· 329 329 int ret; 330 330 331 331 #ifdef DEBUG_SCSI 332 + DPRINTF("Command: data=0x%02x", cmd[0]); 332 333 { 333 334 int i; 334 335 for (i = 1; i < r->req.cmd.len; i++) {
+11 -4
hw/timer/mc146818rtc.c
··· 27 27 #include "hw/hw.h" 28 28 #include "qemu/timer.h" 29 29 #include "sysemu/sysemu.h" 30 + #include "sysemu/replay.h" 30 31 #include "hw/timer/mc146818rtc.h" 31 32 #include "qapi/visitor.h" 32 33 #include "qapi-event.h" ··· 734 735 check_update_timer(s); 735 736 } 736 737 737 - uint64_t now = qemu_clock_get_ns(rtc_clock); 738 - if (now < s->next_periodic_time || 739 - now > (s->next_periodic_time + get_max_clock_jump())) { 740 - periodic_timer_update(s, qemu_clock_get_ns(rtc_clock)); 738 + /* The periodic timer is deterministic in record/replay mode, 739 + * so there is no need to update it after loading the vmstate. 740 + * Reading RTC here would misalign record and replay. 741 + */ 742 + if (replay_mode == REPLAY_MODE_NONE) { 743 + uint64_t now = qemu_clock_get_ns(rtc_clock); 744 + if (now < s->next_periodic_time || 745 + now > (s->next_periodic_time + get_max_clock_jump())) { 746 + periodic_timer_update(s, qemu_clock_get_ns(rtc_clock)); 747 + } 741 748 } 742 749 743 750 #ifdef TARGET_I386
+1 -1
hw/usb/ccid-card-passthru.c
··· 264 264 265 265 static void ccid_card_vscard_drop_connection(PassthruState *card) 266 266 { 267 - CharDriverState *chr = qemu_chr_fe_get_driver(&card->cs); 267 + Chardev *chr = qemu_chr_fe_get_driver(&card->cs); 268 268 269 269 qemu_chr_fe_deinit(&card->cs); 270 270 qemu_chr_delete(chr);
+3 -3
hw/usb/dev-serial.c
··· 483 483 { 484 484 USBSerialState *s = USB_SERIAL_DEV(dev); 485 485 Error *local_err = NULL; 486 - CharDriverState *chr = qemu_chr_fe_get_driver(&s->cs); 486 + Chardev *chr = qemu_chr_fe_get_driver(&s->cs); 487 487 488 488 usb_desc_create_serial(dev); 489 489 usb_desc_init(dev); ··· 512 512 static USBDevice *usb_serial_init(USBBus *bus, const char *filename) 513 513 { 514 514 USBDevice *dev; 515 - CharDriverState *cdrv; 515 + Chardev *cdrv; 516 516 uint32_t vendorid = 0, productid = 0; 517 517 char label[32]; 518 518 static int index; ··· 564 564 static USBDevice *usb_braille_init(USBBus *bus, const char *unused) 565 565 { 566 566 USBDevice *dev; 567 - CharDriverState *cdrv; 567 + Chardev *cdrv; 568 568 569 569 cdrv = qemu_chr_new("braille", "braille"); 570 570 if (!cdrv)
+2 -2
hw/usb/redirect.c
··· 284 284 static int usbredir_write(void *priv, uint8_t *data, int count) 285 285 { 286 286 USBRedirDevice *dev = priv; 287 - CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs); 287 + Chardev *chr = qemu_chr_fe_get_driver(&dev->cs); 288 288 int r; 289 289 290 290 if (!chr->be_open) { ··· 1430 1430 static void usbredir_handle_destroy(USBDevice *udev) 1431 1431 { 1432 1432 USBRedirDevice *dev = USB_REDIRECT(udev); 1433 - CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs); 1433 + Chardev *chr = qemu_chr_fe_get_driver(&dev->cs); 1434 1434 1435 1435 qemu_chr_fe_deinit(&dev->cs); 1436 1436 qemu_chr_delete(chr);
+1
include/block/block.h
··· 116 116 117 117 #define BDRV_REQUEST_MAX_SECTORS MIN(SIZE_MAX >> BDRV_SECTOR_BITS, \ 118 118 INT_MAX >> BDRV_SECTOR_BITS) 119 + #define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS) 119 120 120 121 /* 121 122 * Allocation status flags
+1 -1
include/exec/memory.h
··· 1250 1250 */ 1251 1251 void memory_global_dirty_log_stop(void); 1252 1252 1253 - void mtree_info(fprintf_function mon_printf, void *f); 1253 + void mtree_info(fprintf_function mon_printf, void *f, bool flatview); 1254 1254 1255 1255 /** 1256 1256 * memory_region_dispatch_read: perform a read directly to the specified
+1 -1
include/hw/arm/exynos4210.h
··· 131 131 DeviceState *exynos4210_uart_create(hwaddr addr, 132 132 int fifo_size, 133 133 int channel, 134 - CharDriverState *chr, 134 + Chardev *chr, 135 135 qemu_irq irq); 136 136 137 137 #endif /* EXYNOS4210_H */
+3 -3
include/hw/arm/omap.h
··· 664 664 struct omap_uart_s *omap_uart_init(hwaddr base, 665 665 qemu_irq irq, omap_clk fclk, omap_clk iclk, 666 666 qemu_irq txdma, qemu_irq rxdma, 667 - const char *label, CharDriverState *chr); 667 + const char *label, Chardev *chr); 668 668 struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem, 669 669 struct omap_target_agent_s *ta, 670 670 qemu_irq irq, omap_clk fclk, omap_clk iclk, 671 671 qemu_irq txdma, qemu_irq rxdma, 672 - const char *label, CharDriverState *chr); 672 + const char *label, Chardev *chr); 673 673 void omap_uart_reset(struct omap_uart_s *s); 674 - void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr); 674 + void omap_uart_attach(struct omap_uart_s *s, Chardev *chr); 675 675 676 676 struct omap_mpuio_s; 677 677 qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
+2 -2
include/hw/bt.h
··· 127 127 csrhci_pin_wakeup, 128 128 __csrhci_pins, 129 129 }; 130 - qemu_irq *csrhci_pins_get(CharDriverState *chr); 131 - CharDriverState *uart_hci_init(void); 130 + qemu_irq *csrhci_pins_get(Chardev *chr); 131 + Chardev *uart_hci_init(void); 132 132 133 133 /* bt-l2cap.c */ 134 134 struct bt_l2cap_device_s;
+1 -1
include/hw/char/cadence_uart.h
··· 51 51 52 52 static inline DeviceState *cadence_uart_create(hwaddr addr, 53 53 qemu_irq irq, 54 - CharDriverState *chr) 54 + Chardev *chr) 55 55 { 56 56 DeviceState *dev; 57 57 SysBusDevice *s;
+1 -1
include/hw/char/escc.h
··· 5 5 #define TYPE_ESCC "escc" 6 6 #define ESCC_SIZE 4 7 7 MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB, 8 - CharDriverState *chrA, CharDriverState *chrB, 8 + Chardev *chrA, Chardev *chrB, 9 9 int clock, int it_shift); 10 10 11 11 void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
+2 -2
include/hw/char/pl011.h
··· 17 17 18 18 static inline DeviceState *pl011_create(hwaddr addr, 19 19 qemu_irq irq, 20 - CharDriverState *chr) 20 + Chardev *chr) 21 21 { 22 22 DeviceState *dev; 23 23 SysBusDevice *s; ··· 34 34 35 35 static inline DeviceState *pl011_luminary_create(hwaddr addr, 36 36 qemu_irq irq, 37 - CharDriverState *chr) 37 + Chardev *chr) 38 38 { 39 39 DeviceState *dev; 40 40 SysBusDevice *s;
+2 -2
include/hw/char/serial.h
··· 88 88 89 89 /* legacy pre qom */ 90 90 SerialState *serial_init(int base, qemu_irq irq, int baudbase, 91 - CharDriverState *chr, MemoryRegion *system_io); 91 + Chardev *chr, MemoryRegion *system_io); 92 92 SerialState *serial_mm_init(MemoryRegion *address_space, 93 93 hwaddr base, int it_shift, 94 94 qemu_irq irq, int baudbase, 95 - CharDriverState *chr, enum device_endian end); 95 + Chardev *chr, enum device_endian end); 96 96 97 97 /* serial-isa.c */ 98 98 #define TYPE_ISA_SERIAL "isa-serial"
+1 -1
include/hw/char/xilinx_uartlite.h
··· 17 17 18 18 static inline DeviceState *xilinx_uartlite_create(hwaddr addr, 19 19 qemu_irq irq, 20 - CharDriverState *chr) 20 + Chardev *chr) 21 21 { 22 22 DeviceState *dev; 23 23 SysBusDevice *s;
+1 -1
include/hw/cris/etraxfs.h
··· 48 48 49 49 static inline DeviceState *etraxfs_ser_create(hwaddr addr, 50 50 qemu_irq irq, 51 - CharDriverState *chr) 51 + Chardev *chr) 52 52 { 53 53 DeviceState *dev; 54 54 SysBusDevice *s;
+1 -1
include/hw/devices.h
··· 65 65 /* sm501.c */ 66 66 void sm501_init(struct MemoryRegion *address_space_mem, uint32_t base, 67 67 uint32_t local_mem_bytes, qemu_irq irq, 68 - CharDriverState *chr); 68 + Chardev *chr); 69 69 70 70 #endif
+2
include/hw/i386/apic_internal.h
··· 189 189 DeviceState *vapic; 190 190 hwaddr vapic_paddr; /* note: persistence via kvmvapic */ 191 191 bool legacy_instance_id; 192 + 193 + int apic_irq_delivered; /* for saving static variable */ 192 194 }; 193 195 194 196 typedef struct VAPICState {
+13
include/hw/i386/ich9.h
··· 64 64 uint8_t rst_cnt; 65 65 MemoryRegion rst_cnt_mem; 66 66 67 + /* SMI feature negotiation via fw_cfg */ 68 + uint64_t smi_host_features; /* guest-invisible, host endian */ 69 + uint8_t smi_host_features_le[8]; /* guest-visible, read-only, little 70 + * endian uint64_t */ 71 + uint8_t smi_guest_features_le[8]; /* guest-visible, read-write, little 72 + * endian uint64_t */ 73 + uint8_t smi_features_ok; /* guest-visible, read-only; selecting it 74 + * triggers feature lockdown */ 75 + uint64_t smi_negotiated_features; /* guest-invisible, host endian */ 76 + 67 77 /* isa bus */ 68 78 ISABus *isa_bus; 69 79 MemoryRegion rcrb_mem; /* root complex register block */ ··· 239 249 #define ICH9_SMB_HST_D0 0x05 240 250 #define ICH9_SMB_HST_D1 0x06 241 251 #define ICH9_SMB_HOST_BLOCK_DB 0x07 252 + 253 + /* bit positions used in fw_cfg SMI feature negotiation */ 254 + #define ICH9_LPC_SMI_F_BROADCAST_BIT 0 242 255 243 256 #endif /* HW_ICH9_H */
+11 -1
include/hw/i386/pc.h
··· 181 181 182 182 bool parallel_mm_init(MemoryRegion *address_space, 183 183 hwaddr base, int it_shift, qemu_irq irq, 184 - CharDriverState *chr); 184 + Chardev *chr); 185 185 186 186 /* i8259.c */ 187 187 ··· 381 381 .property = "x-mach-use-reliable-get-clock",\ 382 382 .value = "off",\ 383 383 },\ 384 + {\ 385 + .driver = "ICH9-LPC",\ 386 + .property = "x-smi-broadcast",\ 387 + .value = "off",\ 388 + },\ 389 + {\ 390 + .driver = TYPE_X86_CPU,\ 391 + .property = "vmware-cpuid-freq",\ 392 + .value = "off",\ 393 + }, 384 394 385 395 #define PC_COMPAT_2_7 \ 386 396 HW_COMPAT_2_7 \
+2 -2
include/hw/m68k/mcf.h
··· 11 11 unsigned size); 12 12 void mcf_uart_write(void *opaque, hwaddr addr, 13 13 uint64_t val, unsigned size); 14 - void *mcf_uart_init(qemu_irq irq, CharDriverState *chr); 14 + void *mcf_uart_init(qemu_irq irq, Chardev *chr); 15 15 void mcf_uart_mm_init(struct MemoryRegion *sysmem, 16 16 hwaddr base, 17 - qemu_irq irq, CharDriverState *chr); 17 + qemu_irq irq, Chardev *chr); 18 18 19 19 /* mcf_intc.c */ 20 20 qemu_irq *mcf_intc_init(struct MemoryRegion *sysmem,
+1 -1
include/hw/ppc/spapr_vio.h
··· 127 127 128 128 VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg); 129 129 void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len); 130 - void spapr_vty_create(VIOsPAPRBus *bus, CharDriverState *chardev); 130 + void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev); 131 131 void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd); 132 132 void spapr_vscsi_create(VIOsPAPRBus *bus); 133 133
+1
include/hw/qdev-core.h
··· 26 26 DEVICE_CATEGORY_DISPLAY, 27 27 DEVICE_CATEGORY_SOUND, 28 28 DEVICE_CATEGORY_MISC, 29 + DEVICE_CATEGORY_CPU, 29 30 DEVICE_CATEGORY_MAX 30 31 } DeviceCategory; 31 32
+1 -1
include/hw/qdev-properties.h
··· 184 184 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value); 185 185 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value); 186 186 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value); 187 - void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value); 187 + void qdev_prop_set_chr(DeviceState *dev, const char *name, Chardev *value); 188 188 void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value); 189 189 void qdev_prop_set_drive(DeviceState *dev, const char *name, 190 190 BlockBackend *value, Error **errp);
+1 -1
include/hw/sh4/sh.h
··· 42 42 #define SH_SERIAL_FEAT_SCIF (1 << 0) 43 43 void sh_serial_init(MemoryRegion *sysmem, 44 44 hwaddr base, int feat, 45 - uint32_t freq, CharDriverState *chr, 45 + uint32_t freq, Chardev *chr, 46 46 qemu_irq eri_source, 47 47 qemu_irq rxi_source, 48 48 qemu_irq txi_source,
+1 -1
include/hw/sparc/grlib.h
··· 100 100 101 101 static inline 102 102 DeviceState *grlib_apbuart_create(hwaddr base, 103 - CharDriverState *serial, 103 + Chardev *serial, 104 104 qemu_irq irq) 105 105 { 106 106 DeviceState *dev;
+1 -1
include/hw/xen/xen.h
··· 37 37 38 38 qemu_irq *xen_interrupt_controller_init(void); 39 39 40 - void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); 40 + void xenstore_store_pv_console_info(int i, struct Chardev *chr); 41 41 42 42 void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory); 43 43
+1 -1
include/monitor/monitor.h
··· 16 16 17 17 bool monitor_cur_is_qmp(void); 18 18 19 - void monitor_init(CharDriverState *chr, int flags); 19 + void monitor_init(Chardev *chr, int flags); 20 20 void monitor_cleanup(void); 21 21 22 22 int monitor_suspend(Monitor *mon);
+1 -1
include/qemu/typedefs.h
··· 17 17 typedef struct BlockDriverState BlockDriverState; 18 18 typedef struct BusClass BusClass; 19 19 typedef struct BusState BusState; 20 - typedef struct CharDriverState CharDriverState; 20 + typedef struct Chardev Chardev; 21 21 typedef struct CompatProperty CompatProperty; 22 22 typedef struct CPUAddressSpace CPUAddressSpace; 23 23 typedef struct CPUState CPUState;
+92 -63
include/sysemu/char.h
··· 10 10 #include "qapi/qmp/qstring.h" 11 11 #include "qemu/main-loop.h" 12 12 #include "qemu/bitmap.h" 13 + #include "qom/object.h" 13 14 14 15 /* character device */ 15 16 ··· 69 70 /* Whether it is possible to send/recv file descriptors 70 71 * over the data channel */ 71 72 QEMU_CHAR_FEATURE_FD_PASS, 73 + /* Whether replay or record mode is enabled */ 74 + QEMU_CHAR_FEATURE_REPLAY, 72 75 73 76 QEMU_CHAR_FEATURE_LAST, 74 77 } CharDriverFeature; 75 78 76 79 /* This is the backend as seen by frontend, the actual backend is 77 - * CharDriverState */ 80 + * Chardev */ 78 81 typedef struct CharBackend { 79 - CharDriverState *chr; 82 + Chardev *chr; 80 83 IOEventHandler *chr_event; 81 84 IOCanReadHandler *chr_can_read; 82 85 IOReadHandler *chr_read; ··· 85 88 int fe_open; 86 89 } CharBackend; 87 90 88 - struct CharDriverState { 91 + typedef struct CharDriver CharDriver; 92 + 93 + struct Chardev { 94 + Object parent_obj; 95 + 89 96 QemuMutex chr_write_lock; 90 - int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); 91 - int (*chr_sync_read)(struct CharDriverState *s, 92 - const uint8_t *buf, int len); 93 - GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond); 94 - void (*chr_update_read_handler)(struct CharDriverState *s, 95 - GMainContext *context); 96 - int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); 97 - int (*get_msgfds)(struct CharDriverState *s, int* fds, int num); 98 - int (*set_msgfds)(struct CharDriverState *s, int *fds, int num); 99 - int (*chr_add_client)(struct CharDriverState *chr, int fd); 100 - int (*chr_wait_connected)(struct CharDriverState *chr, Error **errp); 101 - void (*chr_free)(struct CharDriverState *chr); 102 - void (*chr_disconnect)(struct CharDriverState *chr); 103 - void (*chr_accept_input)(struct CharDriverState *chr); 104 - void (*chr_set_echo)(struct CharDriverState *chr, bool echo); 105 - void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open); 106 97 CharBackend *be; 107 - void *opaque; 108 98 char *label; 109 99 char *filename; 110 100 int logfd; 111 101 int be_open; 112 - int is_mux; 113 102 guint fd_in_tag; 114 - bool replay; 115 103 DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); 116 - QTAILQ_ENTRY(CharDriverState) next; 104 + QTAILQ_ENTRY(Chardev) next; 117 105 }; 118 106 119 107 /** 120 - * qemu_chr_alloc: 121 - * @backend: the common backend config 122 - * @errp: pointer to a NULL-initialized error object 123 - * 124 - * Allocate and initialize a new CharDriverState. 125 - * 126 - * Returns: a newly allocated CharDriverState, or NULL on error. 127 - */ 128 - CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp); 129 - 130 - /** 131 108 * @qemu_chr_new_from_opts: 132 109 * 133 110 * Create a new character backend from a QemuOpts list. ··· 136 113 * 137 114 * Returns: a new character backend 138 115 */ 139 - CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, 140 - Error **errp); 116 + Chardev *qemu_chr_new_from_opts(QemuOpts *opts, 117 + Error **errp); 141 118 142 119 /** 143 120 * @qemu_chr_parse_common: ··· 159 136 * 160 137 * Returns: a new character backend 161 138 */ 162 - CharDriverState *qemu_chr_new(const char *label, const char *filename); 139 + Chardev *qemu_chr_new(const char *label, const char *filename); 163 140 164 141 165 142 /** ··· 197 174 * 198 175 * Returns: a new character backend 199 176 */ 200 - CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename); 177 + Chardev *qemu_chr_new_noreplay(const char *label, const char *filename); 201 178 202 179 /** 203 180 * @qemu_chr_delete: ··· 205 182 * Destroy a character backend and remove it from the list of 206 183 * identified character backends. 207 184 */ 208 - void qemu_chr_delete(CharDriverState *chr); 185 + void qemu_chr_delete(Chardev *chr); 209 186 210 187 /** 211 188 * @qemu_chr_free: 212 189 * 213 190 * Destroy a character backend. 214 191 */ 215 - void qemu_chr_free(CharDriverState *chr); 192 + void qemu_chr_free(Chardev *chr); 216 193 217 194 /** 218 195 * @qemu_chr_fe_set_echo: ··· 258 235 * @cond the condition to poll for 259 236 * @func the function to call when the condition happens 260 237 * @user_data the opaque pointer to pass to @func 238 + * 239 + * Returns: the source tag 261 240 */ 262 241 guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, 263 242 GIOFunc func, void *user_data); ··· 366 345 * 367 346 * Returns: the number of bytes the front end can receive via @qemu_chr_be_write 368 347 */ 369 - int qemu_chr_be_can_write(CharDriverState *s); 348 + int qemu_chr_be_can_write(Chardev *s); 370 349 371 350 /** 372 351 * @qemu_chr_be_write: ··· 378 357 * @buf a buffer to receive data from the front end 379 358 * @len the number of bytes to receive from the front end 380 359 */ 381 - void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); 360 + void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len); 382 361 383 362 /** 384 363 * @qemu_chr_be_write_impl: ··· 388 367 * @buf a buffer to receive data from the front end 389 368 * @len the number of bytes to receive from the front end 390 369 */ 391 - void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len); 370 + void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len); 392 371 393 372 /** 394 373 * @qemu_chr_be_event: ··· 397 376 * 398 377 * @event the event to send 399 378 */ 400 - void qemu_chr_be_event(CharDriverState *s, int event); 379 + void qemu_chr_be_event(Chardev *s, int event); 401 380 402 381 /** 403 382 * @qemu_chr_fe_init: ··· 408 387 * 409 388 * Returns: false on error. 410 389 */ 411 - bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); 390 + bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp); 412 391 413 392 /** 414 393 * @qemu_chr_fe_get_driver: ··· 416 395 * Returns the driver associated with a CharBackend or NULL if no 417 396 * associated CharDriver. 418 397 */ 419 - CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); 398 + Chardev *qemu_chr_fe_get_driver(CharBackend *be); 420 399 421 400 /** 422 401 * @qemu_chr_fe_deinit: ··· 461 440 */ 462 441 void qemu_chr_fe_take_focus(CharBackend *b); 463 442 464 - void qemu_chr_be_generic_open(CharDriverState *s); 443 + void qemu_chr_be_generic_open(Chardev *s); 465 444 void qemu_chr_fe_accept_input(CharBackend *be); 466 - int qemu_chr_add_client(CharDriverState *s, int fd); 467 - CharDriverState *qemu_chr_find(const char *name); 468 - bool chr_is_ringbuf(const CharDriverState *chr); 445 + int qemu_chr_add_client(Chardev *s, int fd); 446 + Chardev *qemu_chr_find(const char *name); 469 447 470 - bool qemu_chr_has_feature(CharDriverState *chr, 448 + bool qemu_chr_has_feature(Chardev *chr, 471 449 CharDriverFeature feature); 472 - void qemu_chr_set_feature(CharDriverState *chr, 450 + void qemu_chr_set_feature(Chardev *chr, 473 451 CharDriverFeature feature); 474 452 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); 475 453 476 - typedef void CharDriverParse(QemuOpts *opts, ChardevBackend *backend, 477 - Error **errp); 478 - typedef CharDriverState *CharDriverCreate(const char *id, 479 - ChardevBackend *backend, 480 - ChardevReturn *ret, bool *be_opened, 481 - Error **errp); 454 + #define TYPE_CHARDEV "chardev" 455 + #define CHARDEV(obj) OBJECT_CHECK(Chardev, (obj), TYPE_CHARDEV) 456 + #define CHARDEV_CLASS(klass) \ 457 + OBJECT_CLASS_CHECK(ChardevClass, (klass), TYPE_CHARDEV) 458 + #define CHARDEV_GET_CLASS(obj) \ 459 + OBJECT_GET_CLASS(ChardevClass, (obj), TYPE_CHARDEV) 460 + 461 + #define TYPE_CHARDEV_NULL "chardev-null" 462 + #define TYPE_CHARDEV_MUX "chardev-mux" 463 + #define TYPE_CHARDEV_RINGBUF "chardev-ringbuf" 464 + #define TYPE_CHARDEV_PTY "chardev-pty" 465 + #define TYPE_CHARDEV_CONSOLE "chardev-console" 466 + #define TYPE_CHARDEV_STDIO "chardev-stdio" 467 + #define TYPE_CHARDEV_PIPE "chardev-pipe" 468 + #define TYPE_CHARDEV_MEMORY "chardev-memory" 469 + #define TYPE_CHARDEV_PARALLEL "chardev-parallel" 470 + #define TYPE_CHARDEV_FILE "chardev-file" 471 + #define TYPE_CHARDEV_SERIAL "chardev-serial" 472 + #define TYPE_CHARDEV_SOCKET "chardev-socket" 473 + #define TYPE_CHARDEV_UDP "chardev-udp" 474 + 475 + #define CHARDEV_IS_MUX(chr) \ 476 + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_MUX) 477 + #define CHARDEV_IS_RINGBUF(chr) \ 478 + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_RINGBUF) 479 + #define CHARDEV_IS_PTY(chr) \ 480 + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_PTY) 481 + 482 + typedef struct ChardevClass { 483 + ObjectClass parent_class; 484 + 485 + bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ 486 + 487 + void (*open)(Chardev *chr, ChardevBackend *backend, 488 + bool *be_opened, Error **errp); 482 489 483 - void register_char_driver(const char *name, ChardevBackendKind kind, 484 - CharDriverParse *parse, CharDriverCreate *create); 490 + int (*chr_write)(Chardev *s, const uint8_t *buf, int len); 491 + int (*chr_sync_read)(Chardev *s, const uint8_t *buf, int len); 492 + GSource *(*chr_add_watch)(Chardev *s, GIOCondition cond); 493 + void (*chr_update_read_handler)(Chardev *s, GMainContext *context); 494 + int (*chr_ioctl)(Chardev *s, int cmd, void *arg); 495 + int (*get_msgfds)(Chardev *s, int* fds, int num); 496 + int (*set_msgfds)(Chardev *s, int *fds, int num); 497 + int (*chr_add_client)(Chardev *chr, int fd); 498 + int (*chr_wait_connected)(Chardev *chr, Error **errp); 499 + void (*chr_free)(Chardev *chr); 500 + void (*chr_disconnect)(Chardev *chr); 501 + void (*chr_accept_input)(Chardev *chr); 502 + void (*chr_set_echo)(Chardev *chr, bool echo); 503 + void (*chr_set_fe_open)(Chardev *chr, int fe_open); 504 + } ChardevClass; 505 + 506 + struct CharDriver { 507 + ChardevBackendKind kind; 508 + const char *alias; 509 + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); 510 + }; 511 + 512 + Chardev *qemu_chardev_new(const char *id, const char *typename, 513 + ChardevBackend *backend, Error **errp); 514 + 515 + void register_char_driver(const CharDriver *driver); 485 516 486 517 extern int term_escape_char; 487 518 488 - 489 519 /* console.c */ 490 - typedef CharDriverState *(VcHandler)(ChardevVC *vc, Error **errp); 491 - void register_vc_handler(VcHandler *handler); 520 + void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp); 492 521 493 522 #endif
+11 -2
include/sysemu/replay.h
··· 43 43 44 44 extern ReplayMode replay_mode; 45 45 46 + /* Name of the initial VM snapshot */ 47 + extern char *replay_snapshot; 48 + 46 49 /* Replay process control functions */ 47 50 48 51 /*! Enables recording or saving event log with specified parameters */ ··· 125 128 /* Character device */ 126 129 127 130 /*! Registers char driver to save it's events */ 128 - void replay_register_char_driver(struct CharDriverState *chr); 131 + void replay_register_char_driver(struct Chardev *chr); 129 132 /*! Saves write to char device event to the log */ 130 - void replay_chr_be_write(struct CharDriverState *s, uint8_t *buf, int len); 133 + void replay_chr_be_write(struct Chardev *s, uint8_t *buf, int len); 131 134 /*! Writes char write return value to the replay log. */ 132 135 void replay_char_write_event_save(int res, int offset); 133 136 /*! Reads char write return value from the replay log. */ ··· 148 151 /*! Called to write network packet to the replay log. */ 149 152 void replay_net_packet_event(ReplayNetState *rns, unsigned flags, 150 153 const struct iovec *iov, int iovcnt); 154 + 155 + /* VM state operations */ 156 + 157 + /*! Called at the start of execution. 158 + Loads or saves initial vmstate depending on execution mode. */ 159 + void replay_vmstate_init(void); 151 160 152 161 #endif
+3 -2
include/sysemu/sysemu.h
··· 74 74 void qemu_remove_machine_init_done_notifier(Notifier *notify); 75 75 76 76 void hmp_savevm(Monitor *mon, const QDict *qdict); 77 + int save_vmstate(Monitor *mon, const char *name); 77 78 int load_vmstate(const char *name); 78 79 void hmp_delvm(Monitor *mon, const QDict *qdict); 79 80 void hmp_info_snapshots(Monitor *mon, const QDict *qdict); ··· 189 190 190 191 #define MAX_SERIAL_PORTS 4 191 192 192 - extern CharDriverState *serial_hds[MAX_SERIAL_PORTS]; 193 + extern Chardev *serial_hds[MAX_SERIAL_PORTS]; 193 194 194 195 /* parallel ports */ 195 196 196 197 #define MAX_PARALLEL_PORTS 3 197 198 198 - extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; 199 + extern Chardev *parallel_hds[MAX_PARALLEL_PORTS]; 199 200 200 201 void hmp_usb_add(Monitor *mon, const QDict *qdict); 201 202 void hmp_usb_del(Monitor *mon, const QDict *qdict);
+2
include/ui/console.h
··· 383 383 void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); 384 384 void graphic_hw_gl_block(QemuConsole *con, bool block); 385 385 386 + void qemu_console_early_init(void); 387 + 386 388 QemuConsole *qemu_console_lookup_by_index(unsigned int index); 387 389 QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head); 388 390 QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
+1 -1
include/ui/gtk.h
··· 64 64 GtkWidget *box; 65 65 GtkWidget *scrollbar; 66 66 GtkWidget *terminal; 67 - CharDriverState *chr; 67 + Chardev *chr; 68 68 bool echo; 69 69 } VirtualVteConsole; 70 70 #endif
+1 -1
include/ui/qemu-spice.h
··· 51 51 #if SPICE_SERVER_VERSION >= 0x000c02 52 52 void qemu_spice_register_ports(void); 53 53 #else 54 - static inline CharDriverState *qemu_chr_open_spice_port(const char *name) 54 + static inline Chardev *qemu_chr_open_spice_port(const char *name) 55 55 { return NULL; } 56 56 #endif 57 57
+67 -22
memory.c
··· 2450 2450 call_rcu(as, do_address_space_destroy, rcu); 2451 2451 } 2452 2452 2453 + static const char *memory_region_type(MemoryRegion *mr) 2454 + { 2455 + if (memory_region_is_ram_device(mr)) { 2456 + return "ramd"; 2457 + } else if (memory_region_is_romd(mr)) { 2458 + return "romd"; 2459 + } else if (memory_region_is_rom(mr)) { 2460 + return "rom"; 2461 + } else if (memory_region_is_ram(mr)) { 2462 + return "ram"; 2463 + } else { 2464 + return "i/o"; 2465 + } 2466 + } 2467 + 2453 2468 typedef struct MemoryRegionList MemoryRegionList; 2454 2469 2455 2470 struct MemoryRegionList { ··· 2459 2474 2460 2475 typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead; 2461 2476 2477 + #define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \ 2478 + int128_sub((size), int128_one())) : 0) 2479 + #define MTREE_INDENT " " 2480 + 2462 2481 static void mtree_print_mr(fprintf_function mon_printf, void *f, 2463 2482 const MemoryRegion *mr, unsigned int level, 2464 2483 hwaddr base, ··· 2474 2493 } 2475 2494 2476 2495 for (i = 0; i < level; i++) { 2477 - mon_printf(f, " "); 2496 + mon_printf(f, MTREE_INDENT); 2478 2497 } 2479 2498 2480 2499 if (mr->alias) { ··· 2494 2513 QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue); 2495 2514 } 2496 2515 mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx 2497 - " (prio %d, %c%c): alias %s @%s " TARGET_FMT_plx 2516 + " (prio %d, %s): alias %s @%s " TARGET_FMT_plx 2498 2517 "-" TARGET_FMT_plx "%s\n", 2499 2518 base + mr->addr, 2500 - base + mr->addr 2501 - + (int128_nz(mr->size) ? 2502 - (hwaddr)int128_get64(int128_sub(mr->size, 2503 - int128_one())) : 0), 2519 + base + mr->addr + MR_SIZE(mr->size), 2504 2520 mr->priority, 2505 - mr->romd_mode ? 'R' : '-', 2506 - !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W' 2507 - : '-', 2521 + memory_region_type((MemoryRegion *)mr), 2508 2522 memory_region_name(mr), 2509 2523 memory_region_name(mr->alias), 2510 2524 mr->alias_offset, 2511 - mr->alias_offset 2512 - + (int128_nz(mr->size) ? 2513 - (hwaddr)int128_get64(int128_sub(mr->size, 2514 - int128_one())) : 0), 2525 + mr->alias_offset + MR_SIZE(mr->size), 2515 2526 mr->enabled ? "" : " [disabled]"); 2516 2527 } else { 2517 2528 mon_printf(f, 2518 - TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s%s\n", 2529 + TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %s): %s%s\n", 2519 2530 base + mr->addr, 2520 - base + mr->addr 2521 - + (int128_nz(mr->size) ? 2522 - (hwaddr)int128_get64(int128_sub(mr->size, 2523 - int128_one())) : 0), 2531 + base + mr->addr + MR_SIZE(mr->size), 2524 2532 mr->priority, 2525 - mr->romd_mode ? 'R' : '-', 2526 - !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W' 2527 - : '-', 2533 + memory_region_type((MemoryRegion *)mr), 2528 2534 memory_region_name(mr), 2529 2535 mr->enabled ? "" : " [disabled]"); 2530 2536 } ··· 2558 2564 } 2559 2565 } 2560 2566 2561 - void mtree_info(fprintf_function mon_printf, void *f) 2567 + static void mtree_print_flatview(fprintf_function p, void *f, 2568 + AddressSpace *as) 2569 + { 2570 + FlatView *view = address_space_get_flatview(as); 2571 + FlatRange *range = &view->ranges[0]; 2572 + MemoryRegion *mr; 2573 + int n = view->nr; 2574 + 2575 + if (n <= 0) { 2576 + p(f, MTREE_INDENT "No rendered FlatView for " 2577 + "address space '%s'\n", as->name); 2578 + flatview_unref(view); 2579 + return; 2580 + } 2581 + 2582 + while (n--) { 2583 + mr = range->mr; 2584 + p(f, MTREE_INDENT TARGET_FMT_plx "-" 2585 + TARGET_FMT_plx " (prio %d, %s): %s\n", 2586 + int128_get64(range->addr.start), 2587 + int128_get64(range->addr.start) + MR_SIZE(range->addr.size), 2588 + mr->priority, 2589 + memory_region_type(mr), 2590 + memory_region_name(mr)); 2591 + range++; 2592 + } 2593 + 2594 + flatview_unref(view); 2595 + } 2596 + 2597 + void mtree_info(fprintf_function mon_printf, void *f, bool flatview) 2562 2598 { 2563 2599 MemoryRegionListHead ml_head; 2564 2600 MemoryRegionList *ml, *ml2; 2565 2601 AddressSpace *as; 2602 + 2603 + if (flatview) { 2604 + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { 2605 + mon_printf(f, "address-space (flat view): %s\n", as->name); 2606 + mtree_print_flatview(mon_printf, f, as); 2607 + mon_printf(f, "\n"); 2608 + } 2609 + return; 2610 + } 2566 2611 2567 2612 QTAILQ_INIT(&ml_head); 2568 2613
+22 -11
migration/savevm.c
··· 2042 2042 return ret; 2043 2043 } 2044 2044 2045 - void hmp_savevm(Monitor *mon, const QDict *qdict) 2045 + int save_vmstate(Monitor *mon, const char *name) 2046 2046 { 2047 2047 BlockDriverState *bs, *bs1; 2048 2048 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; 2049 - int ret; 2049 + int ret = -1; 2050 2050 QEMUFile *f; 2051 2051 int saved_vm_running; 2052 2052 uint64_t vm_state_size; 2053 2053 qemu_timeval tv; 2054 2054 struct tm tm; 2055 - const char *name = qdict_get_try_str(qdict, "name"); 2056 2055 Error *local_err = NULL; 2057 2056 AioContext *aio_context; 2058 2057 2059 2058 if (!bdrv_all_can_snapshot(&bs)) { 2060 2059 monitor_printf(mon, "Device '%s' is writable but does not " 2061 2060 "support snapshots.\n", bdrv_get_device_name(bs)); 2062 - return; 2061 + return ret; 2063 2062 } 2064 2063 2065 2064 /* Delete old snapshots of the same name */ 2066 - if (name && bdrv_all_delete_snapshot(name, &bs1, &local_err) < 0) { 2067 - error_reportf_err(local_err, 2068 - "Error while deleting snapshot on device '%s': ", 2069 - bdrv_get_device_name(bs1)); 2070 - return; 2065 + if (name) { 2066 + ret = bdrv_all_delete_snapshot(name, &bs1, &local_err); 2067 + if (ret < 0) { 2068 + error_reportf_err(local_err, 2069 + "Error while deleting snapshot on device '%s': ", 2070 + bdrv_get_device_name(bs1)); 2071 + return ret; 2072 + } 2071 2073 } 2072 2074 2073 2075 bs = bdrv_all_find_vmstate_bs(); 2074 2076 if (bs == NULL) { 2075 2077 monitor_printf(mon, "No block device can accept snapshots\n"); 2076 - return; 2078 + return ret; 2077 2079 } 2078 2080 aio_context = bdrv_get_aio_context(bs); 2079 2081 ··· 2082 2084 ret = global_state_store(); 2083 2085 if (ret) { 2084 2086 monitor_printf(mon, "Error saving global state\n"); 2085 - return; 2087 + return ret; 2086 2088 } 2087 2089 vm_stop(RUN_STATE_SAVE_VM); 2088 2090 ··· 2128 2130 if (ret < 0) { 2129 2131 monitor_printf(mon, "Error while creating snapshot on '%s'\n", 2130 2132 bdrv_get_device_name(bs)); 2133 + goto the_end; 2131 2134 } 2135 + 2136 + ret = 0; 2132 2137 2133 2138 the_end: 2134 2139 aio_context_release(aio_context); 2135 2140 if (saved_vm_running) { 2136 2141 vm_start(); 2137 2142 } 2143 + return ret; 2144 + } 2145 + 2146 + void hmp_savevm(Monitor *mon, const QDict *qdict) 2147 + { 2148 + save_vmstate(mon, qdict_get_try_str(qdict, "name")); 2138 2149 } 2139 2150 2140 2151 void qmp_xen_save_devices_state(const char *filename, Error **errp)
+6 -4
monitor.c
··· 1529 1529 1530 1530 static void hmp_info_mtree(Monitor *mon, const QDict *qdict) 1531 1531 { 1532 - mtree_info((fprintf_function)monitor_printf, mon); 1532 + bool flatview = qdict_get_try_bool(qdict, "flatview", false); 1533 + 1534 + mtree_info((fprintf_function)monitor_printf, mon, flatview); 1533 1535 } 1534 1536 1535 1537 static void hmp_info_numa(Monitor *mon, const QDict *qdict) ··· 3193 3195 ChardevInfo *chr_info = list->value; 3194 3196 3195 3197 if (!strncmp(chr_info->label, str, len)) { 3196 - CharDriverState *chr = qemu_chr_find(chr_info->label); 3197 - if (chr && chr_is_ringbuf(chr)) { 3198 + Chardev *chr = qemu_chr_find(chr_info->label); 3199 + if (chr && CHARDEV_IS_RINGBUF(chr)) { 3198 3200 readline_add_completion(rs, chr_info->label); 3199 3201 } 3200 3202 } ··· 3983 3985 qemu_mutex_init(&monitor_lock); 3984 3986 } 3985 3987 3986 - void monitor_init(CharDriverState *chr, int flags) 3988 + void monitor_init(Chardev *chr, int flags) 3987 3989 { 3988 3990 static int is_first_init = 1; 3989 3991 Monitor *mon;
+2 -2
net/colo-compare.c
··· 564 564 * Return 0 is success. 565 565 * Return 1 is failed. 566 566 */ 567 - static int find_and_check_chardev(CharDriverState **chr, 567 + static int find_and_check_chardev(Chardev **chr, 568 568 char *chr_name, 569 569 Error **errp) 570 570 { ··· 611 611 static void colo_compare_complete(UserCreatable *uc, Error **errp) 612 612 { 613 613 CompareState *s = COLO_COMPARE(uc); 614 - CharDriverState *chr; 614 + Chardev *chr; 615 615 char thread_name[64]; 616 616 static int compare_id; 617 617
+2 -2
net/filter-mirror.c
··· 191 191 static void filter_mirror_setup(NetFilterState *nf, Error **errp) 192 192 { 193 193 MirrorState *s = FILTER_MIRROR(nf); 194 - CharDriverState *chr; 194 + Chardev *chr; 195 195 196 196 if (!s->outdev) { 197 197 error_setg(errp, "filter mirror needs 'outdev' " ··· 220 220 static void filter_redirector_setup(NetFilterState *nf, Error **errp) 221 221 { 222 222 MirrorState *s = FILTER_REDIRECTOR(nf); 223 - CharDriverState *chr; 223 + Chardev *chr; 224 224 225 225 if (!s->indev && !s->outdev) { 226 226 error_setg(errp, "filter redirector needs 'indev' or "
+1 -1
net/slirp.c
··· 748 748 } 749 749 } else { 750 750 Error *err = NULL; 751 - CharDriverState *chr = qemu_chr_new(buf, p); 751 + Chardev *chr = qemu_chr_new(buf, p); 752 752 753 753 if (!chr) { 754 754 error_report("could not open guest forwarding device '%s'", buf);
+5 -5
net/vhost-user.c
··· 195 195 const char *name = opaque; 196 196 NetClientState *ncs[MAX_QUEUE_NUM]; 197 197 VhostUserState *s; 198 - CharDriverState *chr; 198 + Chardev *chr; 199 199 Error *err = NULL; 200 200 int queues; 201 201 ··· 232 232 } 233 233 234 234 static int net_vhost_user_init(NetClientState *peer, const char *device, 235 - const char *name, CharDriverState *chr, 235 + const char *name, Chardev *chr, 236 236 int queues) 237 237 { 238 238 Error *err = NULL; ··· 274 274 return 0; 275 275 } 276 276 277 - static CharDriverState *net_vhost_claim_chardev( 277 + static Chardev *net_vhost_claim_chardev( 278 278 const NetdevVhostUserOptions *opts, Error **errp) 279 279 { 280 - CharDriverState *chr = qemu_chr_find(opts->chardev); 280 + Chardev *chr = qemu_chr_find(opts->chardev); 281 281 282 282 if (chr == NULL) { 283 283 error_setg(errp, "chardev \"%s\" not found", opts->chardev); ··· 324 324 { 325 325 int queues; 326 326 const NetdevVhostUserOptions *vhost_user_opts; 327 - CharDriverState *chr; 327 + Chardev *chr; 328 328 329 329 assert(netdev->type == NET_CLIENT_DRIVER_VHOST_USER); 330 330 vhost_user_opts = &netdev->u.vhost_user;
+1
qdev-monitor.c
··· 137 137 [DEVICE_CATEGORY_DISPLAY] = "Display", 138 138 [DEVICE_CATEGORY_SOUND] = "Sound", 139 139 [DEVICE_CATEGORY_MISC] = "Misc", 140 + [DEVICE_CATEGORY_CPU] = "CPU", 140 141 [DEVICE_CATEGORY_MAX] = "Uncategorized", 141 142 }; 142 143 GSList *list, *elt;
+1061 -853
qemu-char.c
··· 89 89 #define READ_RETRIES 10 90 90 #define TCP_MAX_FDS 16 91 91 92 - typedef struct MuxDriver MuxDriver; 92 + typedef struct MuxChardev MuxChardev; 93 93 94 94 /***********************************************************/ 95 95 /* Socket address helpers */ ··· 157 157 /***********************************************************/ 158 158 /* character device */ 159 159 160 - static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = 160 + static QTAILQ_HEAD(ChardevHead, Chardev) chardevs = 161 161 QTAILQ_HEAD_INITIALIZER(chardevs); 162 162 163 - static void qemu_chr_free_common(CharDriverState *chr); 164 - 165 - CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp) 166 - { 167 - CharDriverState *chr = g_malloc0(sizeof(CharDriverState)); 168 - qemu_mutex_init(&chr->chr_write_lock); 169 - 170 - if (backend->has_logfile) { 171 - int flags = O_WRONLY | O_CREAT; 172 - if (backend->has_logappend && 173 - backend->logappend) { 174 - flags |= O_APPEND; 175 - } else { 176 - flags |= O_TRUNC; 177 - } 178 - chr->logfd = qemu_open(backend->logfile, flags, 0666); 179 - if (chr->logfd < 0) { 180 - error_setg_errno(errp, errno, 181 - "Unable to open logfile %s", 182 - backend->logfile); 183 - g_free(chr); 184 - return NULL; 185 - } 186 - } else { 187 - chr->logfd = -1; 188 - } 189 - 190 - return chr; 191 - } 192 - 193 - void qemu_chr_be_event(CharDriverState *s, int event) 163 + void qemu_chr_be_event(Chardev *s, int event) 194 164 { 195 165 CharBackend *be = s->be; 196 166 ··· 211 181 be->chr_event(be->opaque, event); 212 182 } 213 183 214 - void qemu_chr_be_generic_open(CharDriverState *s) 184 + void qemu_chr_be_generic_open(Chardev *s) 215 185 { 216 186 qemu_chr_be_event(s, CHR_EVENT_OPENED); 217 187 } ··· 219 189 220 190 /* Not reporting errors from writing to logfile, as logs are 221 191 * defined to be "best effort" only */ 222 - static void qemu_chr_fe_write_log(CharDriverState *s, 192 + static void qemu_chr_fe_write_log(Chardev *s, 223 193 const uint8_t *buf, size_t len) 224 194 { 225 195 size_t done = 0; ··· 244 214 } 245 215 } 246 216 247 - static int qemu_chr_fe_write_buffer(CharDriverState *s, const uint8_t *buf, int len, int *offset) 217 + static int qemu_chr_fe_write_buffer(Chardev *s, 218 + const uint8_t *buf, int len, int *offset) 248 219 { 220 + ChardevClass *cc = CHARDEV_GET_CLASS(s); 249 221 int res = 0; 250 222 *offset = 0; 251 223 252 224 qemu_mutex_lock(&s->chr_write_lock); 253 225 while (*offset < len) { 254 226 retry: 255 - res = s->chr_write(s, buf + *offset, len - *offset); 227 + res = cc->chr_write(s, buf + *offset, len - *offset); 256 228 if (res < 0 && errno == EAGAIN) { 257 229 g_usleep(100); 258 230 goto retry; ··· 272 244 return res; 273 245 } 274 246 247 + static bool qemu_chr_replay(Chardev *chr) 248 + { 249 + return qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_REPLAY); 250 + } 251 + 275 252 int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len) 276 253 { 277 - CharDriverState *s = be->chr; 254 + Chardev *s = be->chr; 255 + ChardevClass *cc; 278 256 int ret; 279 257 280 258 if (!s) { 281 259 return 0; 282 260 } 283 261 284 - if (s->replay && replay_mode == REPLAY_MODE_PLAY) { 262 + if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) { 285 263 int offset; 286 264 replay_char_write_event_load(&ret, &offset); 287 265 assert(offset <= len); ··· 289 267 return ret; 290 268 } 291 269 270 + cc = CHARDEV_GET_CLASS(s); 292 271 qemu_mutex_lock(&s->chr_write_lock); 293 - ret = s->chr_write(s, buf, len); 272 + ret = cc->chr_write(s, buf, len); 294 273 295 274 if (ret > 0) { 296 275 qemu_chr_fe_write_log(s, buf, ret); ··· 298 277 299 278 qemu_mutex_unlock(&s->chr_write_lock); 300 279 301 - if (s->replay && replay_mode == REPLAY_MODE_RECORD) { 280 + if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) { 302 281 replay_char_write_event_save(ret, ret < 0 ? 0 : ret); 303 282 } 304 283 305 284 return ret; 306 285 } 307 286 308 - static int qemu_chr_write_all(CharDriverState *s, const uint8_t *buf, int len) 287 + static int qemu_chr_write_all(Chardev *s, const uint8_t *buf, int len) 309 288 { 310 289 int offset; 311 290 int res; 312 291 313 - if (s->replay && replay_mode == REPLAY_MODE_PLAY) { 292 + if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) { 314 293 replay_char_write_event_load(&res, &offset); 315 294 assert(offset <= len); 316 295 qemu_chr_fe_write_buffer(s, buf, offset, &offset); ··· 319 298 320 299 res = qemu_chr_fe_write_buffer(s, buf, len, &offset); 321 300 322 - if (s->replay && replay_mode == REPLAY_MODE_RECORD) { 301 + if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) { 323 302 replay_char_write_event_save(res, offset); 324 303 } 325 304 ··· 331 310 332 311 int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len) 333 312 { 334 - CharDriverState *s = be->chr; 313 + Chardev *s = be->chr; 335 314 336 315 if (!s) { 337 316 return 0; ··· 342 321 343 322 int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len) 344 323 { 345 - CharDriverState *s = be->chr; 324 + Chardev *s = be->chr; 346 325 int offset = 0, counter = 10; 347 326 int res; 348 327 349 - if (!s || !s->chr_sync_read) { 328 + if (!s || !CHARDEV_GET_CLASS(s)->chr_sync_read) { 350 329 return 0; 351 330 } 352 331 353 - if (s->replay && replay_mode == REPLAY_MODE_PLAY) { 332 + if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) { 354 333 return replay_char_read_all_load(buf); 355 334 } 356 335 357 336 while (offset < len) { 358 337 retry: 359 - res = s->chr_sync_read(s, buf + offset, len - offset); 338 + res = CHARDEV_GET_CLASS(s)->chr_sync_read(s, buf + offset, 339 + len - offset); 360 340 if (res == -1 && errno == EAGAIN) { 361 341 g_usleep(100); 362 342 goto retry; ··· 367 347 } 368 348 369 349 if (res < 0) { 370 - if (s->replay && replay_mode == REPLAY_MODE_RECORD) { 350 + if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) { 371 351 replay_char_read_all_save_error(res); 372 352 } 373 353 return res; ··· 380 360 } 381 361 } 382 362 383 - if (s->replay && replay_mode == REPLAY_MODE_RECORD) { 363 + if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) { 384 364 replay_char_read_all_save_buf(buf, offset); 385 365 } 386 366 return offset; ··· 388 368 389 369 int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg) 390 370 { 391 - CharDriverState *s = be->chr; 371 + Chardev *s = be->chr; 392 372 int res; 393 373 394 - if (!s || !s->chr_ioctl || s->replay) { 374 + if (!s || !CHARDEV_GET_CLASS(s)->chr_ioctl || qemu_chr_replay(s)) { 395 375 res = -ENOTSUP; 396 376 } else { 397 - res = s->chr_ioctl(s, cmd, arg); 377 + res = CHARDEV_GET_CLASS(s)->chr_ioctl(s, cmd, arg); 398 378 } 399 379 400 380 return res; 401 381 } 402 382 403 - int qemu_chr_be_can_write(CharDriverState *s) 383 + int qemu_chr_be_can_write(Chardev *s) 404 384 { 405 385 CharBackend *be = s->be; 406 386 ··· 411 391 return be->chr_can_read(be->opaque); 412 392 } 413 393 414 - void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len) 394 + void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len) 415 395 { 416 396 CharBackend *be = s->be; 417 397 ··· 420 400 } 421 401 } 422 402 423 - void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len) 403 + void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len) 424 404 { 425 - if (s->replay) { 405 + if (qemu_chr_replay(s)) { 426 406 if (replay_mode == REPLAY_MODE_PLAY) { 427 407 return; 428 408 } ··· 434 414 435 415 int qemu_chr_fe_get_msgfd(CharBackend *be) 436 416 { 437 - CharDriverState *s = be->chr; 417 + Chardev *s = be->chr; 438 418 int fd; 439 419 int res = (qemu_chr_fe_get_msgfds(be, &fd, 1) == 1) ? fd : -1; 440 - if (s && s->replay) { 441 - fprintf(stderr, 442 - "Replay: get msgfd is not supported for serial devices yet\n"); 420 + if (s && qemu_chr_replay(s)) { 421 + error_report("Replay: get msgfd is not supported " 422 + "for serial devices yet"); 443 423 exit(1); 444 424 } 445 425 return res; ··· 447 427 448 428 int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len) 449 429 { 450 - CharDriverState *s = be->chr; 430 + Chardev *s = be->chr; 451 431 452 432 if (!s) { 453 433 return -1; 454 434 } 455 435 456 - return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1; 436 + return CHARDEV_GET_CLASS(s)->get_msgfds ? 437 + CHARDEV_GET_CLASS(s)->get_msgfds(s, fds, len) : -1; 457 438 } 458 439 459 440 int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num) 460 441 { 461 - CharDriverState *s = be->chr; 442 + Chardev *s = be->chr; 462 443 463 444 if (!s) { 464 445 return -1; 465 446 } 466 447 467 - return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1; 448 + return CHARDEV_GET_CLASS(s)->set_msgfds ? 449 + CHARDEV_GET_CLASS(s)->set_msgfds(s, fds, num) : -1; 468 450 } 469 451 470 - int qemu_chr_add_client(CharDriverState *s, int fd) 452 + int qemu_chr_add_client(Chardev *s, int fd) 471 453 { 472 - return s->chr_add_client ? s->chr_add_client(s, fd) : -1; 454 + return CHARDEV_GET_CLASS(s)->chr_add_client ? 455 + CHARDEV_GET_CLASS(s)->chr_add_client(s, fd) : -1; 473 456 } 474 457 475 458 void qemu_chr_fe_accept_input(CharBackend *be) 476 459 { 477 - CharDriverState *s = be->chr; 460 + Chardev *s = be->chr; 478 461 479 462 if (!s) { 480 463 return; 481 464 } 482 465 483 - if (s->chr_accept_input) 484 - s->chr_accept_input(s); 466 + if (CHARDEV_GET_CLASS(s)->chr_accept_input) { 467 + CHARDEV_GET_CLASS(s)->chr_accept_input(s); 468 + } 485 469 qemu_notify_event(); 486 470 } 487 471 ··· 497 481 va_end(ap); 498 482 } 499 483 500 - static void remove_fd_in_watch(CharDriverState *chr); 501 - static void mux_chr_set_handlers(CharDriverState *chr, GMainContext *context); 502 - static void mux_set_focus(CharDriverState *chr, int focus); 484 + static void remove_fd_in_watch(Chardev *chr); 485 + static void mux_chr_set_handlers(Chardev *chr, GMainContext *context); 486 + static void mux_set_focus(Chardev *chr, int focus); 503 487 504 - static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 488 + static void qemu_char_open(Chardev *chr, ChardevBackend *backend, 489 + bool *be_opened, Error **errp) 505 490 { 506 - return len; 491 + ChardevClass *cc = CHARDEV_GET_CLASS(chr); 492 + /* Any ChardevCommon member would work */ 493 + ChardevCommon *common = backend ? backend->u.null.data : NULL; 494 + 495 + if (common && common->has_logfile) { 496 + int flags = O_WRONLY | O_CREAT; 497 + if (common->has_logappend && 498 + common->logappend) { 499 + flags |= O_APPEND; 500 + } else { 501 + flags |= O_TRUNC; 502 + } 503 + chr->logfd = qemu_open(common->logfile, flags, 0666); 504 + if (chr->logfd < 0) { 505 + error_setg_errno(errp, errno, 506 + "Unable to open logfile %s", 507 + common->logfile); 508 + return; 509 + } 510 + } 511 + 512 + if (cc->open) { 513 + cc->open(chr, backend, be_opened, errp); 514 + } 507 515 } 508 516 509 - static CharDriverState *qemu_chr_open_null(const char *id, 510 - ChardevBackend *backend, 511 - ChardevReturn *ret, 512 - bool *be_opened, 513 - Error **errp) 517 + static void char_init(Object *obj) 514 518 { 515 - CharDriverState *chr; 516 - ChardevCommon *common = backend->u.null.data; 519 + Chardev *chr = CHARDEV(obj); 520 + 521 + chr->logfd = -1; 522 + qemu_mutex_init(&chr->chr_write_lock); 523 + } 524 + 525 + static void char_finalize(Object *obj) 526 + { 527 + Chardev *chr = CHARDEV(obj); 517 528 518 - chr = qemu_chr_alloc(common, errp); 519 - if (!chr) { 520 - return NULL; 529 + if (chr->be) { 530 + chr->be->chr = NULL; 521 531 } 522 - chr->chr_write = null_chr_write; 532 + g_free(chr->filename); 533 + g_free(chr->label); 534 + if (chr->logfd != -1) { 535 + close(chr->logfd); 536 + } 537 + qemu_mutex_destroy(&chr->chr_write_lock); 538 + } 539 + 540 + static const TypeInfo char_type_info = { 541 + .name = TYPE_CHARDEV, 542 + .parent = TYPE_OBJECT, 543 + .instance_size = sizeof(Chardev), 544 + .instance_init = char_init, 545 + .instance_finalize = char_finalize, 546 + .abstract = true, 547 + .class_size = sizeof(ChardevClass), 548 + }; 549 + 550 + static int null_chr_write(Chardev *chr, const uint8_t *buf, int len) 551 + { 552 + return len; 553 + } 554 + 555 + static void null_chr_open(Chardev *chr, 556 + ChardevBackend *backend, 557 + bool *be_opened, 558 + Error **errp) 559 + { 523 560 *be_opened = false; 524 - return chr; 561 + } 562 + 563 + static const CharDriver null_driver = { 564 + .kind = CHARDEV_BACKEND_KIND_NULL, 565 + }; 566 + 567 + static void char_null_class_init(ObjectClass *oc, void *data) 568 + { 569 + ChardevClass *cc = CHARDEV_CLASS(oc); 570 + 571 + cc->open = null_chr_open; 572 + cc->chr_write = null_chr_write; 525 573 } 526 574 575 + static const TypeInfo char_null_type_info = { 576 + .name = TYPE_CHARDEV_NULL, 577 + .parent = TYPE_CHARDEV, 578 + .instance_size = sizeof(Chardev), 579 + .class_init = char_null_class_init, 580 + }; 581 + 527 582 /* MUX driver for serial I/O splitting */ 528 583 #define MAX_MUX 4 529 584 #define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */ 530 585 #define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1) 531 - struct MuxDriver { 586 + struct MuxChardev { 587 + Chardev parent; 532 588 CharBackend *backends[MAX_MUX]; 533 589 CharBackend chr; 534 590 int focus; ··· 543 599 int cons[MAX_MUX]; 544 600 int timestamps; 545 601 546 - /* Protected by the CharDriverState chr_write_lock. */ 602 + /* Protected by the Chardev chr_write_lock. */ 547 603 int linestart; 548 604 int64_t timestamps_start; 549 605 }; 550 606 607 + #define MUX_CHARDEV(obj) OBJECT_CHECK(MuxChardev, (obj), TYPE_CHARDEV_MUX) 608 + 551 609 /* Called with chr_write_lock held. */ 552 - static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 610 + static int mux_chr_write(Chardev *chr, const uint8_t *buf, int len) 553 611 { 554 - MuxDriver *d = chr->opaque; 612 + MuxChardev *d = MUX_CHARDEV(chr); 555 613 int ret; 556 614 if (!d->timestamps) { 557 615 ret = qemu_chr_fe_write(&d->chr, buf, len); ··· 603 661 }; 604 662 605 663 int term_escape_char = 0x01; /* ctrl-a is used for escape */ 606 - static void mux_print_help(CharDriverState *chr) 664 + static void mux_print_help(Chardev *chr) 607 665 { 608 666 int i, j; 609 667 char ebuf[15] = "Escape-Char"; ··· 630 688 } 631 689 } 632 690 633 - static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event) 691 + static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event) 634 692 { 635 693 CharBackend *be = d->backends[mux_nr]; 636 694 ··· 639 697 } 640 698 } 641 699 642 - static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) 700 + static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch) 643 701 { 644 702 if (d->term_got_escape) { 645 703 d->term_got_escape = 0; ··· 683 741 return 0; 684 742 } 685 743 686 - static void mux_chr_accept_input(CharDriverState *chr) 744 + static void mux_chr_accept_input(Chardev *chr) 687 745 { 688 - MuxDriver *d = chr->opaque; 746 + MuxChardev *d = MUX_CHARDEV(chr); 689 747 int m = d->focus; 690 748 CharBackend *be = d->backends[m]; 691 749 ··· 698 756 699 757 static int mux_chr_can_read(void *opaque) 700 758 { 701 - CharDriverState *chr = opaque; 702 - MuxDriver *d = chr->opaque; 759 + MuxChardev *d = MUX_CHARDEV(opaque); 703 760 int m = d->focus; 704 761 CharBackend *be = d->backends[m]; 705 762 ··· 716 773 717 774 static void mux_chr_read(void *opaque, const uint8_t *buf, int size) 718 775 { 719 - CharDriverState *chr = opaque; 720 - MuxDriver *d = chr->opaque; 776 + Chardev *chr = CHARDEV(opaque); 777 + MuxChardev *d = MUX_CHARDEV(opaque); 721 778 int m = d->focus; 722 779 CharBackend *be = d->backends[m]; 723 780 int i; ··· 739 796 740 797 static void mux_chr_event(void *opaque, int event) 741 798 { 742 - CharDriverState *chr = opaque; 743 - MuxDriver *d = chr->opaque; 799 + MuxChardev *d = MUX_CHARDEV(opaque); 744 800 int i; 745 801 746 802 if (!muxes_realized) { ··· 766 822 */ 767 823 static void muxes_realize_done(Notifier *notifier, void *unused) 768 824 { 769 - CharDriverState *chr; 825 + Chardev *chr; 770 826 771 827 QTAILQ_FOREACH(chr, &chardevs, next) { 772 - if (chr->is_mux) { 773 - MuxDriver *d = chr->opaque; 828 + if (CHARDEV_IS_MUX(chr)) { 829 + MuxChardev *d = MUX_CHARDEV(chr); 774 830 int i; 775 831 776 832 /* send OPENED to all already-attached FEs */ ··· 790 846 .notify = muxes_realize_done, 791 847 }; 792 848 793 - static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) 849 + static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond) 794 850 { 795 - MuxDriver *d = s->opaque; 796 - CharDriverState *chr = qemu_chr_fe_get_driver(&d->chr); 851 + MuxChardev *d = MUX_CHARDEV(s); 852 + Chardev *chr = qemu_chr_fe_get_driver(&d->chr); 853 + ChardevClass *cc = CHARDEV_GET_CLASS(chr); 854 + 855 + if (!cc->chr_add_watch) { 856 + return NULL; 857 + } 797 858 798 - return chr->chr_add_watch(chr, cond); 859 + return cc->chr_add_watch(chr, cond); 799 860 } 800 861 801 - static void mux_chr_free(struct CharDriverState *chr) 862 + static void mux_chr_free(struct Chardev *chr) 802 863 { 803 - MuxDriver *d = chr->opaque; 864 + MuxChardev *d = MUX_CHARDEV(chr); 804 865 int i; 805 866 806 867 for (i = 0; i < d->mux_cnt; i++) { ··· 810 871 } 811 872 } 812 873 qemu_chr_fe_deinit(&d->chr); 813 - g_free(d); 814 874 } 815 875 816 - static void mux_chr_set_handlers(CharDriverState *chr, GMainContext *context) 876 + static void mux_chr_set_handlers(Chardev *chr, GMainContext *context) 817 877 { 818 - MuxDriver *d = chr->opaque; 878 + MuxChardev *d = MUX_CHARDEV(chr); 819 879 820 880 /* Fix up the real driver with mux routines */ 821 881 qemu_chr_fe_set_handlers(&d->chr, ··· 826 886 context, true); 827 887 } 828 888 829 - static void mux_set_focus(CharDriverState *chr, int focus) 889 + static void mux_set_focus(Chardev *chr, int focus) 830 890 { 831 - MuxDriver *d = chr->opaque; 891 + MuxChardev *d = MUX_CHARDEV(chr); 832 892 833 893 assert(focus >= 0); 834 894 assert(focus < d->mux_cnt); ··· 842 902 mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN); 843 903 } 844 904 845 - static CharDriverState *qemu_chr_open_mux(const char *id, 846 - ChardevBackend *backend, 847 - ChardevReturn *ret, 848 - bool *be_opened, 849 - Error **errp) 905 + static void qemu_chr_open_mux(Chardev *chr, 906 + ChardevBackend *backend, 907 + bool *be_opened, 908 + Error **errp) 850 909 { 851 910 ChardevMux *mux = backend->u.mux.data; 852 - CharDriverState *chr, *drv; 853 - MuxDriver *d; 854 - ChardevCommon *common = qapi_ChardevMux_base(mux); 911 + Chardev *drv; 912 + MuxChardev *d = MUX_CHARDEV(chr); 855 913 856 914 drv = qemu_chr_find(mux->chardev); 857 915 if (drv == NULL) { 858 916 error_setg(errp, "mux: base chardev %s not found", mux->chardev); 859 - return NULL; 917 + return; 860 918 } 861 919 862 - chr = qemu_chr_alloc(common, errp); 863 - if (!chr) { 864 - return NULL; 865 - } 866 - d = g_new0(MuxDriver, 1); 867 - 868 - chr->opaque = d; 869 920 d->focus = -1; 870 - chr->chr_free = mux_chr_free; 871 - chr->chr_write = mux_chr_write; 872 - chr->chr_accept_input = mux_chr_accept_input; 873 - /* Frontend guest-open / -close notification is not support with muxes */ 874 - chr->chr_set_fe_open = NULL; 875 - if (drv->chr_add_watch) { 876 - chr->chr_add_watch = mux_chr_add_watch; 877 - } 878 921 /* only default to opened state if we've realized the initial 879 922 * set of muxes 880 923 */ 881 924 *be_opened = muxes_realized; 882 - chr->is_mux = 1; 883 - if (!qemu_chr_fe_init(&d->chr, drv, errp)) { 884 - qemu_chr_free(chr); 885 - return NULL; 886 - } 887 - 888 - return chr; 925 + qemu_chr_fe_init(&d->chr, drv, errp); 889 926 } 890 927 891 - CharDriverState *qemu_chr_fe_get_driver(CharBackend *be) 928 + Chardev *qemu_chr_fe_get_driver(CharBackend *be) 892 929 { 893 930 return be->chr; 894 931 } 895 932 896 - bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp) 933 + bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp) 897 934 { 898 935 int tag = 0; 899 936 900 - if (s->is_mux) { 901 - MuxDriver *d = s->opaque; 937 + if (CHARDEV_IS_MUX(s)) { 938 + MuxChardev *d = MUX_CHARDEV(s); 902 939 903 940 if (d->mux_cnt >= MAX_MUX) { 904 941 goto unavailable; ··· 922 959 return false; 923 960 } 924 961 925 - static bool qemu_chr_is_busy(CharDriverState *s) 962 + static bool qemu_chr_is_busy(Chardev *s) 926 963 { 927 - if (s->is_mux) { 928 - MuxDriver *d = s->opaque; 964 + if (CHARDEV_IS_MUX(s)) { 965 + MuxChardev *d = MUX_CHARDEV(s); 929 966 return d->mux_cnt >= 0; 930 967 } else { 931 968 return s->be != NULL; ··· 941 978 if (b->chr->be == b) { 942 979 b->chr->be = NULL; 943 980 } 944 - if (b->chr->is_mux) { 945 - MuxDriver *d = b->chr->opaque; 981 + if (CHARDEV_IS_MUX(b->chr)) { 982 + MuxChardev *d = MUX_CHARDEV(b->chr); 946 983 d->backends[b->tag] = NULL; 947 984 } 948 985 b->chr = NULL; ··· 957 994 GMainContext *context, 958 995 bool set_open) 959 996 { 960 - CharDriverState *s; 997 + Chardev *s; 998 + ChardevClass *cc; 961 999 int fe_open; 962 1000 963 1001 s = b->chr; ··· 965 1003 return; 966 1004 } 967 1005 1006 + cc = CHARDEV_GET_CLASS(s); 968 1007 if (!opaque && !fd_can_read && !fd_read && !fd_event) { 969 1008 fe_open = 0; 970 1009 remove_fd_in_watch(s); ··· 975 1014 b->chr_read = fd_read; 976 1015 b->chr_event = fd_event; 977 1016 b->opaque = opaque; 978 - if (s->chr_update_read_handler) { 979 - s->chr_update_read_handler(s, context); 1017 + if (cc->chr_update_read_handler) { 1018 + cc->chr_update_read_handler(s, context); 980 1019 } 981 1020 982 1021 if (set_open) { ··· 992 1031 } 993 1032 } 994 1033 995 - if (s->is_mux) { 1034 + if (CHARDEV_IS_MUX(s)) { 996 1035 mux_chr_set_handlers(s, context); 997 1036 } 998 1037 } ··· 1003 1042 return; 1004 1043 } 1005 1044 1006 - if (b->chr->is_mux) { 1045 + if (CHARDEV_IS_MUX(b->chr)) { 1007 1046 mux_set_focus(b->chr, b->tag); 1008 1047 } 1009 1048 } ··· 1084 1123 }; 1085 1124 1086 1125 /* Can only be used for read */ 1087 - static guint io_add_watch_poll(CharDriverState *chr, 1126 + static guint io_add_watch_poll(Chardev *chr, 1088 1127 QIOChannel *ioc, 1089 1128 IOCanReadHandler *fd_can_read, 1090 1129 QIOChannelFunc fd_read, ··· 1132 1171 g_source_destroy(&iwp->parent); 1133 1172 } 1134 1173 1135 - static void remove_fd_in_watch(CharDriverState *chr) 1174 + static void remove_fd_in_watch(Chardev *chr) 1136 1175 { 1137 1176 if (chr->fd_in_tag) { 1138 1177 io_remove_watch_poll(chr->fd_in_tag); ··· 1180 1219 return io_channel_send_full(ioc, buf, len, NULL, 0); 1181 1220 } 1182 1221 1183 - 1184 - typedef struct FDCharDriver { 1185 - CharDriverState *chr; 1222 + typedef struct FDChardev { 1223 + Chardev parent; 1224 + Chardev *chr; 1186 1225 QIOChannel *ioc_in, *ioc_out; 1187 1226 int max_size; 1188 - } FDCharDriver; 1227 + } FDChardev; 1228 + 1229 + #define TYPE_CHARDEV_FD "chardev-fd" 1230 + #define FD_CHARDEV(obj) OBJECT_CHECK(FDChardev, (obj), TYPE_CHARDEV_FD) 1189 1231 1190 1232 /* Called with chr_write_lock held. */ 1191 - static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 1233 + static int fd_chr_write(Chardev *chr, const uint8_t *buf, int len) 1192 1234 { 1193 - FDCharDriver *s = chr->opaque; 1194 - 1235 + FDChardev *s = FD_CHARDEV(chr); 1236 + 1195 1237 return io_channel_send(s->ioc_out, buf, len); 1196 1238 } 1197 1239 1198 1240 static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) 1199 1241 { 1200 - CharDriverState *chr = opaque; 1201 - FDCharDriver *s = chr->opaque; 1242 + Chardev *chr = CHARDEV(opaque); 1243 + FDChardev *s = FD_CHARDEV(opaque); 1202 1244 int len; 1203 1245 uint8_t buf[READ_BUF_LEN]; 1204 1246 ssize_t ret; ··· 1227 1269 1228 1270 static int fd_chr_read_poll(void *opaque) 1229 1271 { 1230 - CharDriverState *chr = opaque; 1231 - FDCharDriver *s = chr->opaque; 1272 + Chardev *chr = CHARDEV(opaque); 1273 + FDChardev *s = FD_CHARDEV(opaque); 1232 1274 1233 1275 s->max_size = qemu_chr_be_can_write(chr); 1234 1276 return s->max_size; 1235 1277 } 1236 1278 1237 - static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond) 1279 + static GSource *fd_chr_add_watch(Chardev *chr, GIOCondition cond) 1238 1280 { 1239 - FDCharDriver *s = chr->opaque; 1281 + FDChardev *s = FD_CHARDEV(chr); 1240 1282 return qio_channel_create_watch(s->ioc_out, cond); 1241 1283 } 1242 1284 1243 - static void fd_chr_update_read_handler(CharDriverState *chr, 1285 + static void fd_chr_update_read_handler(Chardev *chr, 1244 1286 GMainContext *context) 1245 1287 { 1246 - FDCharDriver *s = chr->opaque; 1288 + FDChardev *s = FD_CHARDEV(chr); 1247 1289 1248 1290 remove_fd_in_watch(chr); 1249 1291 if (s->ioc_in) { ··· 1254 1296 } 1255 1297 } 1256 1298 1257 - static void fd_chr_free(struct CharDriverState *chr) 1299 + static void fd_chr_free(struct Chardev *chr) 1258 1300 { 1259 - FDCharDriver *s = chr->opaque; 1301 + FDChardev *s = FD_CHARDEV(chr); 1260 1302 1261 1303 remove_fd_in_watch(chr); 1262 1304 if (s->ioc_in) { ··· 1266 1308 object_unref(OBJECT(s->ioc_out)); 1267 1309 } 1268 1310 1269 - g_free(s); 1270 1311 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 1271 1312 } 1272 1313 1273 1314 /* open a character device to a unix fd */ 1274 - static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out, 1275 - ChardevCommon *backend, Error **errp) 1315 + static void qemu_chr_open_fd(Chardev *chr, 1316 + int fd_in, int fd_out) 1276 1317 { 1277 - CharDriverState *chr; 1278 - FDCharDriver *s; 1318 + FDChardev *s = FD_CHARDEV(chr); 1279 1319 char *name; 1280 1320 1281 - chr = qemu_chr_alloc(backend, errp); 1282 - if (!chr) { 1283 - return NULL; 1284 - } 1285 - s = g_new0(FDCharDriver, 1); 1286 1321 s->ioc_in = QIO_CHANNEL(qio_channel_file_new_fd(fd_in)); 1287 1322 name = g_strdup_printf("chardev-file-in-%s", chr->label); 1288 1323 qio_channel_set_name(QIO_CHANNEL(s->ioc_in), name); ··· 1293 1328 g_free(name); 1294 1329 qemu_set_nonblock(fd_out); 1295 1330 s->chr = chr; 1296 - chr->opaque = s; 1297 - chr->chr_add_watch = fd_chr_add_watch; 1298 - chr->chr_write = fd_chr_write; 1299 - chr->chr_update_read_handler = fd_chr_update_read_handler; 1300 - chr->chr_free = fd_chr_free; 1331 + } 1332 + 1333 + static void char_fd_class_init(ObjectClass *oc, void *data) 1334 + { 1335 + ChardevClass *cc = CHARDEV_CLASS(oc); 1301 1336 1302 - return chr; 1337 + cc->chr_add_watch = fd_chr_add_watch; 1338 + cc->chr_write = fd_chr_write; 1339 + cc->chr_update_read_handler = fd_chr_update_read_handler; 1340 + cc->chr_free = fd_chr_free; 1303 1341 } 1304 1342 1305 - static CharDriverState *qemu_chr_open_pipe(const char *id, 1306 - ChardevBackend *backend, 1307 - ChardevReturn *ret, 1308 - bool *be_opened, 1309 - Error **errp) 1343 + static const TypeInfo char_fd_type_info = { 1344 + .name = TYPE_CHARDEV_FD, 1345 + .parent = TYPE_CHARDEV, 1346 + .instance_size = sizeof(FDChardev), 1347 + .class_init = char_fd_class_init, 1348 + .abstract = true, 1349 + }; 1350 + 1351 + static void qemu_chr_open_pipe(Chardev *chr, 1352 + ChardevBackend *backend, 1353 + bool *be_opened, 1354 + Error **errp) 1310 1355 { 1311 1356 ChardevHostdev *opts = backend->u.pipe.data; 1312 1357 int fd_in, fd_out; 1313 1358 char *filename_in; 1314 1359 char *filename_out; 1315 1360 const char *filename = opts->device; 1316 - ChardevCommon *common = qapi_ChardevHostdev_base(opts); 1317 - 1318 1361 1319 1362 filename_in = g_strdup_printf("%s.in", filename); 1320 1363 filename_out = g_strdup_printf("%s.out", filename); ··· 1330 1373 TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY)); 1331 1374 if (fd_in < 0) { 1332 1375 error_setg_file_open(errp, errno, filename); 1333 - return NULL; 1376 + return; 1334 1377 } 1335 1378 } 1336 - return qemu_chr_open_fd(fd_in, fd_out, common, errp); 1379 + qemu_chr_open_fd(chr, fd_in, fd_out); 1337 1380 } 1338 1381 1339 1382 /* init terminal so that we can grab keys */ ··· 1343 1386 static bool stdio_allow_signal; 1344 1387 static bool stdio_echo_state; 1345 1388 1346 - static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo); 1389 + static void qemu_chr_set_echo_stdio(Chardev *chr, bool echo); 1347 1390 1348 1391 static void term_exit(void) 1349 1392 { ··· 1357 1400 qemu_chr_set_echo_stdio(NULL, stdio_echo_state); 1358 1401 } 1359 1402 1360 - static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo) 1403 + static void qemu_chr_set_echo_stdio(Chardev *chr, bool echo) 1361 1404 { 1362 1405 struct termios tty; 1363 1406 ··· 1379 1422 tcsetattr (0, TCSANOW, &tty); 1380 1423 } 1381 1424 1382 - static void qemu_chr_free_stdio(struct CharDriverState *chr) 1425 + static void qemu_chr_free_stdio(struct Chardev *chr) 1383 1426 { 1384 1427 term_exit(); 1385 1428 fd_chr_free(chr); 1386 1429 } 1387 1430 1388 - static CharDriverState *qemu_chr_open_stdio(const char *id, 1389 - ChardevBackend *backend, 1390 - ChardevReturn *ret, 1391 - bool *be_opened, 1392 - Error **errp) 1431 + static void qemu_chr_open_stdio(Chardev *chr, 1432 + ChardevBackend *backend, 1433 + bool *be_opened, 1434 + Error **errp) 1393 1435 { 1394 1436 ChardevStdio *opts = backend->u.stdio.data; 1395 - CharDriverState *chr; 1396 1437 struct sigaction act; 1397 - ChardevCommon *common = qapi_ChardevStdio_base(opts); 1398 1438 1399 1439 if (is_daemonized()) { 1400 1440 error_setg(errp, "cannot use stdio with -daemonize"); 1401 - return NULL; 1441 + return; 1402 1442 } 1403 1443 1404 1444 if (stdio_in_use) { 1405 1445 error_setg(errp, "cannot use stdio by multiple character devices"); 1406 - return NULL; 1446 + return; 1407 1447 } 1408 1448 1409 1449 stdio_in_use = true; ··· 1416 1456 act.sa_handler = term_stdio_handler; 1417 1457 sigaction(SIGCONT, &act, NULL); 1418 1458 1419 - chr = qemu_chr_open_fd(0, 1, common, errp); 1420 - if (!chr) { 1421 - return NULL; 1422 - } 1423 - chr->chr_free = qemu_chr_free_stdio; 1424 - chr->chr_set_echo = qemu_chr_set_echo_stdio; 1459 + qemu_chr_open_fd(chr, 0, 1); 1460 + 1425 1461 if (opts->has_signal) { 1426 1462 stdio_allow_signal = opts->signal; 1427 1463 } 1428 1464 qemu_chr_set_echo_stdio(chr, false); 1429 - 1430 - return chr; 1431 1465 } 1432 1466 1433 1467 #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \ ··· 1438 1472 #define HAVE_CHARDEV_PTY 1 1439 1473 1440 1474 typedef struct { 1475 + Chardev parent; 1441 1476 QIOChannel *ioc; 1442 1477 int read_bytes; 1443 1478 1444 - /* Protected by the CharDriverState chr_write_lock. */ 1479 + /* Protected by the Chardev chr_write_lock. */ 1445 1480 int connected; 1446 1481 guint timer_tag; 1447 1482 guint open_tag; 1448 - } PtyCharDriver; 1483 + } PtyChardev; 1449 1484 1450 - static void pty_chr_update_read_handler_locked(CharDriverState *chr); 1451 - static void pty_chr_state(CharDriverState *chr, int connected); 1485 + #define PTY_CHARDEV(obj) OBJECT_CHECK(PtyChardev, (obj), TYPE_CHARDEV_PTY) 1486 + 1487 + static void pty_chr_update_read_handler_locked(Chardev *chr); 1488 + static void pty_chr_state(Chardev *chr, int connected); 1452 1489 1453 1490 static gboolean pty_chr_timer(gpointer opaque) 1454 1491 { 1455 - struct CharDriverState *chr = opaque; 1456 - PtyCharDriver *s = chr->opaque; 1492 + struct Chardev *chr = CHARDEV(opaque); 1493 + PtyChardev *s = PTY_CHARDEV(opaque); 1457 1494 1458 1495 qemu_mutex_lock(&chr->chr_write_lock); 1459 1496 s->timer_tag = 0; ··· 1467 1504 } 1468 1505 1469 1506 /* Called with chr_write_lock held. */ 1470 - static void pty_chr_rearm_timer(CharDriverState *chr, int ms) 1507 + static void pty_chr_rearm_timer(Chardev *chr, int ms) 1471 1508 { 1472 - PtyCharDriver *s = chr->opaque; 1509 + PtyChardev *s = PTY_CHARDEV(chr); 1473 1510 char *name; 1474 1511 1475 1512 if (s->timer_tag) { ··· 1489 1526 } 1490 1527 1491 1528 /* Called with chr_write_lock held. */ 1492 - static void pty_chr_update_read_handler_locked(CharDriverState *chr) 1529 + static void pty_chr_update_read_handler_locked(Chardev *chr) 1493 1530 { 1494 - PtyCharDriver *s = chr->opaque; 1531 + PtyChardev *s = PTY_CHARDEV(chr); 1495 1532 GPollFD pfd; 1496 1533 int rc; 1497 1534 QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc); ··· 1511 1548 } 1512 1549 } 1513 1550 1514 - static void pty_chr_update_read_handler(CharDriverState *chr, 1551 + static void pty_chr_update_read_handler(Chardev *chr, 1515 1552 GMainContext *context) 1516 1553 { 1517 1554 qemu_mutex_lock(&chr->chr_write_lock); ··· 1520 1557 } 1521 1558 1522 1559 /* Called with chr_write_lock held. */ 1523 - static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 1560 + static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len) 1524 1561 { 1525 - PtyCharDriver *s = chr->opaque; 1562 + PtyChardev *s = PTY_CHARDEV(chr); 1526 1563 1527 1564 if (!s->connected) { 1528 1565 /* guest sends data, check for (re-)connect */ ··· 1534 1571 return io_channel_send(s->ioc, buf, len); 1535 1572 } 1536 1573 1537 - static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond) 1574 + static GSource *pty_chr_add_watch(Chardev *chr, GIOCondition cond) 1538 1575 { 1539 - PtyCharDriver *s = chr->opaque; 1576 + PtyChardev *s = PTY_CHARDEV(chr); 1540 1577 if (!s->connected) { 1541 1578 return NULL; 1542 1579 } ··· 1545 1582 1546 1583 static int pty_chr_read_poll(void *opaque) 1547 1584 { 1548 - CharDriverState *chr = opaque; 1549 - PtyCharDriver *s = chr->opaque; 1585 + Chardev *chr = CHARDEV(opaque); 1586 + PtyChardev *s = PTY_CHARDEV(opaque); 1550 1587 1551 1588 s->read_bytes = qemu_chr_be_can_write(chr); 1552 1589 return s->read_bytes; ··· 1554 1591 1555 1592 static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) 1556 1593 { 1557 - CharDriverState *chr = opaque; 1558 - PtyCharDriver *s = chr->opaque; 1594 + Chardev *chr = CHARDEV(opaque); 1595 + PtyChardev *s = PTY_CHARDEV(opaque); 1559 1596 gsize len; 1560 1597 uint8_t buf[READ_BUF_LEN]; 1561 1598 ssize_t ret; ··· 1579 1616 1580 1617 static gboolean qemu_chr_be_generic_open_func(gpointer opaque) 1581 1618 { 1582 - CharDriverState *chr = opaque; 1583 - PtyCharDriver *s = chr->opaque; 1619 + Chardev *chr = CHARDEV(opaque); 1620 + PtyChardev *s = PTY_CHARDEV(opaque); 1584 1621 1585 1622 s->open_tag = 0; 1586 1623 qemu_chr_be_generic_open(chr); ··· 1588 1625 } 1589 1626 1590 1627 /* Called with chr_write_lock held. */ 1591 - static void pty_chr_state(CharDriverState *chr, int connected) 1628 + static void pty_chr_state(Chardev *chr, int connected) 1592 1629 { 1593 - PtyCharDriver *s = chr->opaque; 1630 + PtyChardev *s = PTY_CHARDEV(chr); 1594 1631 1595 1632 if (!connected) { 1596 1633 if (s->open_tag) { ··· 1622 1659 } 1623 1660 } 1624 1661 1625 - static void pty_chr_free(struct CharDriverState *chr) 1662 + static void pty_chr_free(struct Chardev *chr) 1626 1663 { 1627 - PtyCharDriver *s = chr->opaque; 1664 + PtyChardev *s = PTY_CHARDEV(chr); 1628 1665 1629 1666 qemu_mutex_lock(&chr->chr_write_lock); 1630 1667 pty_chr_state(chr, 0); ··· 1634 1671 s->timer_tag = 0; 1635 1672 } 1636 1673 qemu_mutex_unlock(&chr->chr_write_lock); 1637 - g_free(s); 1638 1674 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 1639 1675 } 1640 1676 1641 - static CharDriverState *qemu_chr_open_pty(const char *id, 1642 - ChardevBackend *backend, 1643 - ChardevReturn *ret, 1644 - bool *be_opened, 1645 - Error **errp) 1677 + static void char_pty_open(Chardev *chr, 1678 + ChardevBackend *backend, 1679 + bool *be_opened, 1680 + Error **errp) 1646 1681 { 1647 - CharDriverState *chr; 1648 - PtyCharDriver *s; 1682 + PtyChardev *s; 1649 1683 int master_fd, slave_fd; 1650 1684 char pty_name[PATH_MAX]; 1651 - ChardevCommon *common = backend->u.pty.data; 1652 1685 char *name; 1653 1686 1654 1687 master_fd = qemu_openpty_raw(&slave_fd, pty_name); 1655 1688 if (master_fd < 0) { 1656 1689 error_setg_errno(errp, errno, "Failed to create PTY"); 1657 - return NULL; 1690 + return; 1658 1691 } 1659 1692 1660 1693 close(slave_fd); 1661 1694 qemu_set_nonblock(master_fd); 1662 1695 1663 - chr = qemu_chr_alloc(common, errp); 1664 - if (!chr) { 1665 - close(master_fd); 1666 - return NULL; 1667 - } 1668 - 1669 1696 chr->filename = g_strdup_printf("pty:%s", pty_name); 1670 - ret->pty = g_strdup(pty_name); 1671 - ret->has_pty = true; 1672 - 1673 - fprintf(stderr, "char device redirected to %s (label %s)\n", 1674 - pty_name, id); 1675 - 1676 - s = g_new0(PtyCharDriver, 1); 1677 - chr->opaque = s; 1678 - chr->chr_write = pty_chr_write; 1679 - chr->chr_update_read_handler = pty_chr_update_read_handler; 1680 - chr->chr_free = pty_chr_free; 1681 - chr->chr_add_watch = pty_chr_add_watch; 1682 - *be_opened = false; 1697 + error_report("char device redirected to %s (label %s)", 1698 + pty_name, chr->label); 1683 1699 1700 + s = PTY_CHARDEV(chr); 1684 1701 s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd)); 1685 1702 name = g_strdup_printf("chardev-pty-%s", chr->label); 1686 1703 qio_channel_set_name(QIO_CHANNEL(s->ioc), name); 1687 1704 g_free(name); 1688 1705 s->timer_tag = 0; 1706 + *be_opened = false; 1707 + } 1689 1708 1690 - return chr; 1709 + static const CharDriver pty_driver = { 1710 + .kind = CHARDEV_BACKEND_KIND_PTY, 1711 + }; 1712 + 1713 + static void char_pty_class_init(ObjectClass *oc, void *data) 1714 + { 1715 + ChardevClass *cc = CHARDEV_CLASS(oc); 1716 + 1717 + cc->open = char_pty_open; 1718 + cc->chr_write = char_pty_chr_write; 1719 + cc->chr_update_read_handler = pty_chr_update_read_handler; 1720 + cc->chr_add_watch = pty_chr_add_watch; 1721 + cc->chr_free = pty_chr_free; 1691 1722 } 1692 1723 1724 + static const TypeInfo char_pty_type_info = { 1725 + .name = TYPE_CHARDEV_PTY, 1726 + .parent = TYPE_CHARDEV, 1727 + .instance_size = sizeof(PtyChardev), 1728 + .class_init = char_pty_class_init, 1729 + }; 1730 + 1693 1731 static void tty_serial_init(int fd, int speed, 1694 1732 int parity, int data_bits, int stop_bits) 1695 1733 { ··· 1805 1843 tcsetattr (fd, TCSANOW, &tty); 1806 1844 } 1807 1845 1808 - static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) 1846 + static int tty_serial_ioctl(Chardev *chr, int cmd, void *arg) 1809 1847 { 1810 - FDCharDriver *s = chr->opaque; 1848 + FDChardev *s = FD_CHARDEV(chr); 1811 1849 QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc_in); 1812 1850 1813 1851 switch(cmd) { ··· 1875 1913 return 0; 1876 1914 } 1877 1915 1878 - static void qemu_chr_free_tty(CharDriverState *chr) 1916 + static void qemu_chr_free_tty(Chardev *chr) 1879 1917 { 1880 1918 fd_chr_free(chr); 1881 1919 } 1882 - 1883 - static CharDriverState *qemu_chr_open_tty_fd(int fd, 1884 - ChardevCommon *backend, 1885 - bool *be_opened, 1886 - Error **errp) 1887 - { 1888 - CharDriverState *chr; 1889 - 1890 - tty_serial_init(fd, 115200, 'N', 8, 1); 1891 - chr = qemu_chr_open_fd(fd, fd, backend, errp); 1892 - if (!chr) { 1893 - return NULL; 1894 - } 1895 - chr->chr_ioctl = tty_serial_ioctl; 1896 - chr->chr_free = qemu_chr_free_tty; 1897 - return chr; 1898 - } 1899 1920 #endif /* __linux__ || __sun__ */ 1900 1921 1901 1922 #if defined(__linux__) ··· 1903 1924 #define HAVE_CHARDEV_PARPORT 1 1904 1925 1905 1926 typedef struct { 1927 + Chardev parent; 1906 1928 int fd; 1907 1929 int mode; 1908 - } ParallelCharDriver; 1930 + } ParallelChardev; 1909 1931 1910 - static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode) 1932 + #define PARALLEL_CHARDEV(obj) \ 1933 + OBJECT_CHECK(ParallelChardev, (obj), TYPE_CHARDEV_PARALLEL) 1934 + 1935 + static int pp_hw_mode(ParallelChardev *s, uint16_t mode) 1911 1936 { 1912 1937 if (s->mode != mode) { 1913 1938 int m = mode; ··· 1918 1943 return 1; 1919 1944 } 1920 1945 1921 - static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) 1946 + static int pp_ioctl(Chardev *chr, int cmd, void *arg) 1922 1947 { 1923 - ParallelCharDriver *drv = chr->opaque; 1948 + ParallelChardev *drv = PARALLEL_CHARDEV(chr); 1924 1949 int fd = drv->fd; 1925 1950 uint8_t b; 1926 1951 ··· 1999 2024 return 0; 2000 2025 } 2001 2026 2002 - static void pp_free(CharDriverState *chr) 2027 + static void pp_free(Chardev *chr) 2003 2028 { 2004 - ParallelCharDriver *drv = chr->opaque; 2029 + ParallelChardev *drv = PARALLEL_CHARDEV(chr); 2005 2030 int fd = drv->fd; 2006 2031 2007 2032 pp_hw_mode(drv, IEEE1284_MODE_COMPAT); 2008 2033 ioctl(fd, PPRELEASE); 2009 2034 close(fd); 2010 - g_free(drv); 2011 2035 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 2012 2036 } 2013 2037 2014 - static CharDriverState *qemu_chr_open_pp_fd(int fd, 2015 - ChardevCommon *backend, 2016 - bool *be_opened, 2017 - Error **errp) 2038 + static void qemu_chr_open_pp_fd(Chardev *chr, 2039 + int fd, 2040 + bool *be_opened, 2041 + Error **errp) 2018 2042 { 2019 - CharDriverState *chr; 2020 - ParallelCharDriver *drv; 2043 + ParallelChardev *drv = PARALLEL_CHARDEV(chr); 2021 2044 2022 2045 if (ioctl(fd, PPCLAIM) < 0) { 2023 2046 error_setg_errno(errp, errno, "not a parallel port"); 2024 2047 close(fd); 2025 - return NULL; 2026 - } 2027 - 2028 - chr = qemu_chr_alloc(backend, errp); 2029 - if (!chr) { 2030 - return NULL; 2048 + return; 2031 2049 } 2032 2050 2033 - drv = g_new0(ParallelCharDriver, 1); 2034 - chr->opaque = drv; 2035 - chr->chr_write = null_chr_write; 2036 - chr->chr_ioctl = pp_ioctl; 2037 - chr->chr_free = pp_free; 2038 - 2039 2051 drv->fd = fd; 2040 2052 drv->mode = IEEE1284_MODE_COMPAT; 2041 - 2042 - return chr; 2043 2053 } 2044 2054 #endif /* __linux__ */ 2045 2055 ··· 2047 2057 2048 2058 #define HAVE_CHARDEV_PARPORT 1 2049 2059 2050 - static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) 2060 + typedef struct { 2061 + Chardev parent; 2062 + int fd; 2063 + } ParallelChardev; 2064 + 2065 + #define PARALLEL_CHARDEV(obj) \ 2066 + OBJECT_CHECK(ParallelChardev, (obj), TYPE_CHARDEV_PARALLEL) 2067 + 2068 + static int pp_ioctl(Chardev *chr, int cmd, void *arg) 2051 2069 { 2052 - int fd = (int)(intptr_t)chr->opaque; 2070 + ParallelChardev *drv = PARALLEL_CHARDEV(chr); 2053 2071 uint8_t b; 2054 2072 2055 - switch(cmd) { 2073 + switch (cmd) { 2056 2074 case CHR_IOCTL_PP_READ_DATA: 2057 - if (ioctl(fd, PPIGDATA, &b) < 0) 2075 + if (ioctl(drv->fd, PPIGDATA, &b) < 0) { 2058 2076 return -ENOTSUP; 2077 + } 2059 2078 *(uint8_t *)arg = b; 2060 2079 break; 2061 2080 case CHR_IOCTL_PP_WRITE_DATA: 2062 2081 b = *(uint8_t *)arg; 2063 - if (ioctl(fd, PPISDATA, &b) < 0) 2082 + if (ioctl(drv->fd, PPISDATA, &b) < 0) { 2064 2083 return -ENOTSUP; 2084 + } 2065 2085 break; 2066 2086 case CHR_IOCTL_PP_READ_CONTROL: 2067 - if (ioctl(fd, PPIGCTRL, &b) < 0) 2087 + if (ioctl(drv->fd, PPIGCTRL, &b) < 0) { 2068 2088 return -ENOTSUP; 2089 + } 2069 2090 *(uint8_t *)arg = b; 2070 2091 break; 2071 2092 case CHR_IOCTL_PP_WRITE_CONTROL: 2072 2093 b = *(uint8_t *)arg; 2073 - if (ioctl(fd, PPISCTRL, &b) < 0) 2094 + if (ioctl(drv->fd, PPISCTRL, &b) < 0) { 2074 2095 return -ENOTSUP; 2096 + } 2075 2097 break; 2076 2098 case CHR_IOCTL_PP_READ_STATUS: 2077 - if (ioctl(fd, PPIGSTATUS, &b) < 0) 2099 + if (ioctl(drv->fd, PPIGSTATUS, &b) < 0) { 2078 2100 return -ENOTSUP; 2101 + } 2079 2102 *(uint8_t *)arg = b; 2080 2103 break; 2081 2104 default: ··· 2084 2107 return 0; 2085 2108 } 2086 2109 2087 - static CharDriverState *qemu_chr_open_pp_fd(int fd, 2088 - ChardevCommon *backend, 2089 - bool *be_opened, 2090 - Error **errp) 2110 + static void qemu_chr_open_pp_fd(Chardev *chr, 2111 + int fd, 2112 + bool *be_opened, 2113 + Error **errp) 2091 2114 { 2092 - CharDriverState *chr; 2093 - 2094 - chr = qemu_chr_alloc(backend, errp); 2095 - if (!chr) { 2096 - return NULL; 2097 - } 2098 - chr->opaque = (void *)(intptr_t)fd; 2099 - chr->chr_write = null_chr_write; 2100 - chr->chr_ioctl = pp_ioctl; 2115 + ParallelChardev *drv = PARALLEL_CHARDEV(chr); 2116 + drv->fd = fd; 2101 2117 *be_opened = false; 2102 - return chr; 2103 2118 } 2104 2119 #endif 2105 2120 ··· 2108 2123 #define HAVE_CHARDEV_SERIAL 1 2109 2124 2110 2125 typedef struct { 2126 + Chardev parent; 2111 2127 int max_size; 2112 2128 HANDLE hcom, hrecv, hsend; 2113 2129 OVERLAPPED orecv; 2114 2130 BOOL fpipe; 2115 2131 DWORD len; 2116 2132 2117 - /* Protected by the CharDriverState chr_write_lock. */ 2133 + /* Protected by the Chardev chr_write_lock. */ 2118 2134 OVERLAPPED osend; 2119 - } WinCharState; 2135 + } WinChardev; 2136 + 2137 + #define TYPE_CHARDEV_WIN "chardev-win" 2138 + #define WIN_CHARDEV(obj) OBJECT_CHECK(WinChardev, (obj), TYPE_CHARDEV_WIN) 2120 2139 2121 2140 typedef struct { 2141 + Chardev parent; 2122 2142 HANDLE hStdIn; 2123 2143 HANDLE hInputReadyEvent; 2124 2144 HANDLE hInputDoneEvent; 2125 2145 HANDLE hInputThread; 2126 2146 uint8_t win_stdio_buf; 2127 - } WinStdioCharState; 2147 + } WinStdioChardev; 2148 + 2149 + #define TYPE_CHARDEV_WIN_STDIO "chardev-win-stdio" 2150 + #define WIN_STDIO_CHARDEV(obj) \ 2151 + OBJECT_CHECK(WinStdioChardev, (obj), TYPE_CHARDEV_WIN_STDIO) 2128 2152 2129 2153 #define NSENDBUF 2048 2130 2154 #define NRECVBUF 2048 ··· 2134 2158 static int win_chr_poll(void *opaque); 2135 2159 static int win_chr_pipe_poll(void *opaque); 2136 2160 2137 - static void win_chr_free(CharDriverState *chr) 2161 + static void win_chr_free(Chardev *chr) 2138 2162 { 2139 - WinCharState *s = chr->opaque; 2163 + WinChardev *s = WIN_CHARDEV(chr); 2140 2164 2141 2165 if (s->hsend) { 2142 2166 CloseHandle(s->hsend); ··· 2158 2182 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 2159 2183 } 2160 2184 2161 - static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp) 2185 + static int win_chr_init(Chardev *chr, const char *filename, Error **errp) 2162 2186 { 2163 - WinCharState *s = chr->opaque; 2187 + WinChardev *s = WIN_CHARDEV(chr); 2164 2188 COMMCONFIG comcfg; 2165 2189 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0}; 2166 2190 COMSTAT comstat; ··· 2226 2250 } 2227 2251 2228 2252 /* Called with chr_write_lock held. */ 2229 - static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1) 2253 + static int win_chr_write(Chardev *chr, const uint8_t *buf, int len1) 2230 2254 { 2231 - WinCharState *s = chr->opaque; 2255 + WinChardev *s = WIN_CHARDEV(chr); 2232 2256 DWORD len, ret, size, err; 2233 2257 2234 2258 len = len1; ··· 2260 2284 return len1 - len; 2261 2285 } 2262 2286 2263 - static int win_chr_read_poll(CharDriverState *chr) 2287 + static int win_chr_read_poll(Chardev *chr) 2264 2288 { 2265 - WinCharState *s = chr->opaque; 2289 + WinChardev *s = WIN_CHARDEV(chr); 2266 2290 2267 2291 s->max_size = qemu_chr_be_can_write(chr); 2268 2292 return s->max_size; 2269 2293 } 2270 2294 2271 - static void win_chr_readfile(CharDriverState *chr) 2295 + static void win_chr_readfile(Chardev *chr) 2272 2296 { 2273 - WinCharState *s = chr->opaque; 2297 + WinChardev *s = WIN_CHARDEV(chr); 2298 + 2274 2299 int ret, err; 2275 2300 uint8_t buf[READ_BUF_LEN]; 2276 2301 DWORD size; ··· 2290 2315 } 2291 2316 } 2292 2317 2293 - static void win_chr_read(CharDriverState *chr) 2318 + static void win_chr_read(Chardev *chr) 2294 2319 { 2295 - WinCharState *s = chr->opaque; 2320 + WinChardev *s = WIN_CHARDEV(chr); 2296 2321 2297 2322 if (s->len > s->max_size) 2298 2323 s->len = s->max_size; ··· 2304 2329 2305 2330 static int win_chr_poll(void *opaque) 2306 2331 { 2307 - CharDriverState *chr = opaque; 2308 - WinCharState *s = chr->opaque; 2332 + Chardev *chr = CHARDEV(opaque); 2333 + WinChardev *s = WIN_CHARDEV(opaque); 2309 2334 COMSTAT status; 2310 2335 DWORD comerr; 2311 2336 ··· 2319 2344 return 0; 2320 2345 } 2321 2346 2322 - static CharDriverState *qemu_chr_open_win_path(const char *filename, 2323 - ChardevCommon *backend, 2324 - Error **errp) 2325 - { 2326 - CharDriverState *chr; 2327 - WinCharState *s; 2328 - 2329 - chr = qemu_chr_alloc(backend, errp); 2330 - if (!chr) { 2331 - return NULL; 2332 - } 2333 - s = g_new0(WinCharState, 1); 2334 - chr->opaque = s; 2335 - chr->chr_write = win_chr_write; 2336 - chr->chr_free = win_chr_free; 2337 - 2338 - if (win_chr_init(chr, filename, errp) < 0) { 2339 - g_free(s); 2340 - qemu_chr_free_common(chr); 2341 - return NULL; 2342 - } 2343 - return chr; 2344 - } 2345 - 2346 2347 static int win_chr_pipe_poll(void *opaque) 2347 2348 { 2348 - CharDriverState *chr = opaque; 2349 - WinCharState *s = chr->opaque; 2349 + Chardev *chr = CHARDEV(opaque); 2350 + WinChardev *s = WIN_CHARDEV(opaque); 2350 2351 DWORD size; 2351 2352 2352 2353 PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL); ··· 2359 2360 return 0; 2360 2361 } 2361 2362 2362 - static int win_chr_pipe_init(CharDriverState *chr, const char *filename, 2363 + static int win_chr_pipe_init(Chardev *chr, const char *filename, 2363 2364 Error **errp) 2364 2365 { 2365 - WinCharState *s = chr->opaque; 2366 + WinChardev *s = WIN_CHARDEV(chr); 2366 2367 OVERLAPPED ov; 2367 2368 int ret; 2368 2369 DWORD size; ··· 2424 2425 } 2425 2426 2426 2427 2427 - static CharDriverState *qemu_chr_open_pipe(const char *id, 2428 - ChardevBackend *backend, 2429 - ChardevReturn *ret, 2430 - bool *be_opened, 2431 - Error **errp) 2428 + static void qemu_chr_open_pipe(Chardev *chr, 2429 + ChardevBackend *backend, 2430 + bool *be_opened, 2431 + Error **errp) 2432 2432 { 2433 2433 ChardevHostdev *opts = backend->u.pipe.data; 2434 2434 const char *filename = opts->device; 2435 - CharDriverState *chr; 2436 - WinCharState *s; 2437 - ChardevCommon *common = qapi_ChardevHostdev_base(opts); 2438 - 2439 - chr = qemu_chr_alloc(common, errp); 2440 - if (!chr) { 2441 - return NULL; 2442 - } 2443 - s = g_new0(WinCharState, 1); 2444 - chr->opaque = s; 2445 - chr->chr_write = win_chr_write; 2446 - chr->chr_free = win_chr_free; 2447 2435 2448 2436 if (win_chr_pipe_init(chr, filename, errp) < 0) { 2449 - g_free(s); 2450 - qemu_chr_free_common(chr); 2451 - return NULL; 2437 + return; 2452 2438 } 2453 - return chr; 2454 2439 } 2455 2440 2456 - static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out, 2457 - ChardevCommon *backend, 2458 - Error **errp) 2441 + static void qemu_chr_open_win_file(Chardev *chr, HANDLE fd_out) 2459 2442 { 2460 - CharDriverState *chr; 2461 - WinCharState *s; 2443 + WinChardev *s = WIN_CHARDEV(chr); 2462 2444 2463 - chr = qemu_chr_alloc(backend, errp); 2464 - if (!chr) { 2465 - return NULL; 2466 - } 2467 - s = g_new0(WinCharState, 1); 2468 2445 s->hcom = fd_out; 2469 - chr->opaque = s; 2470 - chr->chr_write = win_chr_write; 2471 - return chr; 2446 + } 2447 + 2448 + static void char_win_class_init(ObjectClass *oc, void *data) 2449 + { 2450 + ChardevClass *cc = CHARDEV_CLASS(oc); 2451 + 2452 + cc->chr_write = win_chr_write; 2453 + cc->chr_free = win_chr_free; 2454 + } 2455 + 2456 + static const TypeInfo char_win_type_info = { 2457 + .name = TYPE_CHARDEV_WIN, 2458 + .parent = TYPE_CHARDEV, 2459 + .instance_size = sizeof(WinChardev), 2460 + .class_init = char_win_class_init, 2461 + .abstract = true, 2462 + }; 2463 + 2464 + static void qemu_chr_open_win_con(Chardev *chr, 2465 + ChardevBackend *backend, 2466 + bool *be_opened, 2467 + Error **errp) 2468 + { 2469 + qemu_chr_open_win_file(chr, GetStdHandle(STD_OUTPUT_HANDLE)); 2472 2470 } 2473 2471 2474 - static CharDriverState *qemu_chr_open_win_con(const char *id, 2475 - ChardevBackend *backend, 2476 - ChardevReturn *ret, 2477 - bool *be_opened, 2478 - Error **errp) 2472 + static const CharDriver console_driver = { 2473 + .kind = CHARDEV_BACKEND_KIND_CONSOLE, 2474 + }; 2475 + 2476 + static void char_console_class_init(ObjectClass *oc, void *data) 2479 2477 { 2480 - ChardevCommon *common = backend->u.console.data; 2481 - return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), 2482 - common, errp); 2478 + ChardevClass *cc = CHARDEV_CLASS(oc); 2479 + 2480 + cc->open = qemu_chr_open_win_con; 2481 + cc->chr_free = NULL; 2483 2482 } 2484 2483 2485 - static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len) 2484 + static const TypeInfo char_console_type_info = { 2485 + .name = TYPE_CHARDEV_CONSOLE, 2486 + .parent = TYPE_CHARDEV_WIN, 2487 + .class_init = char_console_class_init, 2488 + }; 2489 + 2490 + static int win_stdio_write(Chardev *chr, const uint8_t *buf, int len) 2486 2491 { 2487 2492 HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 2488 2493 DWORD dwSize; ··· 2503 2508 2504 2509 static void win_stdio_wait_func(void *opaque) 2505 2510 { 2506 - CharDriverState *chr = opaque; 2507 - WinStdioCharState *stdio = chr->opaque; 2511 + Chardev *chr = CHARDEV(opaque); 2512 + WinStdioChardev *stdio = WIN_STDIO_CHARDEV(opaque); 2508 2513 INPUT_RECORD buf[4]; 2509 2514 int ret; 2510 2515 DWORD dwSize; ··· 2537 2542 2538 2543 static DWORD WINAPI win_stdio_thread(LPVOID param) 2539 2544 { 2540 - CharDriverState *chr = param; 2541 - WinStdioCharState *stdio = chr->opaque; 2545 + WinStdioChardev *stdio = WIN_STDIO_CHARDEV(param); 2542 2546 int ret; 2543 2547 DWORD dwSize; 2544 2548 ··· 2576 2580 2577 2581 static void win_stdio_thread_wait_func(void *opaque) 2578 2582 { 2579 - CharDriverState *chr = opaque; 2580 - WinStdioCharState *stdio = chr->opaque; 2583 + Chardev *chr = CHARDEV(opaque); 2584 + WinStdioChardev *stdio = WIN_STDIO_CHARDEV(opaque); 2581 2585 2582 2586 if (qemu_chr_be_can_write(chr)) { 2583 2587 qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1); ··· 2586 2590 SetEvent(stdio->hInputDoneEvent); 2587 2591 } 2588 2592 2589 - static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo) 2593 + static void qemu_chr_set_echo_win_stdio(Chardev *chr, bool echo) 2590 2594 { 2591 - WinStdioCharState *stdio = chr->opaque; 2595 + WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr); 2592 2596 DWORD dwMode = 0; 2593 2597 2594 2598 GetConsoleMode(stdio->hStdIn, &dwMode); ··· 2600 2604 } 2601 2605 } 2602 2606 2603 - static void win_stdio_free(CharDriverState *chr) 2607 + static void win_stdio_free(Chardev *chr) 2604 2608 { 2605 - WinStdioCharState *stdio = chr->opaque; 2609 + WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr); 2606 2610 2607 2611 if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) { 2608 2612 CloseHandle(stdio->hInputReadyEvent); ··· 2613 2617 if (stdio->hInputThread != INVALID_HANDLE_VALUE) { 2614 2618 TerminateThread(stdio->hInputThread, 0); 2615 2619 } 2616 - 2617 - g_free(chr->opaque); 2618 2620 } 2619 2621 2620 - static CharDriverState *qemu_chr_open_stdio(const char *id, 2621 - ChardevBackend *backend, 2622 - ChardevReturn *ret, 2623 - bool *be_opened, 2624 - Error **errp) 2622 + static const TypeInfo char_win_stdio_type_info = { 2623 + .name = TYPE_CHARDEV_WIN_STDIO, 2624 + .parent = TYPE_CHARDEV, 2625 + .instance_size = sizeof(WinStdioChardev), 2626 + .abstract = true, 2627 + }; 2628 + 2629 + static void qemu_chr_open_stdio(Chardev *chr, 2630 + ChardevBackend *backend, 2631 + bool *be_opened, 2632 + Error **errp) 2625 2633 { 2626 - CharDriverState *chr; 2627 - WinStdioCharState *stdio; 2634 + WinStdioChardev *stdio = WIN_STDIO_CHARDEV(chr); 2628 2635 DWORD dwMode; 2629 2636 int is_console = 0; 2630 - ChardevCommon *common = qapi_ChardevStdio_base(backend->u.stdio.data); 2631 - 2632 - chr = qemu_chr_alloc(common, errp); 2633 - if (!chr) { 2634 - return NULL; 2635 - } 2636 - stdio = g_new0(WinStdioCharState, 1); 2637 2637 2638 2638 stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); 2639 2639 if (stdio->hStdIn == INVALID_HANDLE_VALUE) { 2640 2640 error_setg(errp, "cannot open stdio: invalid handle"); 2641 - return NULL; 2641 + return; 2642 2642 } 2643 2643 2644 2644 is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; 2645 - 2646 - chr->opaque = stdio; 2647 - chr->chr_write = win_stdio_write; 2648 - chr->chr_free = win_stdio_free; 2649 2645 2650 2646 if (is_console) { 2651 2647 if (qemu_add_wait_object(stdio->hStdIn, ··· 2687 2683 2688 2684 SetConsoleMode(stdio->hStdIn, dwMode); 2689 2685 2690 - chr->chr_set_echo = qemu_chr_set_echo_win_stdio; 2691 2686 qemu_chr_set_echo_win_stdio(chr, false); 2692 2687 2693 - return chr; 2688 + return; 2694 2689 2695 2690 err3: 2696 2691 qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); ··· 2699 2694 CloseHandle(stdio->hInputDoneEvent); 2700 2695 err1: 2701 2696 qemu_del_wait_object(stdio->hStdIn, NULL, NULL); 2702 - return NULL; 2703 2697 } 2704 2698 #endif /* !_WIN32 */ 2705 2699 ··· 2707 2701 /* UDP Net console */ 2708 2702 2709 2703 typedef struct { 2704 + Chardev parent; 2710 2705 QIOChannel *ioc; 2711 2706 uint8_t buf[READ_BUF_LEN]; 2712 2707 int bufcnt; 2713 2708 int bufptr; 2714 2709 int max_size; 2715 - } NetCharDriver; 2710 + } UdpChardev; 2711 + 2712 + #define UDP_CHARDEV(obj) OBJECT_CHECK(UdpChardev, (obj), TYPE_CHARDEV_UDP) 2716 2713 2717 2714 /* Called with chr_write_lock held. */ 2718 - static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 2715 + static int udp_chr_write(Chardev *chr, const uint8_t *buf, int len) 2719 2716 { 2720 - NetCharDriver *s = chr->opaque; 2717 + UdpChardev *s = UDP_CHARDEV(chr); 2721 2718 2722 2719 return qio_channel_write( 2723 2720 s->ioc, (const char *)buf, len, NULL); ··· 2725 2722 2726 2723 static int udp_chr_read_poll(void *opaque) 2727 2724 { 2728 - CharDriverState *chr = opaque; 2729 - NetCharDriver *s = chr->opaque; 2725 + Chardev *chr = CHARDEV(opaque); 2726 + UdpChardev *s = UDP_CHARDEV(opaque); 2730 2727 2731 2728 s->max_size = qemu_chr_be_can_write(chr); 2732 2729 ··· 2743 2740 2744 2741 static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) 2745 2742 { 2746 - CharDriverState *chr = opaque; 2747 - NetCharDriver *s = chr->opaque; 2743 + Chardev *chr = CHARDEV(opaque); 2744 + UdpChardev *s = UDP_CHARDEV(opaque); 2748 2745 ssize_t ret; 2749 2746 2750 2747 if (s->max_size == 0) { ··· 2768 2765 return TRUE; 2769 2766 } 2770 2767 2771 - static void udp_chr_update_read_handler(CharDriverState *chr, 2768 + static void udp_chr_update_read_handler(Chardev *chr, 2772 2769 GMainContext *context) 2773 2770 { 2774 - NetCharDriver *s = chr->opaque; 2771 + UdpChardev *s = UDP_CHARDEV(chr); 2775 2772 2776 2773 remove_fd_in_watch(chr); 2777 2774 if (s->ioc) { ··· 2782 2779 } 2783 2780 } 2784 2781 2785 - static void udp_chr_free(CharDriverState *chr) 2782 + static void udp_chr_free(Chardev *chr) 2786 2783 { 2787 - NetCharDriver *s = chr->opaque; 2784 + UdpChardev *s = UDP_CHARDEV(chr); 2788 2785 2789 2786 remove_fd_in_watch(chr); 2790 2787 if (s->ioc) { 2791 2788 object_unref(OBJECT(s->ioc)); 2792 2789 } 2793 - g_free(s); 2794 2790 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 2795 2791 } 2796 2792 2797 - static CharDriverState *qemu_chr_open_udp(QIOChannelSocket *sioc, 2798 - ChardevCommon *backend, 2799 - bool *be_opened, 2800 - Error **errp) 2801 - { 2802 - CharDriverState *chr = NULL; 2803 - NetCharDriver *s = NULL; 2804 - 2805 - chr = qemu_chr_alloc(backend, errp); 2806 - if (!chr) { 2807 - return NULL; 2808 - } 2809 - s = g_new0(NetCharDriver, 1); 2810 - 2811 - s->ioc = QIO_CHANNEL(sioc); 2812 - s->bufcnt = 0; 2813 - s->bufptr = 0; 2814 - chr->opaque = s; 2815 - chr->chr_write = udp_chr_write; 2816 - chr->chr_update_read_handler = udp_chr_update_read_handler; 2817 - chr->chr_free = udp_chr_free; 2818 - /* be isn't opened until we get a connection */ 2819 - *be_opened = false; 2820 - return chr; 2821 - } 2822 - 2823 2793 /***********************************************************/ 2824 2794 /* TCP Net console */ 2825 2795 2826 2796 typedef struct { 2797 + Chardev parent; 2827 2798 QIOChannel *ioc; /* Client I/O channel */ 2828 2799 QIOChannelSocket *sioc; /* Client master channel */ 2829 2800 QIOChannelSocket *listen_ioc; ··· 2846 2817 guint reconnect_timer; 2847 2818 int64_t reconnect_time; 2848 2819 bool connect_err_reported; 2849 - } TCPCharDriver; 2820 + } SocketChardev; 2821 + 2822 + #define SOCKET_CHARDEV(obj) \ 2823 + OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET) 2850 2824 2851 2825 static gboolean socket_reconnect_timeout(gpointer opaque); 2852 2826 2853 - static void qemu_chr_socket_restart_timer(CharDriverState *chr) 2827 + static void qemu_chr_socket_restart_timer(Chardev *chr) 2854 2828 { 2855 - TCPCharDriver *s = chr->opaque; 2829 + SocketChardev *s = SOCKET_CHARDEV(chr); 2856 2830 char *name; 2831 + 2857 2832 assert(s->connected == 0); 2858 2833 s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time, 2859 2834 socket_reconnect_timeout, chr); ··· 2862 2837 g_free(name); 2863 2838 } 2864 2839 2865 - static void check_report_connect_error(CharDriverState *chr, 2840 + static void check_report_connect_error(Chardev *chr, 2866 2841 Error *err) 2867 2842 { 2868 - TCPCharDriver *s = chr->opaque; 2843 + SocketChardev *s = SOCKET_CHARDEV(chr); 2869 2844 2870 2845 if (!s->connect_err_reported) { 2871 2846 error_report("Unable to connect character device %s: %s", ··· 2880 2855 void *opaque); 2881 2856 2882 2857 /* Called with chr_write_lock held. */ 2883 - static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 2858 + static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len) 2884 2859 { 2885 - TCPCharDriver *s = chr->opaque; 2860 + SocketChardev *s = SOCKET_CHARDEV(chr); 2861 + 2886 2862 if (s->connected) { 2887 2863 int ret = io_channel_send_full(s->ioc, buf, len, 2888 2864 s->write_msgfds, ··· 2904 2880 2905 2881 static int tcp_chr_read_poll(void *opaque) 2906 2882 { 2907 - CharDriverState *chr = opaque; 2908 - TCPCharDriver *s = chr->opaque; 2883 + Chardev *chr = CHARDEV(opaque); 2884 + SocketChardev *s = SOCKET_CHARDEV(opaque); 2909 2885 if (!s->connected) 2910 2886 return 0; 2911 2887 s->max_size = qemu_chr_be_can_write(chr); ··· 2914 2890 2915 2891 #define IAC 255 2916 2892 #define IAC_BREAK 243 2917 - static void tcp_chr_process_IAC_bytes(CharDriverState *chr, 2918 - TCPCharDriver *s, 2893 + static void tcp_chr_process_IAC_bytes(Chardev *chr, 2894 + SocketChardev *s, 2919 2895 uint8_t *buf, int *size) 2920 2896 { 2921 2897 /* Handle any telnet client's basic IAC options to satisfy char by ··· 2962 2938 *size = j; 2963 2939 } 2964 2940 2965 - static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num) 2941 + static int tcp_get_msgfds(Chardev *chr, int *fds, int num) 2966 2942 { 2967 - TCPCharDriver *s = chr->opaque; 2943 + SocketChardev *s = SOCKET_CHARDEV(chr); 2944 + 2968 2945 int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num; 2969 2946 2970 2947 assert(num <= TCP_MAX_FDS); ··· 2987 2964 return to_copy; 2988 2965 } 2989 2966 2990 - static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num) 2967 + static int tcp_set_msgfds(Chardev *chr, int *fds, int num) 2991 2968 { 2992 - TCPCharDriver *s = chr->opaque; 2969 + SocketChardev *s = SOCKET_CHARDEV(chr); 2993 2970 2994 2971 /* clear old pending fd array */ 2995 2972 g_free(s->write_msgfds); ··· 3012 2989 return 0; 3013 2990 } 3014 2991 3015 - static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) 2992 + static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len) 3016 2993 { 3017 - TCPCharDriver *s = chr->opaque; 2994 + SocketChardev *s = SOCKET_CHARDEV(chr); 3018 2995 struct iovec iov = { .iov_base = buf, .iov_len = len }; 3019 2996 int ret; 3020 2997 size_t i; ··· 3069 3046 return ret; 3070 3047 } 3071 3048 3072 - static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond) 3049 + static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond) 3073 3050 { 3074 - TCPCharDriver *s = chr->opaque; 3051 + SocketChardev *s = SOCKET_CHARDEV(chr); 3075 3052 return qio_channel_create_watch(s->ioc, cond); 3076 3053 } 3077 3054 3078 - static void tcp_chr_free_connection(CharDriverState *chr) 3055 + static void tcp_chr_free_connection(Chardev *chr) 3079 3056 { 3080 - TCPCharDriver *s = chr->opaque; 3057 + SocketChardev *s = SOCKET_CHARDEV(chr); 3081 3058 int i; 3082 3059 3083 3060 if (!s->connected) { ··· 3104 3081 s->connected = 0; 3105 3082 } 3106 3083 3107 - static void tcp_chr_disconnect(CharDriverState *chr) 3084 + static void tcp_chr_disconnect(Chardev *chr) 3108 3085 { 3109 - TCPCharDriver *s = chr->opaque; 3086 + SocketChardev *s = SOCKET_CHARDEV(chr); 3110 3087 3111 3088 if (!s->connected) { 3112 3089 return; ··· 3128 3105 3129 3106 static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) 3130 3107 { 3131 - CharDriverState *chr = opaque; 3132 - TCPCharDriver *s = chr->opaque; 3108 + Chardev *chr = CHARDEV(opaque); 3109 + SocketChardev *s = SOCKET_CHARDEV(opaque); 3133 3110 uint8_t buf[READ_BUF_LEN]; 3134 3111 int len, size; 3135 3112 ··· 3153 3130 return TRUE; 3154 3131 } 3155 3132 3156 - static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len) 3133 + static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len) 3157 3134 { 3158 - TCPCharDriver *s = chr->opaque; 3135 + SocketChardev *s = SOCKET_CHARDEV(chr); 3159 3136 int size; 3160 3137 3161 3138 if (!s->connected) { ··· 3173 3150 3174 3151 static void tcp_chr_connect(void *opaque) 3175 3152 { 3176 - CharDriverState *chr = opaque; 3177 - TCPCharDriver *s = chr->opaque; 3153 + Chardev *chr = CHARDEV(opaque); 3154 + SocketChardev *s = SOCKET_CHARDEV(opaque); 3178 3155 3179 3156 g_free(chr->filename); 3180 3157 chr->filename = sockaddr_to_str( ··· 3192 3169 qemu_chr_be_generic_open(chr); 3193 3170 } 3194 3171 3195 - static void tcp_chr_update_read_handler(CharDriverState *chr, 3172 + static void tcp_chr_update_read_handler(Chardev *chr, 3196 3173 GMainContext *context) 3197 3174 { 3198 - TCPCharDriver *s = chr->opaque; 3175 + SocketChardev *s = SOCKET_CHARDEV(chr); 3199 3176 3200 3177 if (!s->connected) { 3201 3178 return; ··· 3211 3188 } 3212 3189 3213 3190 typedef struct { 3214 - CharDriverState *chr; 3191 + Chardev *chr; 3215 3192 char buf[12]; 3216 3193 size_t buflen; 3217 3194 } TCPCharDriverTelnetInit; ··· 3244 3221 return TRUE; 3245 3222 } 3246 3223 3247 - static void tcp_chr_telnet_init(CharDriverState *chr) 3224 + static void tcp_chr_telnet_init(Chardev *chr) 3248 3225 { 3249 - TCPCharDriver *s = chr->opaque; 3226 + SocketChardev *s = SOCKET_CHARDEV(chr); 3250 3227 TCPCharDriverTelnetInit *init = 3251 3228 g_new0(TCPCharDriverTelnetInit, 1); 3252 3229 size_t n = 0; ··· 3280 3257 static void tcp_chr_tls_handshake(QIOTask *task, 3281 3258 gpointer user_data) 3282 3259 { 3283 - CharDriverState *chr = user_data; 3284 - TCPCharDriver *s = chr->opaque; 3260 + Chardev *chr = user_data; 3261 + SocketChardev *s = user_data; 3285 3262 3286 3263 if (qio_task_propagate_error(task, NULL)) { 3287 3264 tcp_chr_disconnect(chr); ··· 3295 3272 } 3296 3273 3297 3274 3298 - static void tcp_chr_tls_init(CharDriverState *chr) 3275 + static void tcp_chr_tls_init(Chardev *chr) 3299 3276 { 3300 - TCPCharDriver *s = chr->opaque; 3277 + SocketChardev *s = SOCKET_CHARDEV(chr); 3301 3278 QIOChannelTLS *tioc; 3302 3279 Error *err = NULL; 3303 3280 gchar *name; ··· 3333 3310 } 3334 3311 3335 3312 3336 - static void tcp_chr_set_client_ioc_name(CharDriverState *chr, 3313 + static void tcp_chr_set_client_ioc_name(Chardev *chr, 3337 3314 QIOChannelSocket *sioc) 3338 3315 { 3339 - TCPCharDriver *s = chr->opaque; 3316 + SocketChardev *s = SOCKET_CHARDEV(chr); 3340 3317 char *name; 3341 3318 name = g_strdup_printf("chardev-tcp-%s-%s", 3342 3319 s->is_listen ? "server" : "client", ··· 3346 3323 3347 3324 } 3348 3325 3349 - static int tcp_chr_new_client(CharDriverState *chr, QIOChannelSocket *sioc) 3326 + static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc) 3350 3327 { 3351 - TCPCharDriver *s = chr->opaque; 3328 + SocketChardev *s = SOCKET_CHARDEV(chr); 3329 + 3352 3330 if (s->ioc != NULL) { 3353 3331 return -1; 3354 3332 } ··· 3382 3360 } 3383 3361 3384 3362 3385 - static int tcp_chr_add_client(CharDriverState *chr, int fd) 3363 + static int tcp_chr_add_client(Chardev *chr, int fd) 3386 3364 { 3387 3365 int ret; 3388 3366 QIOChannelSocket *sioc; ··· 3401 3379 GIOCondition cond, 3402 3380 void *opaque) 3403 3381 { 3404 - CharDriverState *chr = opaque; 3382 + Chardev *chr = CHARDEV(opaque); 3405 3383 QIOChannelSocket *sioc; 3406 3384 3407 3385 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(channel), ··· 3417 3395 return TRUE; 3418 3396 } 3419 3397 3420 - static int tcp_chr_wait_connected(CharDriverState *chr, Error **errp) 3398 + static int tcp_chr_wait_connected(Chardev *chr, Error **errp) 3421 3399 { 3422 - TCPCharDriver *s = chr->opaque; 3400 + SocketChardev *s = SOCKET_CHARDEV(chr); 3423 3401 QIOChannelSocket *sioc; 3424 3402 3425 3403 /* It can't wait on s->connected, since it is set asynchronously 3426 3404 * in TLS and telnet cases, only wait for an accepted socket */ 3427 3405 while (!s->ioc) { 3428 3406 if (s->is_listen) { 3429 - fprintf(stderr, "QEMU waiting for connection on: %s\n", 3430 - chr->filename); 3407 + error_report("QEMU waiting for connection on: %s", 3408 + chr->filename); 3431 3409 qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), true, NULL); 3432 3410 tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr); 3433 3411 qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL); ··· 3446 3424 return 0; 3447 3425 } 3448 3426 3449 - static int qemu_chr_wait_connected(CharDriverState *chr, Error **errp) 3427 + static int qemu_chr_wait_connected(Chardev *chr, Error **errp) 3450 3428 { 3451 - if (chr->chr_wait_connected) { 3452 - return chr->chr_wait_connected(chr, errp); 3429 + ChardevClass *cc = CHARDEV_GET_CLASS(chr); 3430 + 3431 + if (cc->chr_wait_connected) { 3432 + return cc->chr_wait_connected(chr, errp); 3453 3433 } 3454 3434 3455 3435 return 0; ··· 3465 3445 return qemu_chr_wait_connected(be->chr, errp); 3466 3446 } 3467 3447 3468 - static void tcp_chr_free(CharDriverState *chr) 3448 + static void tcp_chr_free(Chardev *chr) 3469 3449 { 3470 - TCPCharDriver *s = chr->opaque; 3450 + SocketChardev *s = SOCKET_CHARDEV(chr); 3471 3451 3472 3452 tcp_chr_free_connection(chr); 3473 3453 ··· 3486 3466 if (s->tls_creds) { 3487 3467 object_unref(OBJECT(s->tls_creds)); 3488 3468 } 3489 - g_free(s); 3469 + 3490 3470 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 3491 3471 } 3492 3472 ··· 3494 3474 static void qemu_chr_socket_connected(QIOTask *task, void *opaque) 3495 3475 { 3496 3476 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task)); 3497 - CharDriverState *chr = opaque; 3498 - TCPCharDriver *s = chr->opaque; 3477 + Chardev *chr = CHARDEV(opaque); 3478 + SocketChardev *s = SOCKET_CHARDEV(chr); 3499 3479 Error *err = NULL; 3500 3480 3501 3481 if (qio_task_propagate_error(task, &err)) { ··· 3516 3496 /* Ring buffer chardev */ 3517 3497 3518 3498 typedef struct { 3499 + Chardev parent; 3519 3500 size_t size; 3520 3501 size_t prod; 3521 3502 size_t cons; 3522 3503 uint8_t *cbuf; 3523 - } RingBufCharDriver; 3504 + } RingBufChardev; 3505 + 3506 + #define RINGBUF_CHARDEV(obj) \ 3507 + OBJECT_CHECK(RingBufChardev, (obj), TYPE_CHARDEV_RINGBUF) 3524 3508 3525 - static size_t ringbuf_count(const CharDriverState *chr) 3509 + static size_t ringbuf_count(const Chardev *chr) 3526 3510 { 3527 - const RingBufCharDriver *d = chr->opaque; 3511 + const RingBufChardev *d = RINGBUF_CHARDEV(chr); 3528 3512 3529 3513 return d->prod - d->cons; 3530 3514 } 3531 3515 3532 3516 /* Called with chr_write_lock held. */ 3533 - static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 3517 + static int ringbuf_chr_write(Chardev *chr, const uint8_t *buf, int len) 3534 3518 { 3535 - RingBufCharDriver *d = chr->opaque; 3519 + RingBufChardev *d = RINGBUF_CHARDEV(chr); 3536 3520 int i; 3537 3521 3538 3522 if (!buf || (len < 0)) { ··· 3549 3533 return len; 3550 3534 } 3551 3535 3552 - static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len) 3536 + static int ringbuf_chr_read(Chardev *chr, uint8_t *buf, int len) 3553 3537 { 3554 - RingBufCharDriver *d = chr->opaque; 3538 + RingBufChardev *d = RINGBUF_CHARDEV(chr); 3555 3539 int i; 3556 3540 3557 3541 qemu_mutex_lock(&chr->chr_write_lock); ··· 3563 3547 return i; 3564 3548 } 3565 3549 3566 - static void ringbuf_chr_free(struct CharDriverState *chr) 3550 + static void ringbuf_chr_free(struct Chardev *chr) 3567 3551 { 3568 - RingBufCharDriver *d = chr->opaque; 3552 + RingBufChardev *d = RINGBUF_CHARDEV(chr); 3569 3553 3570 3554 g_free(d->cbuf); 3571 - g_free(d); 3572 - chr->opaque = NULL; 3573 3555 } 3574 3556 3575 - static CharDriverState *qemu_chr_open_ringbuf(const char *id, 3576 - ChardevBackend *backend, 3577 - ChardevReturn *ret, 3578 - bool *be_opened, 3579 - Error **errp) 3557 + static void qemu_chr_open_ringbuf(Chardev *chr, 3558 + ChardevBackend *backend, 3559 + bool *be_opened, 3560 + Error **errp) 3580 3561 { 3581 3562 ChardevRingbuf *opts = backend->u.ringbuf.data; 3582 - ChardevCommon *common = qapi_ChardevRingbuf_base(opts); 3583 - CharDriverState *chr; 3584 - RingBufCharDriver *d; 3585 - 3586 - chr = qemu_chr_alloc(common, errp); 3587 - if (!chr) { 3588 - return NULL; 3589 - } 3590 - d = g_malloc(sizeof(*d)); 3563 + RingBufChardev *d = RINGBUF_CHARDEV(chr); 3591 3564 3592 3565 d->size = opts->has_size ? opts->size : 65536; 3593 3566 3594 3567 /* The size must be power of 2 */ 3595 3568 if (d->size & (d->size - 1)) { 3596 3569 error_setg(errp, "size of ringbuf chardev must be power of two"); 3597 - goto fail; 3570 + return; 3598 3571 } 3599 3572 3600 3573 d->prod = 0; 3601 3574 d->cons = 0; 3602 3575 d->cbuf = g_malloc0(d->size); 3603 - 3604 - chr->opaque = d; 3605 - chr->chr_write = ringbuf_chr_write; 3606 - chr->chr_free = ringbuf_chr_free; 3607 - 3608 - return chr; 3609 - 3610 - fail: 3611 - g_free(d); 3612 - qemu_chr_free_common(chr); 3613 - return NULL; 3614 - } 3615 - 3616 - bool chr_is_ringbuf(const CharDriverState *chr) 3617 - { 3618 - return chr->chr_write == ringbuf_chr_write; 3619 3576 } 3620 3577 3621 3578 void qmp_ringbuf_write(const char *device, const char *data, 3622 3579 bool has_format, enum DataFormat format, 3623 3580 Error **errp) 3624 3581 { 3625 - CharDriverState *chr; 3582 + Chardev *chr; 3626 3583 const uint8_t *write_data; 3627 3584 int ret; 3628 3585 gsize write_count; ··· 3633 3590 return; 3634 3591 } 3635 3592 3636 - if (!chr_is_ringbuf(chr)) { 3593 + if (!CHARDEV_IS_RINGBUF(chr)) { 3637 3594 error_setg(errp,"%s is not a ringbuf device", device); 3638 3595 return; 3639 3596 } ··· 3666 3623 bool has_format, enum DataFormat format, 3667 3624 Error **errp) 3668 3625 { 3669 - CharDriverState *chr; 3626 + Chardev *chr; 3670 3627 uint8_t *read_data; 3671 3628 size_t count; 3672 3629 char *data; ··· 3677 3634 return NULL; 3678 3635 } 3679 3636 3680 - if (!chr_is_ringbuf(chr)) { 3637 + if (!CHARDEV_IS_RINGBUF(chr)) { 3681 3638 error_setg(errp,"%s is not a ringbuf device", device); 3682 3639 return NULL; 3683 3640 } ··· 3894 3851 stdio->signal = qemu_opt_get_bool(opts, "signal", true); 3895 3852 } 3896 3853 3854 + static const CharDriver stdio_driver = { 3855 + .kind = CHARDEV_BACKEND_KIND_STDIO, 3856 + .parse = qemu_chr_parse_stdio, 3857 + }; 3858 + 3859 + static void char_stdio_class_init(ObjectClass *oc, void *data) 3860 + { 3861 + ChardevClass *cc = CHARDEV_CLASS(oc); 3862 + 3863 + cc->open = qemu_chr_open_stdio; 3864 + #ifdef _WIN32 3865 + cc->chr_write = win_stdio_write; 3866 + cc->chr_set_echo = qemu_chr_set_echo_win_stdio; 3867 + cc->chr_free = win_stdio_free; 3868 + #else 3869 + cc->chr_set_echo = qemu_chr_set_echo_stdio; 3870 + cc->chr_free = qemu_chr_free_stdio; 3871 + #endif 3872 + } 3873 + 3874 + static const TypeInfo char_stdio_type_info = { 3875 + .name = TYPE_CHARDEV_STDIO, 3876 + #ifdef _WIN32 3877 + .parent = TYPE_CHARDEV_WIN_STDIO, 3878 + #else 3879 + .parent = TYPE_CHARDEV_FD, 3880 + #endif 3881 + .class_init = char_stdio_class_init, 3882 + }; 3883 + 3897 3884 #ifdef HAVE_CHARDEV_SERIAL 3898 3885 static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, 3899 3886 Error **errp) ··· 3943 3930 dev->device = g_strdup(device); 3944 3931 } 3945 3932 3933 + static const CharDriver pipe_driver = { 3934 + .kind = CHARDEV_BACKEND_KIND_PIPE, 3935 + .parse = qemu_chr_parse_pipe, 3936 + }; 3937 + 3938 + static void char_pipe_class_init(ObjectClass *oc, void *data) 3939 + { 3940 + ChardevClass *cc = CHARDEV_CLASS(oc); 3941 + 3942 + cc->open = qemu_chr_open_pipe; 3943 + } 3944 + 3945 + static const TypeInfo char_pipe_type_info = { 3946 + .name = TYPE_CHARDEV_PIPE, 3947 + #ifdef _WIN32 3948 + .parent = TYPE_CHARDEV_WIN, 3949 + #else 3950 + .parent = TYPE_CHARDEV_FD, 3951 + #endif 3952 + .class_init = char_pipe_class_init, 3953 + }; 3954 + 3946 3955 static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend, 3947 3956 Error **errp) 3948 3957 { ··· 3959 3968 } 3960 3969 } 3961 3970 3971 + static const CharDriver ringbuf_driver = { 3972 + .kind = CHARDEV_BACKEND_KIND_RINGBUF, 3973 + .parse = qemu_chr_parse_ringbuf, 3974 + }; 3975 + 3976 + static void char_ringbuf_class_init(ObjectClass *oc, void *data) 3977 + { 3978 + ChardevClass *cc = CHARDEV_CLASS(oc); 3979 + 3980 + cc->open = qemu_chr_open_ringbuf; 3981 + cc->chr_write = ringbuf_chr_write; 3982 + cc->chr_free = ringbuf_chr_free; 3983 + } 3984 + 3985 + static const TypeInfo char_ringbuf_type_info = { 3986 + .name = TYPE_CHARDEV_RINGBUF, 3987 + .parent = TYPE_CHARDEV, 3988 + .class_init = char_ringbuf_class_init, 3989 + .instance_size = sizeof(RingBufChardev), 3990 + }; 3991 + 3992 + /* Bug-compatibility: */ 3993 + static const CharDriver memory_driver = { 3994 + .kind = CHARDEV_BACKEND_KIND_MEMORY, 3995 + .parse = qemu_chr_parse_ringbuf, 3996 + }; 3997 + 3998 + static const TypeInfo char_memory_type_info = { 3999 + .name = TYPE_CHARDEV_MEMORY, 4000 + .parent = TYPE_CHARDEV_RINGBUF, 4001 + }; 4002 + 3962 4003 static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend, 3963 4004 Error **errp) 3964 4005 { ··· 3973 4014 qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux)); 3974 4015 mux->chardev = g_strdup(chardev); 3975 4016 } 4017 + 4018 + static const CharDriver mux_driver = { 4019 + .kind = CHARDEV_BACKEND_KIND_MUX, 4020 + .parse = qemu_chr_parse_mux, 4021 + }; 4022 + 4023 + static void char_mux_class_init(ObjectClass *oc, void *data) 4024 + { 4025 + ChardevClass *cc = CHARDEV_CLASS(oc); 4026 + 4027 + cc->open = qemu_chr_open_mux; 4028 + cc->chr_free = mux_chr_free; 4029 + cc->chr_write = mux_chr_write; 4030 + cc->chr_accept_input = mux_chr_accept_input; 4031 + cc->chr_add_watch = mux_chr_add_watch; 4032 + } 4033 + 4034 + static const TypeInfo char_mux_type_info = { 4035 + .name = TYPE_CHARDEV_MUX, 4036 + .parent = TYPE_CHARDEV, 4037 + .class_init = char_mux_class_init, 4038 + .instance_size = sizeof(MuxChardev), 4039 + }; 3976 4040 3977 4041 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, 3978 4042 Error **errp) ··· 4101 4165 } 4102 4166 } 4103 4167 4104 - typedef struct CharDriver { 4105 - const char *name; 4106 - ChardevBackendKind kind; 4107 - CharDriverParse *parse; 4108 - CharDriverCreate *create; 4109 - } CharDriver; 4168 + static const CharDriver *backends[CHARDEV_BACKEND_KIND__MAX]; 4110 4169 4111 - static GSList *backends; 4112 - 4113 - void register_char_driver(const char *name, ChardevBackendKind kind, 4114 - CharDriverParse *parse, CharDriverCreate *create) 4170 + void register_char_driver(const CharDriver *driver) 4115 4171 { 4116 - CharDriver *s; 4117 - 4118 - s = g_malloc0(sizeof(*s)); 4119 - s->name = g_strdup(name); 4120 - s->kind = kind; 4121 - s->parse = parse; 4122 - s->create = create; 4123 - 4124 - backends = g_slist_append(backends, s); 4172 + backends[driver->kind] = driver; 4125 4173 } 4126 4174 4127 - CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, 4128 - Error **errp) 4175 + Chardev *qemu_chr_new_from_opts(QemuOpts *opts, 4176 + Error **errp) 4129 4177 { 4130 4178 Error *local_err = NULL; 4131 - CharDriver *cd; 4132 - CharDriverState *chr; 4133 - GSList *i; 4179 + const CharDriver *cd = NULL; 4180 + Chardev *chr; 4181 + int i; 4134 4182 ChardevReturn *ret = NULL; 4135 4183 ChardevBackend *backend; 4184 + const char *name = qemu_opt_get(opts, "backend"); 4136 4185 const char *id = qemu_opts_id(opts); 4137 4186 char *bid = NULL; 4138 4187 4139 - if (qemu_opt_get(opts, "backend") == NULL) { 4188 + if (name == NULL) { 4140 4189 error_setg(errp, "chardev: \"%s\" missing backend", 4141 4190 qemu_opts_id(opts)); 4142 4191 goto err; 4143 4192 } 4144 4193 4145 - if (is_help_option(qemu_opt_get(opts, "backend"))) { 4146 - fprintf(stderr, "Available chardev backend types:\n"); 4147 - for (i = backends; i; i = i->next) { 4148 - cd = i->data; 4149 - fprintf(stderr, "%s\n", cd->name); 4194 + if (is_help_option(name)) { 4195 + GString *str = g_string_new(""); 4196 + for (i = 0; i < ARRAY_SIZE(backends); i++) { 4197 + cd = backends[i]; 4198 + if (cd) { 4199 + g_string_append_printf(str, "\n%s", ChardevBackendKind_lookup[cd->kind]); 4200 + if (cd->alias) { 4201 + g_string_append_printf(str, "\n%s", cd->alias); 4202 + } 4203 + } 4150 4204 } 4151 - exit(!is_help_option(qemu_opt_get(opts, "backend"))); 4205 + 4206 + error_report("Available chardev backend types: %s", str->str); 4207 + g_string_free(str, true); 4208 + exit(0); 4152 4209 } 4153 4210 4154 4211 if (id == NULL) { ··· 4156 4213 goto err; 4157 4214 } 4158 4215 4159 - for (i = backends; i; i = i->next) { 4160 - cd = i->data; 4161 - 4162 - if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) { 4216 + for (i = 0; i < ARRAY_SIZE(backends); i++) { 4217 + cd = backends[i]; 4218 + if (!cd) { 4219 + continue; 4220 + } 4221 + if (g_strcmp0(ChardevBackendKind_lookup[cd->kind], name) == 0 || 4222 + g_strcmp0(cd->alias, name) == 0) { 4163 4223 break; 4164 4224 } 4165 4225 } 4166 - if (i == NULL) { 4167 - error_setg(errp, "chardev: backend \"%s\" not found", 4168 - qemu_opt_get(opts, "backend")); 4226 + if (i == ARRAY_SIZE(backends)) { 4227 + error_setg(errp, "chardev: backend \"%s\" not found", name); 4169 4228 goto err; 4170 4229 } 4171 4230 ··· 4222 4281 return NULL; 4223 4282 } 4224 4283 4225 - CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename) 4284 + Chardev *qemu_chr_new_noreplay(const char *label, const char *filename) 4226 4285 { 4227 4286 const char *p; 4228 - CharDriverState *chr; 4287 + Chardev *chr; 4229 4288 QemuOpts *opts; 4230 4289 Error *err = NULL; 4231 4290 ··· 4248 4307 return chr; 4249 4308 } 4250 4309 4251 - CharDriverState *qemu_chr_new(const char *label, const char *filename) 4310 + Chardev *qemu_chr_new(const char *label, const char *filename) 4252 4311 { 4253 - CharDriverState *chr; 4312 + Chardev *chr; 4254 4313 chr = qemu_chr_new_noreplay(label, filename); 4255 4314 if (chr) { 4256 - chr->replay = replay_mode != REPLAY_MODE_NONE; 4257 - if (chr->replay && chr->chr_ioctl) { 4258 - fprintf(stderr, 4259 - "Replay: ioctl is not supported for serial devices yet\n"); 4315 + if (replay_mode != REPLAY_MODE_NONE) { 4316 + qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY); 4317 + } 4318 + if (qemu_chr_replay(chr) && CHARDEV_GET_CLASS(chr)->chr_ioctl) { 4319 + error_report("Replay: ioctl is not supported " 4320 + "for serial devices yet"); 4260 4321 } 4261 4322 replay_register_char_driver(chr); 4262 4323 } ··· 4265 4326 4266 4327 void qemu_chr_fe_set_echo(CharBackend *be, bool echo) 4267 4328 { 4268 - CharDriverState *chr = be->chr; 4329 + Chardev *chr = be->chr; 4269 4330 4270 - if (chr && chr->chr_set_echo) { 4271 - chr->chr_set_echo(chr, echo); 4331 + if (chr && CHARDEV_GET_CLASS(chr)->chr_set_echo) { 4332 + CHARDEV_GET_CLASS(chr)->chr_set_echo(chr, echo); 4272 4333 } 4273 4334 } 4274 4335 4275 4336 void qemu_chr_fe_set_open(CharBackend *be, int fe_open) 4276 4337 { 4277 - CharDriverState *chr = be->chr; 4338 + Chardev *chr = be->chr; 4278 4339 4279 4340 if (!chr) { 4280 4341 return; ··· 4284 4345 return; 4285 4346 } 4286 4347 be->fe_open = fe_open; 4287 - if (chr->chr_set_fe_open) { 4288 - chr->chr_set_fe_open(chr, fe_open); 4348 + if (CHARDEV_GET_CLASS(chr)->chr_set_fe_open) { 4349 + CHARDEV_GET_CLASS(chr)->chr_set_fe_open(chr, fe_open); 4289 4350 } 4290 4351 } 4291 4352 4292 4353 guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, 4293 4354 GIOFunc func, void *user_data) 4294 4355 { 4295 - CharDriverState *s = be->chr; 4356 + Chardev *s = be->chr; 4296 4357 GSource *src; 4297 4358 guint tag; 4298 4359 4299 - if (!s || s->chr_add_watch == NULL) { 4360 + if (!s || CHARDEV_GET_CLASS(s)->chr_add_watch == NULL) { 4300 4361 return 0; 4301 4362 } 4302 4363 4303 - src = s->chr_add_watch(s, cond); 4364 + src = CHARDEV_GET_CLASS(s)->chr_add_watch(s, cond); 4304 4365 if (!src) { 4305 4366 return 0; 4306 4367 } ··· 4314 4375 4315 4376 void qemu_chr_fe_disconnect(CharBackend *be) 4316 4377 { 4317 - CharDriverState *chr = be->chr; 4378 + Chardev *chr = be->chr; 4318 4379 4319 - if (chr && chr->chr_disconnect) { 4320 - chr->chr_disconnect(chr); 4380 + if (chr && CHARDEV_GET_CLASS(chr)->chr_disconnect) { 4381 + CHARDEV_GET_CLASS(chr)->chr_disconnect(chr); 4321 4382 } 4322 4383 } 4323 4384 4324 - static void qemu_chr_free_common(CharDriverState *chr) 4385 + void qemu_chr_free(Chardev *chr) 4325 4386 { 4326 - if (chr->be) { 4327 - chr->be->chr = NULL; 4387 + if (CHARDEV_GET_CLASS(chr)->chr_free) { 4388 + CHARDEV_GET_CLASS(chr)->chr_free(chr); 4328 4389 } 4329 - g_free(chr->filename); 4330 - g_free(chr->label); 4331 - if (chr->logfd != -1) { 4332 - close(chr->logfd); 4333 - } 4334 - qemu_mutex_destroy(&chr->chr_write_lock); 4335 - g_free(chr); 4390 + object_unref(OBJECT(chr)); 4336 4391 } 4337 4392 4338 - void qemu_chr_free(CharDriverState *chr) 4339 - { 4340 - if (chr->chr_free) { 4341 - chr->chr_free(chr); 4342 - } 4343 - qemu_chr_free_common(chr); 4344 - } 4345 - 4346 - void qemu_chr_delete(CharDriverState *chr) 4393 + void qemu_chr_delete(Chardev *chr) 4347 4394 { 4348 4395 QTAILQ_REMOVE(&chardevs, chr, next); 4349 4396 qemu_chr_free(chr); ··· 4352 4399 ChardevInfoList *qmp_query_chardev(Error **errp) 4353 4400 { 4354 4401 ChardevInfoList *chr_list = NULL; 4355 - CharDriverState *chr; 4402 + Chardev *chr; 4356 4403 4357 4404 QTAILQ_FOREACH(chr, &chardevs, next) { 4358 4405 ChardevInfoList *info = g_malloc0(sizeof(*info)); ··· 4368 4415 return chr_list; 4369 4416 } 4370 4417 4418 + static ChardevBackendInfoList * 4419 + qmp_prepend_backend(ChardevBackendInfoList *list, const char *name) 4420 + { 4421 + ChardevBackendInfoList *info = g_malloc0(sizeof(*info)); 4422 + info->value = g_malloc0(sizeof(*info->value)); 4423 + info->value->name = g_strdup(name); 4424 + info->next = list; 4425 + return info; 4426 + } 4427 + 4371 4428 ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp) 4372 4429 { 4373 4430 ChardevBackendInfoList *backend_list = NULL; 4374 - CharDriver *c = NULL; 4375 - GSList *i = NULL; 4431 + const CharDriver *c; 4432 + int i; 4376 4433 4377 - for (i = backends; i; i = i->next) { 4378 - ChardevBackendInfoList *info = g_malloc0(sizeof(*info)); 4379 - c = i->data; 4380 - info->value = g_malloc0(sizeof(*info->value)); 4381 - info->value->name = g_strdup(c->name); 4434 + for (i = 0; i < ARRAY_SIZE(backends); i++) { 4435 + c = backends[i]; 4436 + if (!c) { 4437 + continue; 4438 + } 4382 4439 4383 - info->next = backend_list; 4384 - backend_list = info; 4440 + backend_list = qmp_prepend_backend(backend_list, 4441 + ChardevBackendKind_lookup[c->kind]); 4442 + if (c->alias) { 4443 + backend_list = qmp_prepend_backend(backend_list, c->alias); 4444 + } 4385 4445 } 4386 4446 4387 4447 return backend_list; 4388 4448 } 4389 4449 4390 - CharDriverState *qemu_chr_find(const char *name) 4450 + Chardev *qemu_chr_find(const char *name) 4391 4451 { 4392 - CharDriverState *chr; 4452 + Chardev *chr; 4393 4453 4394 4454 QTAILQ_FOREACH(chr, &chardevs, next) { 4395 4455 if (strcmp(chr->label, name) != 0) ··· 4495 4555 4496 4556 #ifdef _WIN32 4497 4557 4498 - static CharDriverState *qmp_chardev_open_file(const char *id, 4499 - ChardevBackend *backend, 4500 - ChardevReturn *ret, 4501 - bool *be_opened, 4502 - Error **errp) 4558 + static void qmp_chardev_open_file(Chardev *chr, 4559 + ChardevBackend *backend, 4560 + bool *be_opened, 4561 + Error **errp) 4503 4562 { 4504 4563 ChardevFile *file = backend->u.file.data; 4505 - ChardevCommon *common = qapi_ChardevFile_base(file); 4506 4564 HANDLE out; 4507 4565 DWORD accessmode; 4508 4566 DWORD flags; 4509 4567 4510 4568 if (file->has_in) { 4511 4569 error_setg(errp, "input file not supported"); 4512 - return NULL; 4570 + return; 4513 4571 } 4514 4572 4515 4573 if (file->has_append && file->append) { ··· 4526 4584 FILE_ATTRIBUTE_NORMAL, NULL); 4527 4585 if (out == INVALID_HANDLE_VALUE) { 4528 4586 error_setg(errp, "open %s failed", file->out); 4529 - return NULL; 4587 + return; 4530 4588 } 4531 - return qemu_chr_open_win_file(out, common, errp); 4589 + 4590 + qemu_chr_open_win_file(chr, out); 4532 4591 } 4533 4592 4534 - static CharDriverState *qmp_chardev_open_serial(const char *id, 4535 - ChardevBackend *backend, 4536 - ChardevReturn *ret, 4537 - bool *be_opened, 4538 - Error **errp) 4593 + static void qmp_chardev_open_serial(Chardev *chr, 4594 + ChardevBackend *backend, 4595 + bool *be_opened, 4596 + Error **errp) 4539 4597 { 4540 4598 ChardevHostdev *serial = backend->u.serial.data; 4541 - ChardevCommon *common = qapi_ChardevHostdev_base(serial); 4542 - return qemu_chr_open_win_path(serial->device, common, errp); 4599 + 4600 + win_chr_init(chr, serial->device, errp); 4543 4601 } 4544 4602 4545 4603 #else /* WIN32 */ ··· 4556 4614 return fd; 4557 4615 } 4558 4616 4559 - static CharDriverState *qmp_chardev_open_file(const char *id, 4560 - ChardevBackend *backend, 4561 - ChardevReturn *ret, 4562 - bool *be_opened, 4563 - Error **errp) 4617 + static void qmp_chardev_open_file(Chardev *chr, 4618 + ChardevBackend *backend, 4619 + bool *be_opened, 4620 + Error **errp) 4564 4621 { 4565 4622 ChardevFile *file = backend->u.file.data; 4566 - ChardevCommon *common = qapi_ChardevFile_base(file); 4567 4623 int flags, in = -1, out; 4568 4624 4569 4625 flags = O_WRONLY | O_CREAT | O_BINARY; ··· 4575 4631 4576 4632 out = qmp_chardev_open_file_source(file->out, flags, errp); 4577 4633 if (out < 0) { 4578 - return NULL; 4634 + return; 4579 4635 } 4580 4636 4581 4637 if (file->has_in) { ··· 4583 4639 in = qmp_chardev_open_file_source(file->in, flags, errp); 4584 4640 if (in < 0) { 4585 4641 qemu_close(out); 4586 - return NULL; 4642 + return; 4587 4643 } 4588 4644 } 4589 4645 4590 - return qemu_chr_open_fd(in, out, common, errp); 4646 + qemu_chr_open_fd(chr, in, out); 4591 4647 } 4592 4648 4593 4649 #ifdef HAVE_CHARDEV_SERIAL 4594 - static CharDriverState *qmp_chardev_open_serial(const char *id, 4595 - ChardevBackend *backend, 4596 - ChardevReturn *ret, 4597 - bool *be_opened, 4598 - Error **errp) 4650 + static void qmp_chardev_open_serial(Chardev *chr, 4651 + ChardevBackend *backend, 4652 + bool *be_opened, 4653 + Error **errp) 4599 4654 { 4600 4655 ChardevHostdev *serial = backend->u.serial.data; 4601 - ChardevCommon *common = qapi_ChardevHostdev_base(serial); 4602 4656 int fd; 4603 4657 4604 4658 fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); 4605 4659 if (fd < 0) { 4606 - return NULL; 4660 + return; 4607 4661 } 4608 4662 qemu_set_nonblock(fd); 4609 - return qemu_chr_open_tty_fd(fd, common, be_opened, errp); 4663 + tty_serial_init(fd, 115200, 'N', 8, 1); 4664 + 4665 + qemu_chr_open_fd(chr, fd, fd); 4610 4666 } 4611 4667 #endif 4612 4668 4613 4669 #ifdef HAVE_CHARDEV_PARPORT 4614 - static CharDriverState *qmp_chardev_open_parallel(const char *id, 4615 - ChardevBackend *backend, 4616 - ChardevReturn *ret, 4617 - bool *be_opened, 4618 - Error **errp) 4670 + static void qmp_chardev_open_parallel(Chardev *chr, 4671 + ChardevBackend *backend, 4672 + bool *be_opened, 4673 + Error **errp) 4619 4674 { 4620 4675 ChardevHostdev *parallel = backend->u.parallel.data; 4621 - ChardevCommon *common = qapi_ChardevHostdev_base(parallel); 4622 4676 int fd; 4623 4677 4624 4678 fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); 4625 4679 if (fd < 0) { 4626 - return NULL; 4680 + return; 4627 4681 } 4628 - return qemu_chr_open_pp_fd(fd, common, be_opened, errp); 4682 + qemu_chr_open_pp_fd(chr, fd, be_opened, errp); 4683 + } 4684 + 4685 + static const CharDriver parallel_driver = { 4686 + .kind = CHARDEV_BACKEND_KIND_PARALLEL, 4687 + .alias = "parport", 4688 + .parse = qemu_chr_parse_parallel, 4689 + }; 4690 + 4691 + static void char_parallel_class_init(ObjectClass *oc, void *data) 4692 + { 4693 + ChardevClass *cc = CHARDEV_CLASS(oc); 4694 + 4695 + cc->open = qmp_chardev_open_parallel; 4696 + #if defined(__linux__) 4697 + cc->chr_write = null_chr_write; 4698 + cc->chr_ioctl = pp_ioctl; 4699 + cc->chr_free = pp_free; 4700 + #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 4701 + /* FIXME: no chr_free */ 4702 + cc->chr_write = null_chr_write; 4703 + cc->chr_ioctl = pp_ioctl; 4704 + #endif 4629 4705 } 4706 + 4707 + static const TypeInfo char_parallel_type_info = { 4708 + .name = TYPE_CHARDEV_PARALLEL, 4709 + .parent = TYPE_CHARDEV, 4710 + .instance_size = sizeof(ParallelChardev), 4711 + .class_init = char_parallel_class_init, 4712 + }; 4630 4713 #endif 4631 4714 4632 4715 #endif /* WIN32 */ 4633 4716 4717 + static const CharDriver file_driver = { 4718 + .kind = CHARDEV_BACKEND_KIND_FILE, 4719 + .parse = qemu_chr_parse_file_out, 4720 + }; 4721 + 4722 + static void char_file_class_init(ObjectClass *oc, void *data) 4723 + { 4724 + ChardevClass *cc = CHARDEV_CLASS(oc); 4725 + 4726 + cc->open = qmp_chardev_open_file; 4727 + #ifdef _WIN32 4728 + /* FIXME: no chr_free */ 4729 + cc->chr_free = NULL; 4730 + #endif 4731 + } 4732 + 4733 + static const TypeInfo char_file_type_info = { 4734 + .name = TYPE_CHARDEV_FILE, 4735 + #ifdef _WIN32 4736 + .parent = TYPE_CHARDEV_WIN, 4737 + #else 4738 + .parent = TYPE_CHARDEV_FD, 4739 + #endif 4740 + .class_init = char_file_class_init, 4741 + }; 4742 + 4743 + #ifdef HAVE_CHARDEV_SERIAL 4744 + 4745 + static const CharDriver serial_driver = { 4746 + .kind = CHARDEV_BACKEND_KIND_SERIAL, 4747 + .alias = "tty", 4748 + .parse = qemu_chr_parse_serial, 4749 + }; 4750 + 4751 + static void char_serial_class_init(ObjectClass *oc, void *data) 4752 + { 4753 + ChardevClass *cc = CHARDEV_CLASS(oc); 4754 + 4755 + cc->open = qmp_chardev_open_serial; 4756 + #ifndef _WIN32 4757 + cc->chr_ioctl = tty_serial_ioctl; 4758 + cc->chr_free = qemu_chr_free_tty; 4759 + #endif 4760 + } 4761 + 4762 + static const TypeInfo char_serial_type_info = { 4763 + .name = TYPE_CHARDEV_SERIAL, 4764 + #ifdef _WIN32 4765 + .parent = TYPE_CHARDEV_WIN, 4766 + #else 4767 + .parent = TYPE_CHARDEV_FD, 4768 + #endif 4769 + .class_init = char_serial_class_init, 4770 + }; 4771 + #endif 4772 + 4634 4773 static gboolean socket_reconnect_timeout(gpointer opaque) 4635 4774 { 4636 - CharDriverState *chr = opaque; 4637 - TCPCharDriver *s = chr->opaque; 4775 + Chardev *chr = CHARDEV(opaque); 4776 + SocketChardev *s = SOCKET_CHARDEV(opaque); 4638 4777 QIOChannelSocket *sioc; 4639 4778 4640 4779 s->reconnect_timer = 0; ··· 4652 4791 return false; 4653 4792 } 4654 4793 4655 - static CharDriverState *qmp_chardev_open_socket(const char *id, 4656 - ChardevBackend *backend, 4657 - ChardevReturn *ret, 4658 - bool *be_opened, 4659 - Error **errp) 4794 + static void qmp_chardev_open_socket(Chardev *chr, 4795 + ChardevBackend *backend, 4796 + bool *be_opened, 4797 + Error **errp) 4660 4798 { 4661 - CharDriverState *chr; 4662 - TCPCharDriver *s; 4799 + SocketChardev *s = SOCKET_CHARDEV(chr); 4663 4800 ChardevSocket *sock = backend->u.socket.data; 4664 4801 SocketAddress *addr = sock->addr; 4665 4802 bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; ··· 4667 4804 bool is_telnet = sock->has_telnet ? sock->telnet : false; 4668 4805 bool is_waitconnect = sock->has_wait ? sock->wait : false; 4669 4806 int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0; 4670 - ChardevCommon *common = qapi_ChardevSocket_base(sock); 4671 4807 QIOChannelSocket *sioc = NULL; 4672 - 4673 - chr = qemu_chr_alloc(common, errp); 4674 - if (!chr) { 4675 - return NULL; 4676 - } 4677 - s = g_new0(TCPCharDriver, 1); 4678 4808 4679 4809 s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX; 4680 4810 s->is_listen = is_listen; ··· 4720 4850 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); 4721 4851 } 4722 4852 4723 - chr->opaque = s; 4724 - chr->chr_wait_connected = tcp_chr_wait_connected; 4725 - chr->chr_write = tcp_chr_write; 4726 - chr->chr_sync_read = tcp_chr_sync_read; 4727 - chr->chr_free = tcp_chr_free; 4728 - chr->chr_disconnect = tcp_chr_disconnect; 4729 - chr->get_msgfds = tcp_get_msgfds; 4730 - chr->set_msgfds = tcp_set_msgfds; 4731 - chr->chr_add_client = tcp_chr_add_client; 4732 - chr->chr_add_watch = tcp_chr_add_watch; 4733 - chr->chr_update_read_handler = tcp_chr_update_read_handler; 4734 4853 /* be isn't opened until we get a connection */ 4735 4854 *be_opened = false; 4736 4855 ··· 4778 4897 } 4779 4898 } 4780 4899 4781 - return chr; 4900 + return; 4782 4901 4783 - error: 4902 + error: 4784 4903 if (sioc) { 4785 4904 object_unref(OBJECT(sioc)); 4786 4905 } 4787 4906 if (s->tls_creds) { 4788 4907 object_unref(OBJECT(s->tls_creds)); 4789 4908 } 4790 - g_free(s); 4791 - qemu_chr_free_common(chr); 4792 - return NULL; 4793 4909 } 4794 4910 4795 - static CharDriverState *qmp_chardev_open_udp(const char *id, 4796 - ChardevBackend *backend, 4797 - ChardevReturn *ret, 4798 - bool *be_opened, 4799 - Error **errp) 4911 + static const CharDriver socket_driver = { 4912 + .kind = CHARDEV_BACKEND_KIND_SOCKET, 4913 + .parse = qemu_chr_parse_socket, 4914 + }; 4915 + 4916 + static void char_socket_class_init(ObjectClass *oc, void *data) 4917 + { 4918 + ChardevClass *cc = CHARDEV_CLASS(oc); 4919 + 4920 + cc->open = qmp_chardev_open_socket; 4921 + cc->chr_wait_connected = tcp_chr_wait_connected; 4922 + cc->chr_write = tcp_chr_write; 4923 + cc->chr_sync_read = tcp_chr_sync_read; 4924 + cc->chr_disconnect = tcp_chr_disconnect; 4925 + cc->get_msgfds = tcp_get_msgfds; 4926 + cc->set_msgfds = tcp_set_msgfds; 4927 + cc->chr_add_client = tcp_chr_add_client; 4928 + cc->chr_add_watch = tcp_chr_add_watch; 4929 + cc->chr_update_read_handler = tcp_chr_update_read_handler; 4930 + cc->chr_free = tcp_chr_free; 4931 + } 4932 + 4933 + static const TypeInfo char_socket_type_info = { 4934 + .name = TYPE_CHARDEV_SOCKET, 4935 + .parent = TYPE_CHARDEV, 4936 + .instance_size = sizeof(SocketChardev), 4937 + .class_init = char_socket_class_init, 4938 + }; 4939 + 4940 + static void qmp_chardev_open_udp(Chardev *chr, 4941 + ChardevBackend *backend, 4942 + bool *be_opened, 4943 + Error **errp) 4800 4944 { 4801 4945 ChardevUdp *udp = backend->u.udp.data; 4802 - ChardevCommon *common = qapi_ChardevUdp_base(udp); 4803 4946 QIOChannelSocket *sioc = qio_channel_socket_new(); 4804 4947 char *name; 4805 - CharDriverState *chr; 4948 + UdpChardev *s = UDP_CHARDEV(chr); 4806 4949 4807 4950 if (qio_channel_socket_dgram_sync(sioc, 4808 4951 udp->local, udp->remote, 4809 4952 errp) < 0) { 4810 4953 object_unref(OBJECT(sioc)); 4811 - return NULL; 4954 + return; 4812 4955 } 4813 - chr = qemu_chr_open_udp(sioc, common, be_opened, errp); 4814 4956 4815 4957 name = g_strdup_printf("chardev-udp-%s", chr->label); 4816 4958 qio_channel_set_name(QIO_CHANNEL(sioc), name); 4817 4959 g_free(name); 4818 4960 4819 - return chr; 4961 + s->ioc = QIO_CHANNEL(sioc); 4962 + /* be isn't opened until we get a connection */ 4963 + *be_opened = false; 4820 4964 } 4821 4965 4966 + static const CharDriver udp_driver = { 4967 + .kind = CHARDEV_BACKEND_KIND_UDP, 4968 + .parse = qemu_chr_parse_udp, 4969 + }; 4822 4970 4823 - bool qemu_chr_has_feature(CharDriverState *chr, 4971 + static void char_udp_class_init(ObjectClass *oc, void *data) 4972 + { 4973 + ChardevClass *cc = CHARDEV_CLASS(oc); 4974 + 4975 + cc->open = qmp_chardev_open_udp; 4976 + cc->chr_write = udp_chr_write; 4977 + cc->chr_update_read_handler = udp_chr_update_read_handler; 4978 + cc->chr_free = udp_chr_free; 4979 + } 4980 + 4981 + static const TypeInfo char_udp_type_info = { 4982 + .name = TYPE_CHARDEV_UDP, 4983 + .parent = TYPE_CHARDEV, 4984 + .instance_size = sizeof(UdpChardev), 4985 + .class_init = char_udp_class_init, 4986 + }; 4987 + 4988 + bool qemu_chr_has_feature(Chardev *chr, 4824 4989 CharDriverFeature feature) 4825 4990 { 4826 4991 return test_bit(feature, chr->features); 4827 4992 } 4828 4993 4829 - void qemu_chr_set_feature(CharDriverState *chr, 4994 + void qemu_chr_set_feature(Chardev *chr, 4830 4995 CharDriverFeature feature) 4831 4996 { 4832 4997 return set_bit(feature, chr->features); 4998 + } 4999 + 5000 + static const ChardevClass *char_get_class(const char *driver, Error **errp) 5001 + { 5002 + ObjectClass *oc; 5003 + const ChardevClass *cc; 5004 + char *typename = g_strdup_printf("chardev-%s", driver); 5005 + 5006 + oc = object_class_by_name(typename); 5007 + g_free(typename); 5008 + 5009 + if (!object_class_dynamic_cast(oc, TYPE_CHARDEV)) { 5010 + error_setg(errp, "'%s' is not a valid char driver name", driver); 5011 + return NULL; 5012 + } 5013 + 5014 + if (object_class_is_abstract(oc)) { 5015 + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver", 5016 + "abstract device type"); 5017 + return NULL; 5018 + } 5019 + 5020 + cc = CHARDEV_CLASS(oc); 5021 + if (cc->internal) { 5022 + error_setg(errp, "'%s' is not a valid char driver name", driver); 5023 + return NULL; 5024 + } 5025 + 5026 + return cc; 5027 + } 5028 + 5029 + Chardev *qemu_chardev_new(const char *id, const char *typename, 5030 + ChardevBackend *backend, Error **errp) 5031 + { 5032 + Chardev *chr = NULL; 5033 + Error *local_err = NULL; 5034 + bool be_opened = true; 5035 + 5036 + assert(g_str_has_prefix(typename, "chardev-")); 5037 + 5038 + chr = CHARDEV(object_new(typename)); 5039 + chr->label = g_strdup(id); 5040 + 5041 + qemu_char_open(chr, backend, &be_opened, &local_err); 5042 + if (local_err) { 5043 + error_propagate(errp, local_err); 5044 + object_unref(OBJECT(chr)); 5045 + return NULL; 5046 + } 5047 + 5048 + if (!chr->filename) { 5049 + chr->filename = g_strdup(typename + 8); 5050 + } 5051 + if (be_opened) { 5052 + qemu_chr_be_event(chr, CHR_EVENT_OPENED); 5053 + } 5054 + 5055 + return chr; 4833 5056 } 4834 5057 4835 5058 ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, 4836 5059 Error **errp) 4837 5060 { 4838 - ChardevReturn *ret = g_new0(ChardevReturn, 1); 4839 - CharDriverState *chr = NULL; 4840 - Error *local_err = NULL; 4841 - GSList *i; 4842 - CharDriver *cd; 4843 - bool be_opened = true; 5061 + const ChardevClass *cc; 5062 + ChardevReturn *ret; 5063 + Chardev *chr; 4844 5064 4845 5065 chr = qemu_chr_find(id); 4846 5066 if (chr) { 4847 5067 error_setg(errp, "Chardev '%s' already exists", id); 4848 - goto out_error; 5068 + return NULL; 4849 5069 } 4850 5070 4851 - for (i = backends; i; i = i->next) { 4852 - cd = i->data; 4853 - 4854 - if (cd->kind == backend->type) { 4855 - chr = cd->create(id, backend, ret, &be_opened, &local_err); 4856 - if (local_err) { 4857 - error_propagate(errp, local_err); 4858 - goto out_error; 4859 - } 4860 - break; 4861 - } 5071 + cc = char_get_class(ChardevBackendKind_lookup[backend->type], errp); 5072 + if (!cc) { 5073 + return NULL; 4862 5074 } 4863 5075 4864 - if (chr == NULL) { 4865 - assert(!i); 4866 - error_setg(errp, "chardev backend not available"); 4867 - goto out_error; 5076 + chr = qemu_chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)), 5077 + backend, errp); 5078 + if (!chr) { 5079 + return NULL; 4868 5080 } 4869 5081 4870 - chr->label = g_strdup(id); 4871 - if (!chr->filename) { 4872 - chr->filename = g_strdup(ChardevBackendKind_lookup[backend->type]); 5082 + ret = g_new0(ChardevReturn, 1); 5083 + if (CHARDEV_IS_PTY(chr)) { 5084 + ret->pty = g_strdup(chr->filename + 4); 5085 + ret->has_pty = true; 4873 5086 } 4874 - if (be_opened) { 4875 - qemu_chr_be_event(chr, CHR_EVENT_OPENED); 4876 - } 5087 + 4877 5088 QTAILQ_INSERT_TAIL(&chardevs, chr, next); 4878 5089 return ret; 4879 - 4880 - out_error: 4881 - g_free(ret); 4882 - return NULL; 4883 5090 } 4884 5091 4885 5092 void qmp_chardev_remove(const char *id, Error **errp) 4886 5093 { 4887 - CharDriverState *chr; 5094 + Chardev *chr; 4888 5095 4889 5096 chr = qemu_chr_find(id); 4890 5097 if (chr == NULL) { ··· 4895 5102 error_setg(errp, "Chardev '%s' is busy", id); 4896 5103 return; 4897 5104 } 4898 - if (chr->replay) { 5105 + if (qemu_chr_replay(chr)) { 4899 5106 error_setg(errp, 4900 5107 "Chardev '%s' cannot be unplugged in record/replay mode", id); 4901 5108 return; ··· 4905 5112 4906 5113 void qemu_chr_cleanup(void) 4907 5114 { 4908 - CharDriverState *chr, *tmp; 5115 + Chardev *chr, *tmp; 4909 5116 4910 5117 QTAILQ_FOREACH_SAFE(chr, &chardevs, next, tmp) { 4911 5118 qemu_chr_delete(chr); ··· 4914 5121 4915 5122 static void register_types(void) 4916 5123 { 4917 - register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, 4918 - qemu_chr_open_null); 4919 - register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, 4920 - qemu_chr_parse_socket, qmp_chardev_open_socket); 4921 - register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, 4922 - qmp_chardev_open_udp); 4923 - register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, 4924 - qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); 4925 - register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, 4926 - qemu_chr_parse_file_out, qmp_chardev_open_file); 4927 - register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, 4928 - qemu_chr_parse_stdio, qemu_chr_open_stdio); 4929 - #if defined HAVE_CHARDEV_SERIAL 4930 - register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, 4931 - qemu_chr_parse_serial, qmp_chardev_open_serial); 4932 - register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, 4933 - qemu_chr_parse_serial, qmp_chardev_open_serial); 5124 + static const struct { 5125 + const CharDriver *driver; 5126 + const TypeInfo *type; 5127 + } chardevs[] = { 5128 + { &null_driver, &char_null_type_info }, 5129 + { &socket_driver, &char_socket_type_info }, 5130 + { &udp_driver, &char_udp_type_info }, 5131 + { &ringbuf_driver, &char_ringbuf_type_info }, 5132 + { &file_driver, &char_file_type_info }, 5133 + { &stdio_driver, &char_stdio_type_info }, 5134 + #ifdef HAVE_CHARDEV_SERIAL 5135 + { &serial_driver, &char_serial_type_info }, 4934 5136 #endif 4935 5137 #ifdef HAVE_CHARDEV_PARPORT 4936 - register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, 4937 - qemu_chr_parse_parallel, qmp_chardev_open_parallel); 4938 - register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, 4939 - qemu_chr_parse_parallel, qmp_chardev_open_parallel); 5138 + { &parallel_driver, &char_parallel_type_info }, 4940 5139 #endif 4941 5140 #ifdef HAVE_CHARDEV_PTY 4942 - register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, 4943 - qemu_chr_open_pty); 5141 + { &pty_driver, &char_pty_type_info }, 4944 5142 #endif 4945 5143 #ifdef _WIN32 4946 - register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, 4947 - qemu_chr_open_win_con); 5144 + { &console_driver, &char_console_type_info }, 5145 + #endif 5146 + { &pipe_driver, &char_pipe_type_info }, 5147 + { &mux_driver, &char_mux_type_info }, 5148 + { &memory_driver, &char_memory_type_info } 5149 + }; 5150 + int i; 5151 + 5152 + type_register_static(&char_type_info); 5153 + #ifndef _WIN32 5154 + type_register_static(&char_fd_type_info); 5155 + #else 5156 + type_register_static(&char_win_type_info); 5157 + type_register_static(&char_win_stdio_type_info); 4948 5158 #endif 4949 - register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, 4950 - qemu_chr_parse_pipe, qemu_chr_open_pipe); 4951 - register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, 4952 - qemu_chr_open_mux); 4953 - /* Bug-compatibility: */ 4954 - register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, 4955 - qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); 5159 + for (i = 0; i < ARRAY_SIZE(chardevs); i++) { 5160 + type_register_static(chardevs[i].type); 5161 + register_char_driver(chardevs[i].driver); 5162 + } 5163 + 4956 5164 /* this must be done after machine init, since we register FEs with muxes 4957 5165 * as part of realize functions like serial_isa_realizefn when -nographic 4958 5166 * is specified
+7 -5
qemu-options.hx
··· 2430 2430 exiting QEMU with the key sequence @key{Control-c}. This option is enabled by 2431 2431 default, use @option{signal=off} to disable it. 2432 2432 2433 - @option{stdio} is not available on Windows hosts. 2434 - 2435 2433 @item -chardev braille ,id=@var{id} 2436 2434 2437 2435 Connect to a local BrlAPI server. @option{braille} does not take any options. ··· 3017 3015 version of netcat which can listen to a TCP port and send and receive 3018 3016 characters via udp. If you have a patched version of netcat which 3019 3017 activates telnet remote echo and single char transfer, then you can 3020 - use the following options to step up a netcat redirector to allow 3018 + use the following options to set up a netcat redirector to allow 3021 3019 telnet on port 5555 to access the QEMU port. 3022 3020 @table @code 3023 3021 @item QEMU Options: ··· 3400 3398 ETEXI 3401 3399 3402 3400 DEF("icount", HAS_ARG, QEMU_OPTION_icount, \ 3403 - "-icount [shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=<filename>]\n" \ 3401 + "-icount [shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=<filename>,rrsnapshot=<snapshot>]\n" \ 3404 3402 " enable virtual instruction counter with 2^N clock ticks per\n" \ 3405 3403 " instruction, enable aligning the host and virtual clocks\n" \ 3406 3404 " or disable real time cpu sleeping\n", QEMU_ARCH_ALL) 3407 3405 STEXI 3408 - @item -icount [shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename}] 3406 + @item -icount [shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename},rrsnapshot=@var{snapshot}] 3409 3407 @findex -icount 3410 3408 Enable virtual instruction counter. The virtual cpu will execute one 3411 3409 instruction every 2^@var{N} ns of virtual time. If @code{auto} is specified ··· 3438 3436 When @option{rr} option is specified deterministic record/replay is enabled. 3439 3437 Replay log is written into @var{filename} file in record mode and 3440 3438 read from this file in replay mode. 3439 + 3440 + Option rrsnapshot is used to create new vm snapshot named @var{snapshot} 3441 + at the start of execution recording. In replay mode this option is used 3442 + to load the initial VM state. 3441 3443 ETEXI 3442 3444 3443 3445 DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \
+1 -1
qmp.c
··· 616 616 bool has_skipauth, bool skipauth, bool has_tls, bool tls, 617 617 Error **errp) 618 618 { 619 - CharDriverState *s; 619 + Chardev *s; 620 620 int fd; 621 621 622 622 fd = monitor_get_fd(cur_mon, fdname, errp);
+1
qom/cpu.c
··· 415 415 k->cpu_exec_enter = cpu_common_noop; 416 416 k->cpu_exec_exit = cpu_common_noop; 417 417 k->cpu_exec_interrupt = cpu_common_exec_interrupt; 418 + set_bit(DEVICE_CATEGORY_CPU, dc->categories); 418 419 dc->realize = cpu_common_realizefn; 419 420 dc->unrealize = cpu_common_unrealizefn; 420 421 /*
+1 -1
qtest.c
··· 670 670 671 671 void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp) 672 672 { 673 - CharDriverState *chr; 673 + Chardev *chr; 674 674 675 675 chr = qemu_chr_new("qtest", qtest_chrdev); 676 676
+4 -4
replay/replay-char.c
··· 18 18 19 19 /* Char drivers that generate qemu_chr_be_write events 20 20 that should be saved into the log. */ 21 - static CharDriverState **char_drivers; 21 + static Chardev **char_drivers; 22 22 static int drivers_count; 23 23 24 24 /* Char event attributes. */ ··· 28 28 size_t len; 29 29 } CharEvent; 30 30 31 - static int find_char_driver(CharDriverState *chr) 31 + static int find_char_driver(Chardev *chr) 32 32 { 33 33 int i = 0; 34 34 for ( ; i < drivers_count ; ++i) { ··· 39 39 return -1; 40 40 } 41 41 42 - void replay_register_char_driver(CharDriverState *chr) 42 + void replay_register_char_driver(Chardev *chr) 43 43 { 44 44 if (replay_mode == REPLAY_MODE_NONE) { 45 45 return; ··· 49 49 char_drivers[drivers_count++] = chr; 50 50 } 51 51 52 - void replay_chr_be_write(CharDriverState *s, uint8_t *buf, int len) 52 + void replay_chr_be_write(Chardev *s, uint8_t *buf, int len) 53 53 { 54 54 CharEvent *event = g_malloc0(sizeof(CharEvent)); 55 55
+17
replay/replay-snapshot.c
··· 59 59 { 60 60 vmstate_register(NULL, 0, &vmstate_replay, &replay_state); 61 61 } 62 + 63 + void replay_vmstate_init(void) 64 + { 65 + if (replay_snapshot) { 66 + if (replay_mode == REPLAY_MODE_RECORD) { 67 + if (save_vmstate(cur_mon, replay_snapshot) != 0) { 68 + error_report("Could not create snapshot for icount record"); 69 + exit(1); 70 + } 71 + } else if (replay_mode == REPLAY_MODE_PLAY) { 72 + if (load_vmstate(replay_snapshot) != 0) { 73 + error_report("Could not load snapshot for icount replay"); 74 + exit(1); 75 + } 76 + } 77 + } 78 + }
+5
replay/replay.c
··· 26 26 #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) 27 27 28 28 ReplayMode replay_mode = REPLAY_MODE_NONE; 29 + char *replay_snapshot; 29 30 30 31 /* Name of replay file */ 31 32 static char *replay_filename; ··· 292 293 exit(1); 293 294 } 294 295 296 + replay_snapshot = g_strdup(qemu_opt_get(opts, "rrsnapshot")); 295 297 replay_vmstate_register(); 296 298 replay_enable(fname, mode); 297 299 ··· 345 347 g_free(replay_filename); 346 348 replay_filename = NULL; 347 349 } 350 + 351 + g_free(replay_snapshot); 352 + replay_snapshot = NULL; 348 353 349 354 replay_finish_events(); 350 355 replay_mutex_destroy();
+129 -102
spice-qemu-char.c
··· 2 2 #include "trace.h" 3 3 #include "ui/qemu-spice.h" 4 4 #include "sysemu/char.h" 5 + #include "qemu/error-report.h" 5 6 #include <spice.h> 6 7 #include <spice/protocol.h> 7 8 8 9 9 - typedef struct SpiceCharDriver { 10 - CharDriverState* chr; 11 - SpiceCharDeviceInstance sin; 10 + typedef struct SpiceChardev { 11 + Chardev parent; 12 + 13 + SpiceCharDeviceInstance sin; 12 14 bool active; 13 15 bool blocked; 14 16 const uint8_t *datapos; 15 17 int datalen; 16 - QLIST_ENTRY(SpiceCharDriver) next; 17 - } SpiceCharDriver; 18 + QLIST_ENTRY(SpiceChardev) next; 19 + } SpiceChardev; 20 + 21 + #define TYPE_CHARDEV_SPICE "chardev-spice" 22 + #define TYPE_CHARDEV_SPICEVMC "chardev-spicevmc" 23 + #define TYPE_CHARDEV_SPICEPORT "chardev-spiceport" 24 + 25 + #define SPICE_CHARDEV(obj) OBJECT_CHECK(SpiceChardev, (obj), TYPE_CHARDEV_SPICE) 18 26 19 27 typedef struct SpiceCharSource { 20 28 GSource source; 21 - SpiceCharDriver *scd; 29 + SpiceChardev *scd; 22 30 } SpiceCharSource; 23 31 24 - static QLIST_HEAD(, SpiceCharDriver) spice_chars = 32 + static QLIST_HEAD(, SpiceChardev) spice_chars = 25 33 QLIST_HEAD_INITIALIZER(spice_chars); 26 34 27 35 static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) 28 36 { 29 - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); 37 + SpiceChardev *scd = container_of(sin, SpiceChardev, sin); 38 + Chardev *chr = CHARDEV(scd); 30 39 ssize_t out = 0; 31 40 ssize_t last_out; 32 41 uint8_t* p = (uint8_t*)buf; 33 42 34 43 while (len > 0) { 35 - int can_write = qemu_chr_be_can_write(scd->chr); 44 + int can_write = qemu_chr_be_can_write(chr); 36 45 last_out = MIN(len, can_write); 37 46 if (last_out <= 0) { 38 47 break; 39 48 } 40 - qemu_chr_be_write(scd->chr, p, last_out); 49 + qemu_chr_be_write(chr, p, last_out); 41 50 out += last_out; 42 51 len -= last_out; 43 52 p += last_out; ··· 49 58 50 59 static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) 51 60 { 52 - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); 61 + SpiceChardev *scd = container_of(sin, SpiceChardev, sin); 53 62 int bytes = MIN(len, scd->datalen); 54 63 55 64 if (bytes > 0) { ··· 69 78 #if SPICE_SERVER_VERSION >= 0x000c02 70 79 static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event) 71 80 { 72 - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); 81 + SpiceChardev *scd = container_of(sin, SpiceChardev, sin); 82 + Chardev *chr = CHARDEV(scd); 73 83 int chr_event; 74 84 75 85 switch (event) { ··· 81 91 } 82 92 83 93 trace_spice_vmc_event(chr_event); 84 - qemu_chr_be_event(scd->chr, chr_event); 94 + qemu_chr_be_event(chr, chr_event); 85 95 } 86 96 #endif 87 97 88 98 static void vmc_state(SpiceCharDeviceInstance *sin, int connected) 89 99 { 90 - SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); 100 + SpiceChardev *scd = container_of(sin, SpiceChardev, sin); 101 + Chardev *chr = CHARDEV(scd); 91 102 92 - if ((scd->chr->be_open && connected) || 93 - (!scd->chr->be_open && !connected)) { 103 + if ((chr->be_open && connected) || 104 + (!chr->be_open && !connected)) { 94 105 return; 95 106 } 96 107 97 - qemu_chr_be_event(scd->chr, 108 + qemu_chr_be_event(chr, 98 109 connected ? CHR_EVENT_OPENED : CHR_EVENT_CLOSED); 99 110 } 100 111 ··· 115 126 }; 116 127 117 128 118 - static void vmc_register_interface(SpiceCharDriver *scd) 129 + static void vmc_register_interface(SpiceChardev *scd) 119 130 { 120 131 if (scd->active) { 121 132 return; ··· 126 137 trace_spice_vmc_register_interface(scd); 127 138 } 128 139 129 - static void vmc_unregister_interface(SpiceCharDriver *scd) 140 + static void vmc_unregister_interface(SpiceChardev *scd) 130 141 { 131 142 if (!scd->active) { 132 143 return; ··· 166 177 .dispatch = spice_char_source_dispatch, 167 178 }; 168 179 169 - static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond) 180 + static GSource *spice_chr_add_watch(Chardev *chr, GIOCondition cond) 170 181 { 171 - SpiceCharDriver *scd = chr->opaque; 182 + SpiceChardev *scd = SPICE_CHARDEV(chr); 172 183 SpiceCharSource *src; 173 184 174 185 assert(cond & G_IO_OUT); ··· 180 191 return (GSource *)src; 181 192 } 182 193 183 - static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 194 + static int spice_chr_write(Chardev *chr, const uint8_t *buf, int len) 184 195 { 185 - SpiceCharDriver *s = chr->opaque; 196 + SpiceChardev *s = SPICE_CHARDEV(chr); 186 197 int read_bytes; 187 198 188 199 assert(s->datalen == 0); ··· 199 210 return read_bytes; 200 211 } 201 212 202 - static void spice_chr_free(struct CharDriverState *chr) 213 + static void spice_chr_free(struct Chardev *chr) 203 214 { 204 - SpiceCharDriver *s = chr->opaque; 215 + SpiceChardev *s = SPICE_CHARDEV(chr); 205 216 206 217 vmc_unregister_interface(s); 207 218 QLIST_REMOVE(s, next); ··· 210 221 #if SPICE_SERVER_VERSION >= 0x000c02 211 222 g_free((char *)s->sin.portname); 212 223 #endif 213 - g_free(s); 214 224 } 215 225 216 - static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open) 226 + static void spice_vmc_set_fe_open(struct Chardev *chr, int fe_open) 217 227 { 218 - SpiceCharDriver *s = chr->opaque; 228 + SpiceChardev *s = SPICE_CHARDEV(chr); 219 229 if (fe_open) { 220 230 vmc_register_interface(s); 221 231 } else { ··· 223 233 } 224 234 } 225 235 226 - static void spice_port_set_fe_open(struct CharDriverState *chr, int fe_open) 236 + static void spice_port_set_fe_open(struct Chardev *chr, int fe_open) 227 237 { 228 238 #if SPICE_SERVER_VERSION >= 0x000c02 229 - SpiceCharDriver *s = chr->opaque; 239 + SpiceChardev *s = SPICE_CHARDEV(chr); 230 240 231 241 if (fe_open) { 232 242 spice_server_port_event(&s->sin, SPICE_PORT_EVENT_OPENED); ··· 236 246 #endif 237 247 } 238 248 239 - static void print_allowed_subtypes(void) 240 - { 241 - const char** psubtype; 242 - int i; 243 - 244 - fprintf(stderr, "allowed names: "); 245 - for(i=0, psubtype = spice_server_char_device_recognized_subtypes(); 246 - *psubtype != NULL; ++psubtype, ++i) { 247 - if (i == 0) { 248 - fprintf(stderr, "%s", *psubtype); 249 - } else { 250 - fprintf(stderr, ", %s", *psubtype); 251 - } 252 - } 253 - fprintf(stderr, "\n"); 254 - } 255 - 256 - static void spice_chr_accept_input(struct CharDriverState *chr) 249 + static void spice_chr_accept_input(struct Chardev *chr) 257 250 { 258 - SpiceCharDriver *s = chr->opaque; 251 + SpiceChardev *s = SPICE_CHARDEV(chr); 259 252 260 253 spice_server_char_device_wakeup(&s->sin); 261 254 } 262 255 263 - static CharDriverState *chr_open(const char *subtype, 264 - void (*set_fe_open)(struct CharDriverState *, 265 - int), 266 - ChardevCommon *backend, 267 - Error **errp) 256 + static void chr_open(Chardev *chr, const char *subtype) 268 257 { 269 - CharDriverState *chr; 270 - SpiceCharDriver *s; 258 + SpiceChardev *s = SPICE_CHARDEV(chr); 271 259 272 - chr = qemu_chr_alloc(backend, errp); 273 - if (!chr) { 274 - return NULL; 275 - } 276 - s = g_malloc0(sizeof(SpiceCharDriver)); 277 - s->chr = chr; 278 260 s->active = false; 279 261 s->sin.subtype = g_strdup(subtype); 280 - chr->opaque = s; 281 - chr->chr_write = spice_chr_write; 282 - chr->chr_add_watch = spice_chr_add_watch; 283 - chr->chr_free = spice_chr_free; 284 - chr->chr_set_fe_open = set_fe_open; 285 - chr->chr_accept_input = spice_chr_accept_input; 286 262 287 263 QLIST_INSERT_HEAD(&spice_chars, s, next); 288 - 289 - return chr; 290 264 } 291 265 292 - static CharDriverState *qemu_chr_open_spice_vmc(const char *id, 293 - ChardevBackend *backend, 294 - ChardevReturn *ret, 295 - bool *be_opened, 296 - Error **errp) 266 + static void qemu_chr_open_spice_vmc(Chardev *chr, 267 + ChardevBackend *backend, 268 + bool *be_opened, 269 + Error **errp) 297 270 { 298 271 ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data; 299 272 const char *type = spicevmc->type; 300 273 const char **psubtype = spice_server_char_device_recognized_subtypes(); 301 - ChardevCommon *common = qapi_ChardevSpiceChannel_base(spicevmc); 302 274 303 275 for (; *psubtype != NULL; ++psubtype) { 304 276 if (strcmp(type, *psubtype) == 0) { ··· 306 278 } 307 279 } 308 280 if (*psubtype == NULL) { 309 - fprintf(stderr, "spice-qemu-char: unsupported type: %s\n", type); 310 - print_allowed_subtypes(); 311 - return NULL; 281 + char *subtypes = g_strjoinv(", ", 282 + (gchar **)spice_server_char_device_recognized_subtypes()); 283 + 284 + error_setg(errp, "unsupported type name: %s", type); 285 + error_append_hint(errp, "allowed spice char type names: %s\n", 286 + subtypes); 287 + 288 + g_free(subtypes); 289 + return; 312 290 } 313 291 314 292 *be_opened = false; 315 - return chr_open(type, spice_vmc_set_fe_open, common, errp); 293 + chr_open(chr, type); 316 294 } 317 295 318 296 #if SPICE_SERVER_VERSION >= 0x000c02 319 - static CharDriverState *qemu_chr_open_spice_port(const char *id, 320 - ChardevBackend *backend, 321 - ChardevReturn *ret, 322 - bool *be_opened, 323 - Error **errp) 297 + static void qemu_chr_open_spice_port(Chardev *chr, 298 + ChardevBackend *backend, 299 + bool *be_opened, 300 + Error **errp) 324 301 { 325 302 ChardevSpicePort *spiceport = backend->u.spiceport.data; 326 303 const char *name = spiceport->fqdn; 327 - ChardevCommon *common = qapi_ChardevSpicePort_base(spiceport); 328 - CharDriverState *chr; 329 - SpiceCharDriver *s; 304 + SpiceChardev *s; 330 305 331 306 if (name == NULL) { 332 - fprintf(stderr, "spice-qemu-char: missing name parameter\n"); 333 - return NULL; 307 + error_setg(errp, "missing name parameter"); 308 + return; 334 309 } 335 310 336 - chr = chr_open("port", spice_port_set_fe_open, common, errp); 337 - if (!chr) { 338 - return NULL; 339 - } 311 + chr_open(chr, "port"); 312 + 340 313 *be_opened = false; 341 - s = chr->opaque; 314 + s = SPICE_CHARDEV(chr); 342 315 s->sin.portname = g_strdup(name); 343 - 344 - return chr; 345 316 } 346 317 347 318 void qemu_spice_register_ports(void) 348 319 { 349 - SpiceCharDriver *s; 320 + SpiceChardev *s; 350 321 351 322 QLIST_FOREACH(s, &spice_chars, next) { 352 323 if (s->sin.portname == NULL) { ··· 387 358 spiceport->fqdn = g_strdup(name); 388 359 } 389 360 361 + static void char_spice_class_init(ObjectClass *oc, void *data) 362 + { 363 + ChardevClass *cc = CHARDEV_CLASS(oc); 364 + 365 + cc->chr_write = spice_chr_write; 366 + cc->chr_add_watch = spice_chr_add_watch; 367 + cc->chr_accept_input = spice_chr_accept_input; 368 + cc->chr_free = spice_chr_free; 369 + } 370 + 371 + static const TypeInfo char_spice_type_info = { 372 + .name = TYPE_CHARDEV_SPICE, 373 + .parent = TYPE_CHARDEV, 374 + .instance_size = sizeof(SpiceChardev), 375 + .class_init = char_spice_class_init, 376 + .abstract = true, 377 + }; 378 + 379 + static void char_spicevmc_class_init(ObjectClass *oc, void *data) 380 + { 381 + ChardevClass *cc = CHARDEV_CLASS(oc); 382 + 383 + cc->open = qemu_chr_open_spice_vmc; 384 + cc->chr_set_fe_open = spice_vmc_set_fe_open; 385 + } 386 + 387 + static const TypeInfo char_spicevmc_type_info = { 388 + .name = TYPE_CHARDEV_SPICEVMC, 389 + .parent = TYPE_CHARDEV_SPICE, 390 + .class_init = char_spicevmc_class_init, 391 + }; 392 + 393 + static void char_spiceport_class_init(ObjectClass *oc, void *data) 394 + { 395 + ChardevClass *cc = CHARDEV_CLASS(oc); 396 + 397 + cc->open = qemu_chr_open_spice_port; 398 + cc->chr_set_fe_open = spice_port_set_fe_open; 399 + } 400 + 401 + static const TypeInfo char_spiceport_type_info = { 402 + .name = TYPE_CHARDEV_SPICEPORT, 403 + .parent = TYPE_CHARDEV_SPICE, 404 + .class_init = char_spiceport_class_init, 405 + }; 406 + 390 407 static void register_types(void) 391 408 { 392 - register_char_driver("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC, 393 - qemu_chr_parse_spice_vmc, qemu_chr_open_spice_vmc); 394 - register_char_driver("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT, 395 - qemu_chr_parse_spice_port, qemu_chr_open_spice_port); 409 + static const CharDriver vmc_driver = { 410 + .kind = CHARDEV_BACKEND_KIND_SPICEVMC, 411 + .parse = qemu_chr_parse_spice_vmc, 412 + }; 413 + static const CharDriver port_driver = { 414 + .kind = CHARDEV_BACKEND_KIND_SPICEPORT, 415 + .parse = qemu_chr_parse_spice_port, 416 + }; 417 + register_char_driver(&vmc_driver); 418 + register_char_driver(&port_driver); 419 + 420 + type_register_static(&char_spice_type_info); 421 + type_register_static(&char_spicevmc_type_info); 422 + type_register_static(&char_spiceport_type_info); 396 423 } 397 424 398 425 type_init(register_types);
+1 -1
stubs/monitor.c
··· 11 11 return -1; 12 12 } 13 13 14 - void monitor_init(CharDriverState *chr, int flags) 14 + void monitor_init(Chardev *chr, int flags) 15 15 { 16 16 }
+2 -2
stubs/replay.c
··· 30 30 { 31 31 } 32 32 33 - void replay_register_char_driver(CharDriverState *chr) 33 + void replay_register_char_driver(Chardev *chr) 34 34 { 35 35 } 36 36 37 - void replay_chr_be_write(CharDriverState *s, uint8_t *buf, int len) 37 + void replay_chr_be_write(Chardev *s, uint8_t *buf, int len) 38 38 { 39 39 abort(); 40 40 }
+1
target/i386/cpu.c
··· 3658 3658 DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true), 3659 3659 DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false), 3660 3660 DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true), 3661 + DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true), 3661 3662 DEFINE_PROP_END_OF_LIST() 3662 3663 }; 3663 3664
+4
target/i386/cpu.h
··· 1214 1214 bool host_features; 1215 1215 uint32_t apic_id; 1216 1216 1217 + /* Enables publishing of TSC increment and Local APIC bus frequencies to 1218 + * the guest OS in CPUID page 0x40000010, the same way that VMWare does. */ 1219 + bool vmware_cpuid_freq; 1220 + 1217 1221 /* if true the CPUID code directly forward host cache leaves to the guest */ 1218 1222 bool cache_info_passthrough; 1219 1223
+30 -6
target/i386/kvm.c
··· 982 982 } 983 983 } 984 984 985 - cpuid_data.cpuid.padding = 0; 986 - r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data); 987 - if (r) { 988 - goto fail; 989 - } 990 - 991 985 r = kvm_arch_set_tsc_khz(cs); 992 986 if (r < 0) { 993 987 goto fail; ··· 1005 999 if (r > 0) { 1006 1000 env->tsc_khz = r; 1007 1001 } 1002 + } 1003 + 1004 + if (cpu->vmware_cpuid_freq 1005 + /* Guests depend on 0x40000000 to detect this feature, so only expose 1006 + * it if KVM exposes leaf 0x40000000. (Conflicts with Hyper-V) */ 1007 + && cpu->expose_kvm 1008 + && kvm_base == KVM_CPUID_SIGNATURE 1009 + /* TSC clock must be stable and known for this feature. */ 1010 + && ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) 1011 + || env->user_tsc_khz != 0) 1012 + && env->tsc_khz != 0) { 1013 + 1014 + c = &cpuid_data.entries[cpuid_i++]; 1015 + c->function = KVM_CPUID_SIGNATURE | 0x10; 1016 + c->eax = env->tsc_khz; 1017 + /* LAPIC resolution of 1ns (freq: 1GHz) is hardcoded in KVM's 1018 + * APIC_BUS_CYCLE_NS */ 1019 + c->ebx = 1000000; 1020 + c->ecx = c->edx = 0; 1021 + 1022 + c = cpuid_find_entry(&cpuid_data.cpuid, kvm_base, 0); 1023 + c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10); 1024 + } 1025 + 1026 + cpuid_data.cpuid.nent = cpuid_i; 1027 + 1028 + cpuid_data.cpuid.padding = 0; 1029 + r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data); 1030 + if (r) { 1031 + goto fail; 1008 1032 } 1009 1033 1010 1034 if (has_xsave) {
+1
target/i386/seg_helper.c
··· 1331 1331 #endif 1332 1332 if (interrupt_request & CPU_INTERRUPT_SIPI) { 1333 1333 do_cpu_sipi(cpu); 1334 + ret = true; 1334 1335 } else if (env->hflags2 & HF2_GIF_MASK) { 1335 1336 if ((interrupt_request & CPU_INTERRUPT_SMI) && 1336 1337 !(env->hflags & HF_SMM_MASK)) {
+1 -1
tests/Makefile.include
··· 510 510 tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y) 511 511 tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y) 512 512 513 - tests/test-char$(EXESUF): tests/test-char.o qemu-char.o qemu-timer.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y) 513 + tests/test-char$(EXESUF): tests/test-char.o qemu-char.o qemu-timer.o $(test-util-obj-y) $(qtest-obj-y) $(test-block-obj-y) 514 514 tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y) 515 515 tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y) 516 516 tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
+5 -5
tests/test-char.c
··· 40 40 #ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS 41 41 static void char_stdio_test_subprocess(void) 42 42 { 43 - CharDriverState *chr; 43 + Chardev *chr; 44 44 CharBackend be; 45 45 int ret; 46 46 ··· 68 68 static void char_ringbuf_test(void) 69 69 { 70 70 QemuOpts *opts; 71 - CharDriverState *chr; 71 + Chardev *chr; 72 72 CharBackend be; 73 73 char *data; 74 74 int ret; ··· 109 109 static void char_mux_test(void) 110 110 { 111 111 QemuOpts *opts; 112 - CharDriverState *chr, *base; 112 + Chardev *chr, *base; 113 113 char *data; 114 114 FeHandler h1 = { 0, }, h2 = { 0, }; 115 115 CharBackend chr_be1, chr_be2; ··· 185 185 static void char_null_test(void) 186 186 { 187 187 Error *err = NULL; 188 - CharDriverState *chr; 188 + Chardev *chr; 189 189 CharBackend be; 190 190 int ret; 191 191 ··· 227 227 228 228 static void char_invalid_test(void) 229 229 { 230 - CharDriverState *chr; 230 + Chardev *chr; 231 231 232 232 chr = qemu_chr_new("label-invalid", "invalid"); 233 233 g_assert_null(chr);
+2 -2
tests/vhost-user-test.c
··· 454 454 static void test_server_create_chr(TestServer *server, const gchar *opt) 455 455 { 456 456 gchar *chr_path; 457 - CharDriverState *chr; 457 + Chardev *chr; 458 458 459 459 chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt); 460 460 chr = qemu_chr_new(server->chr_name, chr_path); ··· 486 486 static gboolean _test_server_free(TestServer *server) 487 487 { 488 488 int i; 489 - CharDriverState *chr = qemu_chr_fe_get_driver(&server->chr); 489 + Chardev *chr = qemu_chr_fe_get_driver(&server->chr); 490 490 491 491 qemu_chr_fe_deinit(&server->chr); 492 492 qemu_chr_delete(chr);
+2
translate-all.c
··· 1290 1290 /* flush must be done */ 1291 1291 tb_flush(cpu); 1292 1292 mmap_unlock(); 1293 + /* Make the execution loop process the flush as soon as possible. */ 1294 + cpu->exception_index = EXCP_INTERRUPT; 1293 1295 cpu_loop_exit(cpu); 1294 1296 } 1295 1297
+66 -45
ui/console.c
··· 158 158 int esc_params[MAX_ESC_PARAMS]; 159 159 int nb_esc_params; 160 160 161 - CharDriverState *chr; 161 + Chardev *chr; 162 162 /* fifo for key pressed */ 163 163 QEMUFIFO out_fifo; 164 164 uint8_t out_fifo_buf[16]; ··· 183 183 static bool cursor_visible_phase; 184 184 static QEMUTimer *cursor_timer; 185 185 186 - static void text_console_do_init(CharDriverState *chr, DisplayState *ds); 186 + static void text_console_do_init(Chardev *chr, DisplayState *ds); 187 187 static void dpy_refresh(DisplayState *s); 188 188 static DisplayState *get_alloc_displaystate(void); 189 189 static void text_console_update_cursor_timer(void); ··· 1046 1046 } 1047 1047 } 1048 1048 1049 - static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) 1049 + typedef struct VCChardev { 1050 + Chardev parent; 1051 + QemuConsole *console; 1052 + } VCChardev; 1053 + 1054 + #define TYPE_CHARDEV_VC "chardev-vc" 1055 + #define VC_CHARDEV(obj) OBJECT_CHECK(VCChardev, (obj), TYPE_CHARDEV_VC) 1056 + 1057 + static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len) 1050 1058 { 1051 - QemuConsole *s = chr->opaque; 1059 + VCChardev *drv = VC_CHARDEV(chr); 1060 + QemuConsole *s = drv->console; 1052 1061 int i; 1062 + 1063 + if (!s->ds) { 1064 + return 0; 1065 + } 1053 1066 1054 1067 s->update_x0 = s->width * FONT_WIDTH; 1055 1068 s->update_y0 = s->height * FONT_HEIGHT; ··· 1129 1142 *q++ = '['; 1130 1143 *q++ = keysym & 0xff; 1131 1144 } else if (s->echo && (keysym == '\r' || keysym == '\n')) { 1132 - console_puts(s->chr, (const uint8_t *) "\r", 1); 1145 + vc_chr_write(s->chr, (const uint8_t *) "\r", 1); 1133 1146 *q++ = '\n'; 1134 1147 } else { 1135 1148 *q++ = keysym; 1136 1149 } 1137 1150 if (s->echo) { 1138 - console_puts(s->chr, buf, q - buf); 1151 + vc_chr_write(s->chr, buf, q - buf); 1139 1152 } 1140 1153 be = s->chr->be; 1141 1154 if (be && be->chr_read) { ··· 1952 1965 return con ? surface_height(con->surface) : fallback; 1953 1966 } 1954 1967 1955 - static void text_console_set_echo(CharDriverState *chr, bool echo) 1968 + static void vc_chr_set_echo(Chardev *chr, bool echo) 1956 1969 { 1957 - QemuConsole *s = chr->opaque; 1970 + VCChardev *drv = VC_CHARDEV(chr); 1971 + QemuConsole *s = drv->console; 1958 1972 1959 1973 s->echo = echo; 1960 1974 } ··· 1992 2006 .text_update = text_console_update, 1993 2007 }; 1994 2008 1995 - static void text_console_do_init(CharDriverState *chr, DisplayState *ds) 2009 + static void text_console_do_init(Chardev *chr, DisplayState *ds) 1996 2010 { 1997 - QemuConsole *s; 2011 + VCChardev *drv = VC_CHARDEV(chr); 2012 + QemuConsole *s = drv->console; 1998 2013 int g_width = 80 * FONT_WIDTH; 1999 2014 int g_height = 24 * FONT_HEIGHT; 2000 2015 2001 - s = chr->opaque; 2002 - 2003 - chr->chr_write = console_puts; 2004 - 2005 2016 s->out_fifo.buf = s->out_fifo_buf; 2006 2017 s->out_fifo.buf_size = sizeof(s->out_fifo_buf); 2007 2018 s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s); ··· 2041 2052 2042 2053 s->t_attrib.bgcol = QEMU_COLOR_BLUE; 2043 2054 len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label); 2044 - console_puts(chr, (uint8_t*)msg, len); 2055 + vc_chr_write(chr, (uint8_t *)msg, len); 2045 2056 s->t_attrib = s->t_attrib_default; 2046 2057 } 2047 2058 2048 2059 qemu_chr_be_generic_open(chr); 2049 2060 } 2050 2061 2051 - static CharDriverState *text_console_init(ChardevVC *vc, Error **errp) 2062 + static const CharDriver vc_driver; 2063 + 2064 + static void vc_chr_open(Chardev *chr, 2065 + ChardevBackend *backend, 2066 + bool *be_opened, 2067 + Error **errp) 2052 2068 { 2053 - ChardevCommon *common = qapi_ChardevVC_base(vc); 2054 - CharDriverState *chr; 2069 + ChardevVC *vc = backend->u.vc.data; 2070 + VCChardev *drv = VC_CHARDEV(chr); 2055 2071 QemuConsole *s; 2056 2072 unsigned width = 0; 2057 2073 unsigned height = 0; 2058 2074 2059 - chr = qemu_chr_alloc(common, errp); 2060 - if (!chr) { 2061 - return NULL; 2062 - } 2063 - 2064 2075 if (vc->has_width) { 2065 2076 width = vc->width; 2066 2077 } else if (vc->has_cols) { ··· 2082 2093 } 2083 2094 2084 2095 if (!s) { 2085 - g_free(chr); 2086 2096 error_setg(errp, "cannot create text console"); 2087 - return NULL; 2097 + return; 2088 2098 } 2089 2099 2090 2100 s->chr = chr; 2091 - chr->opaque = s; 2092 - chr->chr_set_echo = text_console_set_echo; 2101 + drv->console = s; 2093 2102 2094 2103 if (display_state) { 2095 2104 text_console_do_init(chr, display_state); 2096 2105 } 2097 - return chr; 2098 - } 2099 2106 2100 - static VcHandler *vc_handler = text_console_init; 2101 - 2102 - static CharDriverState *vc_init(const char *id, ChardevBackend *backend, 2103 - ChardevReturn *ret, bool *be_opened, 2104 - Error **errp) 2105 - { 2106 2107 /* console/chardev init sometimes completes elsewhere in a 2nd 2107 2108 * stage, so defer OPENED events until they are fully initialized 2108 2109 */ 2109 2110 *be_opened = false; 2110 - return vc_handler(backend->u.vc.data, errp); 2111 - } 2112 - 2113 - void register_vc_handler(VcHandler *handler) 2114 - { 2115 - vc_handler = handler; 2116 2111 } 2117 2112 2118 2113 void qemu_console_resize(QemuConsole *s, int width, int height) ··· 2150 2145 return pf; 2151 2146 } 2152 2147 2153 - static void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, 2154 - Error **errp) 2148 + void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp) 2155 2149 { 2156 2150 int val; 2157 2151 ChardevVC *vc; ··· 2191 2185 .class_size = sizeof(QemuConsoleClass), 2192 2186 }; 2193 2187 2188 + static void char_vc_class_init(ObjectClass *oc, void *data) 2189 + { 2190 + ChardevClass *cc = CHARDEV_CLASS(oc); 2191 + 2192 + cc->open = vc_chr_open; 2193 + cc->chr_write = vc_chr_write; 2194 + cc->chr_set_echo = vc_chr_set_echo; 2195 + } 2196 + 2197 + static const TypeInfo char_vc_type_info = { 2198 + .name = TYPE_CHARDEV_VC, 2199 + .parent = TYPE_CHARDEV, 2200 + .instance_size = sizeof(VCChardev), 2201 + .class_init = char_vc_class_init, 2202 + }; 2203 + 2204 + void qemu_console_early_init(void) 2205 + { 2206 + /* set the default vc driver */ 2207 + if (!object_class_by_name(TYPE_CHARDEV_VC)) { 2208 + type_register(&char_vc_type_info); 2209 + register_char_driver(&vc_driver); 2210 + } 2211 + } 2212 + 2213 + static const CharDriver vc_driver = { 2214 + .kind = CHARDEV_BACKEND_KIND_VC, 2215 + .parse = qemu_chr_parse_vc, 2216 + }; 2194 2217 2195 2218 static void register_types(void) 2196 2219 { 2197 2220 type_register_static(&qemu_console_info); 2198 - register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc, 2199 - vc_init); 2200 2221 } 2201 2222 2202 2223 type_init(register_types);
+57 -29
ui/gtk.c
··· 181 181 bool ignore_keys; 182 182 }; 183 183 184 + typedef struct VCChardev { 185 + Chardev parent; 186 + VirtualConsole *console; 187 + bool echo; 188 + } VCChardev; 189 + 190 + #define TYPE_CHARDEV_VC "chardev-vc" 191 + #define VC_CHARDEV(obj) OBJECT_CHECK(VCChardev, (obj), TYPE_CHARDEV_VC) 192 + 184 193 static void gd_grab_pointer(VirtualConsole *vc, const char *reason); 185 194 static void gd_ungrab_pointer(GtkDisplayState *s); 186 195 static void gd_grab_keyboard(VirtualConsole *vc, const char *reason); ··· 1683 1692 } 1684 1693 } 1685 1694 1686 - static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len) 1695 + static int gd_vc_chr_write(Chardev *chr, const uint8_t *buf, int len) 1687 1696 { 1688 - VirtualConsole *vc = chr->opaque; 1697 + VCChardev *vcd = VC_CHARDEV(chr); 1698 + VirtualConsole *vc = vcd->console; 1689 1699 1690 1700 vte_terminal_feed(VTE_TERMINAL(vc->vte.terminal), (const char *)buf, len); 1691 1701 return len; 1692 1702 } 1693 1703 1694 - static void gd_vc_chr_set_echo(CharDriverState *chr, bool echo) 1704 + static void gd_vc_chr_set_echo(Chardev *chr, bool echo) 1695 1705 { 1696 - VirtualConsole *vc = chr->opaque; 1706 + VCChardev *vcd = VC_CHARDEV(chr); 1707 + VirtualConsole *vc = vcd->console; 1697 1708 1698 - vc->vte.echo = echo; 1709 + if (vc) { 1710 + vc->vte.echo = echo; 1711 + } else { 1712 + vcd->echo = echo; 1713 + } 1699 1714 } 1700 1715 1701 1716 static int nb_vcs; 1702 - static CharDriverState *vcs[MAX_VCS]; 1717 + static Chardev *vcs[MAX_VCS]; 1718 + static const CharDriver gd_vc_driver; 1703 1719 1704 - static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp) 1720 + static void gd_vc_open(Chardev *chr, 1721 + ChardevBackend *backend, 1722 + bool *be_opened, 1723 + Error **errp) 1705 1724 { 1706 - ChardevCommon *common = qapi_ChardevVC_base(vc); 1707 - CharDriverState *chr; 1708 - 1709 1725 if (nb_vcs == MAX_VCS) { 1710 1726 error_setg(errp, "Maximum number of consoles reached"); 1711 - return NULL; 1727 + return; 1712 1728 } 1713 1729 1714 - chr = qemu_chr_alloc(common, errp); 1715 - if (!chr) { 1716 - return NULL; 1717 - } 1718 - 1719 - chr->chr_write = gd_vc_chr_write; 1720 - chr->chr_set_echo = gd_vc_chr_set_echo; 1730 + vcs[nb_vcs++] = chr; 1721 1731 1722 - /* Temporary, until gd_vc_vte_init runs. */ 1723 - chr->opaque = g_new0(VirtualConsole, 1); 1732 + /* console/chardev init sometimes completes elsewhere in a 2nd 1733 + * stage, so defer OPENED events until they are fully initialized 1734 + */ 1735 + *be_opened = false; 1736 + } 1724 1737 1725 - vcs[nb_vcs++] = chr; 1738 + static void char_gd_vc_class_init(ObjectClass *oc, void *data) 1739 + { 1740 + ChardevClass *cc = CHARDEV_CLASS(oc); 1726 1741 1727 - return chr; 1742 + cc->open = gd_vc_open; 1743 + cc->chr_write = gd_vc_chr_write; 1744 + cc->chr_set_echo = gd_vc_chr_set_echo; 1728 1745 } 1729 1746 1747 + static const TypeInfo char_gd_vc_type_info = { 1748 + .name = TYPE_CHARDEV_VC, 1749 + .parent = TYPE_CHARDEV, 1750 + .instance_size = sizeof(VCChardev), 1751 + .class_init = char_gd_vc_class_init, 1752 + }; 1753 + 1754 + static const CharDriver gd_vc_driver = { 1755 + .kind = CHARDEV_BACKEND_KIND_VC, 1756 + .parse = qemu_chr_parse_vc, 1757 + }; 1758 + 1730 1759 static gboolean gd_vc_in(VteTerminal *terminal, gchar *text, guint size, 1731 1760 gpointer user_data) 1732 1761 { ··· 1755 1784 } 1756 1785 1757 1786 static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc, 1758 - CharDriverState *chr, int idx, 1787 + Chardev *chr, int idx, 1759 1788 GSList *group, GtkWidget *view_menu) 1760 1789 { 1761 1790 char buffer[32]; 1762 1791 GtkWidget *box; 1763 1792 GtkWidget *scrollbar; 1764 1793 GtkAdjustment *vadjustment; 1765 - VirtualConsole *tmp_vc = chr->opaque; 1794 + VCChardev *vcd = VC_CHARDEV(chr); 1766 1795 1767 1796 vc->s = s; 1768 - vc->vte.echo = tmp_vc->vte.echo; 1769 - 1797 + vc->vte.echo = vcd->echo; 1770 1798 vc->vte.chr = chr; 1771 - chr->opaque = vc; 1772 - g_free(tmp_vc); 1799 + vcd->console = vc; 1773 1800 1774 1801 snprintf(buffer, sizeof(buffer), "vc%d", idx); 1775 1802 vc->label = g_strdup_printf("%s", vc->vte.chr->label ··· 2325 2352 } 2326 2353 2327 2354 #if defined(CONFIG_VTE) 2328 - register_vc_handler(gd_vc_handler); 2355 + type_register(&char_gd_vc_type_info); 2356 + register_char_driver(&gd_vc_driver); 2329 2357 #endif 2330 2358 }
+13 -46
vl.c
··· 151 151 static int no_frame = 0; 152 152 int no_quit = 0; 153 153 static bool grab_on_hover; 154 - CharDriverState *serial_hds[MAX_SERIAL_PORTS]; 155 - CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; 156 - CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; 157 - CharDriverState *sclp_hds[MAX_SCLP_CONSOLES]; 154 + Chardev *serial_hds[MAX_SERIAL_PORTS]; 155 + Chardev *parallel_hds[MAX_PARALLEL_PORTS]; 156 + Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES]; 157 + Chardev *sclp_hds[MAX_SCLP_CONSOLES]; 158 158 int win2k_install_hack = 0; 159 159 int singlestep = 0; 160 160 int smp_cpus = 1; ··· 465 465 }, { 466 466 .name = "rrfile", 467 467 .type = QEMU_OPT_STRING, 468 + }, { 469 + .name = "rrsnapshot", 470 + .type = QEMU_OPT_STRING, 468 471 }, 469 472 { /* end of list */ } 470 473 }, ··· 512 515 }, 513 516 }; 514 517 515 - #ifdef CONFIG_LIBISCSI 516 - static QemuOptsList qemu_iscsi_opts = { 517 - .name = "iscsi", 518 - .head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head), 519 - .desc = { 520 - { 521 - .name = "user", 522 - .type = QEMU_OPT_STRING, 523 - .help = "username for CHAP authentication to target", 524 - },{ 525 - .name = "password", 526 - .type = QEMU_OPT_STRING, 527 - .help = "password for CHAP authentication to target", 528 - },{ 529 - .name = "password-secret", 530 - .type = QEMU_OPT_STRING, 531 - .help = "ID of the secret providing password for CHAP " 532 - "authentication to target", 533 - },{ 534 - .name = "header-digest", 535 - .type = QEMU_OPT_STRING, 536 - .help = "HeaderDigest setting. " 537 - "{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}", 538 - },{ 539 - .name = "initiator-name", 540 - .type = QEMU_OPT_STRING, 541 - .help = "Initiator iqn name to use when connecting", 542 - },{ 543 - .name = "timeout", 544 - .type = QEMU_OPT_NUMBER, 545 - .help = "Request timeout in seconds (default 0 = no timeout)", 546 - }, 547 - { /* end of list */ } 548 - }, 549 - }; 550 - #endif 551 - 552 518 /** 553 519 * Get machine options 554 520 * ··· 2356 2322 2357 2323 static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) 2358 2324 { 2359 - CharDriverState *chr; 2325 + Chardev *chr; 2360 2326 const char *chardev; 2361 2327 const char *mode; 2362 2328 int flags; ··· 3042 3008 qemu_add_opts(&qemu_icount_opts); 3043 3009 qemu_add_opts(&qemu_semihosting_config_opts); 3044 3010 qemu_add_opts(&qemu_fw_cfg_opts); 3045 - #ifdef CONFIG_LIBISCSI 3046 - qemu_add_opts(&qemu_iscsi_opts); 3047 - #endif 3048 3011 module_call_init(MODULE_INIT_OPTS); 3049 3012 3050 3013 runstate_init(); ··· 4289 4252 sdl_display_early_init(request_opengl); 4290 4253 } 4291 4254 4255 + qemu_console_early_init(); 4256 + 4292 4257 if (request_opengl == 1 && display_opengl == 0) { 4293 4258 #if defined(CONFIG_OPENGL) 4294 4259 error_report("OpenGL is not supported by the display"); ··· 4634 4599 replay_checkpoint(CHECKPOINT_RESET); 4635 4600 qemu_system_reset(VMRESET_SILENT); 4636 4601 register_global_state(); 4637 - if (loadvm) { 4602 + if (replay_mode != REPLAY_MODE_NONE) { 4603 + replay_vmstate_init(); 4604 + } else if (loadvm) { 4638 4605 if (load_vmstate(loadvm) < 0) { 4639 4606 autostart = 0; 4640 4607 }
+1 -1
xen-common-stub.c
··· 9 9 #include "qemu-common.h" 10 10 #include "hw/xen/xen.h" 11 11 12 - void xenstore_store_pv_console_info(int i, CharDriverState *chr) 12 + void xenstore_store_pv_console_info(int i, Chardev *chr) 13 13 { 14 14 }
+2 -2
xen-common.c
··· 25 25 do { } while (0) 26 26 #endif 27 27 28 - static int store_dev_info(int domid, CharDriverState *cs, const char *string) 28 + static int store_dev_info(int domid, Chardev *cs, const char *string) 29 29 { 30 30 struct xs_handle *xs = NULL; 31 31 char *path = NULL; ··· 74 74 return ret; 75 75 } 76 76 77 - void xenstore_store_pv_console_info(int i, CharDriverState *chr) 77 + void xenstore_store_pv_console_info(int i, Chardev *chr) 78 78 { 79 79 if (i == 0) { 80 80 store_dev_info(xen_domid, chr, "/console");