From ac8c19ba742fcbc3d64a5390b32acc6479edd7e1 Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Tue, 24 Jan 2017 10:17:41 +0300 Subject: savevm: add public save_vmstate function This patch introduces save_vmstate function to allow saving and loading vmstates from the replay module. Signed-off-by: Pavel Dovgalyuk Message-Id: <20170124071741.4572.13714.stgit@PASHA-ISP> Signed-off-by: Paolo Bonzini --- include/sysemu/sysemu.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index ff8ffb5..4ef2eb0 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -74,6 +74,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify); void qemu_remove_machine_init_done_notifier(Notifier *notify); void hmp_savevm(Monitor *mon, const QDict *qdict); +int save_vmstate(Monitor *mon, const char *name); int load_vmstate(const char *name); void hmp_delvm(Monitor *mon, const QDict *qdict); void hmp_info_snapshots(Monitor *mon, const QDict *qdict); -- cgit v1.1 From 9c2037d0a41d3d55b17a68e42e815be45036d8d2 Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Tue, 24 Jan 2017 10:17:47 +0300 Subject: replay: save/load initial state This patch implements initial vmstate creation or loading at the start of record/replay. It is needed for rewinding the execution in the replay mode. v4 changes: - snapshots are not created by default anymore v3 changes: - added rrsnapshot option Signed-off-by: Pavel Dovgalyuk Message-Id: <20170124071746.4572.61449.stgit@PASHA-ISP> Signed-off-by: Paolo Bonzini --- include/sysemu/replay.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index abb35ca..740b425 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -43,6 +43,9 @@ typedef struct ReplayNetState ReplayNetState; extern ReplayMode replay_mode; +/* Name of the initial VM snapshot */ +extern char *replay_snapshot; + /* Replay process control functions */ /*! Enables recording or saving event log with specified parameters */ @@ -149,4 +152,10 @@ void replay_unregister_net(ReplayNetState *rns); void replay_net_packet_event(ReplayNetState *rns, unsigned flags, const struct iovec *iov, int iovcnt); +/* VM state operations */ + +/*! Called at the start of execution. + Loads or saves initial vmstate depending on execution mode. */ +void replay_vmstate_init(void); + #endif -- cgit v1.1 From 07bfa354772f2de67008dc66c201b627acff0106 Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Thu, 26 Jan 2017 15:34:29 +0300 Subject: apic: save apic_delivered flag This patch implements saving/restoring of static apic_delivered variable. v8: saving static variable only for one of the APICs Signed-off-by: Pavel Dovgalyuk Message-Id: <20170126123429.5412.94368.stgit@PASHA-ISP> Signed-off-by: Paolo Bonzini --- include/hw/i386/apic_internal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h index 1209eb4..20ad28c 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -189,6 +189,8 @@ struct APICCommonState { DeviceState *vapic; hwaddr vapic_paddr; /* note: persistence via kvmvapic */ bool legacy_instance_id; + + int apic_irq_delivered; /* for saving static variable */ }; typedef struct VAPICState { -- cgit v1.1 From 57bb40c9db408f692ec0a5365a141524b5cd7680 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Mon, 16 Jan 2017 16:40:05 +0800 Subject: memory: hmp: add "-f" for "info mtree" Adding one more option "-f" for "info mtree" to dump the flat views of all the address spaces. This will be useful to debug the memory rendering logic, also it'll be much easier with it to know what memory region is handling what address range. Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Peter Xu Message-Id: <1484556005-29701-3-git-send-email-peterx@redhat.com> Signed-off-by: Paolo Bonzini --- include/exec/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/exec/memory.h b/include/exec/memory.h index a10044f..987f925 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1250,7 +1250,7 @@ void memory_global_dirty_log_start(void); */ void memory_global_dirty_log_stop(void); -void mtree_info(fprintf_function mon_printf, void *f); +void mtree_info(fprintf_function mon_printf, void *f, bool flatview); /** * memory_region_dispatch_read: perform a read directly to the specified -- cgit v1.1 From 50de920b372b21e129667e16e016329d7204a7b2 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 26 Jan 2017 02:44:14 +0100 Subject: hw/isa/lpc_ich9: add SMI feature negotiation via fw_cfg Introduce the following fw_cfg files: - "etc/smi/supported-features": a little endian uint64_t feature bitmap, presenting the features known by the host to the guest. Read-only for the guest. The content of this file will be determined via bit-granularity ICH9-LPC device properties, to be introduced later. For now, the bitmask is left zeroed. The bits will be set from machine type compat properties and on the QEMU command line, hence this file is not migrated. - "etc/smi/requested-features": a little endian uint64_t feature bitmap, representing the features the guest would like to request. Read-write for the guest. The guest can freely (re)write this file, it has no direct consequence. Initial value is zero. A nonzero value causes the SMI-related fw_cfg files and fields that are under guest influence to be migrated. - "etc/smi/features-ok": contains a uint8_t value, and it is read-only for the guest. When the guest selects the associated fw_cfg key, the guest features are validated against the host features. In case of error, the negotiation doesn't proceed, and the "features-ok" file remains zero. In case of success, the "features-ok" file becomes (uint8_t)1, and the negotiated features are locked down internally (to which no further changes are possible until reset). The initial value is zero. A nonzero value causes the SMI-related fw_cfg files and fields that are under guest influence to be migrated. The C-language fields backing the "supported-features" and "requested-features" files are uint8_t arrays. This is because they carry guest-side representation (our choice is little endian), while VMSTATE_UINT64() assumes / implies host-side endianness for any uint64_t fields. If we migrate a guest between hosts with different endiannesses (which is possible with TCG), then the host-side value is preserved, and the host-side representation is translated. This would be visible to the guest through fw_cfg, unless we used plain byte arrays. So we do. Cc: "Michael S. Tsirkin" Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov Message-Id: <20170126014416.11211-2-lersek@redhat.com> Signed-off-by: Paolo Bonzini --- include/hw/i386/ich9.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index 5fd7e97..da11187 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -64,6 +64,16 @@ typedef struct ICH9LPCState { uint8_t rst_cnt; MemoryRegion rst_cnt_mem; + /* SMI feature negotiation via fw_cfg */ + uint64_t smi_host_features; /* guest-invisible, host endian */ + uint8_t smi_host_features_le[8]; /* guest-visible, read-only, little + * endian uint64_t */ + uint8_t smi_guest_features_le[8]; /* guest-visible, read-write, little + * endian uint64_t */ + uint8_t smi_features_ok; /* guest-visible, read-only; selecting it + * triggers feature lockdown */ + uint64_t smi_negotiated_features; /* guest-invisible, host endian */ + /* isa bus */ ISABus *isa_bus; MemoryRegion rcrb_mem; /* root complex register block */ -- cgit v1.1 From 5ce45c7a2b15cda0a4d8f6c38c4036df25dc9c42 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 26 Jan 2017 02:44:15 +0100 Subject: hw/isa/lpc_ich9: add broadcast SMI feature The generic edk2 SMM infrastructure prefers EFI_SMM_CONTROL2_PROTOCOL.Trigger() to inject an SMI on each processor. If Trigger() only brings the current processor into SMM, then edk2 handles it in the following ways: (1) If Trigger() is executed by the BSP (which is guaranteed before ExitBootServices(), but is not necessarily true at runtime), then: (a) If edk2 has been configured for "traditional" SMM synchronization, then the BSP sends directed SMIs to the APs with APIC delivery, bringing them into SMM individually. Then the BSP runs the SMI handler / dispatcher. (b) If edk2 has been configured for "relaxed" SMM synchronization, then the APs that are not already in SMM are not brought in, and the BSP runs the SMI handler / dispatcher. (2) If Trigger() is executed by an AP (which is possible after ExitBootServices(), and can be forced e.g. by "taskset -c 1 efibootmgr"), then the AP in question brings in the BSP with a directed SMI, and the BSP runs the SMI handler / dispatcher. The smaller problem with (1a) and (2) is that the BSP and AP synchronization is slow. For example, the "taskset -c 1 efibootmgr" command from (2) can take more than 3 seconds to complete, because efibootmgr accesses non-volatile UEFI variables intensively. The larger problem is that QEMU's current behavior diverges from the behavior usually seen on physical hardware, and that keeps exposing obscure corner cases, race conditions and other instabilities in edk2, which generally expects / prefers a software SMI to affect all CPUs at once. Therefore introduce the "broadcast SMI" feature that causes QEMU to inject the SMI on all VCPUs. While the original posting of this patch only intended to speed up (2), based on our recent "stress testing" of SMM this patch actually provides functional improvements. Cc: "Michael S. Tsirkin" Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov Message-Id: <20170126014416.11211-3-lersek@redhat.com> Signed-off-by: Paolo Bonzini --- include/hw/i386/ich9.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index da11187..18dcca7 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -250,4 +250,7 @@ Object *ich9_lpc_find(void); #define ICH9_SMB_HST_D1 0x06 #define ICH9_SMB_HOST_BLOCK_DB 0x07 +/* bit positions used in fw_cfg SMI feature negotiation */ +#define ICH9_LPC_SMI_F_BROADCAST_BIT 0 + #endif /* HW_ICH9_H */ -- cgit v1.1 From b8bab8eb6934cbf6577a18a9c5657d7707379ac0 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 26 Jan 2017 02:44:16 +0100 Subject: hw/isa/lpc_ich9: negotiate SMI broadcast on pc-q35-2.9+ machine types Cc: "Michael S. Tsirkin" Cc: Eduardo Habkost Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov Message-Id: <20170126014416.11211-4-lersek@redhat.com> Signed-off-by: Paolo Bonzini --- include/hw/i386/pc.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 5a20c5e..b89441d 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -381,6 +381,12 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .property = "x-mach-use-reliable-get-clock",\ .value = "off",\ },\ + {\ + .driver = "ICH9-LPC",\ + .property = "x-smi-broadcast",\ + .value = "off",\ + },\ + #define PC_COMPAT_2_7 \ HW_COMPAT_2_7 \ -- cgit v1.1 From ba31cc7226ebcee639f18faa90c1542bd364fba3 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 20 Jan 2017 14:01:16 +0100 Subject: Introduce DEVICE_CATEGORY_CPU for CPU devices Now that CPUs show up in the help text of "-device ?", we should group them into an appropriate category. Signed-off-by: Thomas Huth Reviewed-by: Eduardo Habkost Message-Id: <1484917276-7107-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- include/hw/qdev-core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 2c97347..b44b476 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -26,6 +26,7 @@ typedef enum DeviceCategory { DEVICE_CATEGORY_DISPLAY, DEVICE_CATEGORY_SOUND, DEVICE_CATEGORY_MISC, + DEVICE_CATEGORY_CPU, DEVICE_CATEGORY_MAX } DeviceCategory; -- cgit v1.1 From 482652502e98b1d570de0585f01dd55e35fdebfb Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 20 Jan 2017 17:25:26 +0100 Subject: block: Fix target variable of BLKSECTGET ioctl Commit 6f6071745bd0 ("raw-posix: Fetch max sectors for host block device") introduced a routine to call the kernel BLKSECTGET ioctl, which stores the result back to user space. However, the size of the data returned depends on the routine handling the ioctl. The (compat_)blkdev_ioctl returns a short, while sg_ioctl returns an int. Thus, on big-endian systems, we can find ourselves accidentally shifting the result to a much larger value. (On s390x, a short is 16 bits while an int is 32 bits.) Also, the two ioctl handlers return values in different scales (block returns sectors, while sg returns bytes), so some tweaking of the outputs is required such that hdev_get_max_transfer_length returns a value in a consistent set of units. Signed-off-by: Eric Farman Message-Id: <20170120162527.66075-3-farman@linux.vnet.ibm.com> Reviewed-by: Fam Zheng Signed-off-by: Paolo Bonzini --- include/block/block.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index 8b0dcda..4e81f20 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -116,6 +116,7 @@ typedef struct HDGeometry { #define BDRV_REQUEST_MAX_SECTORS MIN(SIZE_MAX >> BDRV_SECTOR_BITS, \ INT_MAX >> BDRV_SECTOR_BITS) +#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS) /* * Allocation status flags -- cgit v1.1 From 0b564e6f53b42cf036d09dafa5037e6be1395bda Mon Sep 17 00:00:00 2001 From: Phil Dennis-Jordan Date: Fri, 20 Jan 2017 15:11:36 +0100 Subject: pc: Enable vmware-cpuid-freq CPU option for 2.9+ machine types Signed-off-by: Phil Dennis-Jordan Message-Id: <1484921496-11257-4-git-send-email-phil@philjordan.eu> Signed-off-by: Paolo Bonzini --- include/hw/i386/pc.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index b89441d..7c0f5a7 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -386,7 +386,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .property = "x-smi-broadcast",\ .value = "off",\ },\ - + {\ + .driver = TYPE_X86_CPU,\ + .property = "vmware-cpuid-freq",\ + .value = "off",\ + }, #define PC_COMPAT_2_7 \ HW_COMPAT_2_7 \ -- cgit v1.1 From 943b468434e26887a78ab323c7682b8722c2b178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 16 Dec 2016 11:49:45 +0100 Subject: char: add qemu_chr_fe_add_watch() Returns description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 0a14942..b6e3618 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -258,6 +258,8 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...) * @cond the condition to poll for * @func the function to call when the condition happens * @user_data the opaque pointer to pass to @func + * + * Returns: the source tag */ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, GIOFunc func, void *user_data); -- cgit v1.1 From 0b812f31925f2ed50eb54d2be6ac9291bf67b890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 21 Oct 2016 16:07:45 +0300 Subject: char: use a const CharDriver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to allocate & copy fields, let's use static const struct instead. Add an alias field to the CharDriver structure to cover the cases where we previously registered a driver twice under two names. Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index b6e3618..fee2c34 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -475,15 +475,17 @@ void qemu_chr_set_feature(CharDriverState *chr, CharDriverFeature feature); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); -typedef void CharDriverParse(QemuOpts *opts, ChardevBackend *backend, - Error **errp); -typedef CharDriverState *CharDriverCreate(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, bool *be_opened, - Error **errp); - -void register_char_driver(const char *name, ChardevBackendKind kind, - CharDriverParse *parse, CharDriverCreate *create); +typedef struct CharDriver { + ChardevBackendKind kind; + const char *alias; + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); + CharDriverState *(*create)(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, bool *be_opened, + Error **errp); +} CharDriver; + +void register_char_driver(const CharDriver *driver); extern int term_escape_char; -- cgit v1.1 From b68e956abe2ad0a1ecf53868e0bf1a61b418ded8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 21 Oct 2016 20:49:37 +0300 Subject: char: move callbacks in CharDriver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the code more declarative, and avoids duplicating the information on all instances. Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index fee2c34..2dd0564 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -85,24 +85,11 @@ typedef struct CharBackend { int fe_open; } CharBackend; +typedef struct CharDriver CharDriver; + struct CharDriverState { + const CharDriver *driver; QemuMutex chr_write_lock; - int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); - int (*chr_sync_read)(struct CharDriverState *s, - const uint8_t *buf, int len); - GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond); - void (*chr_update_read_handler)(struct CharDriverState *s, - GMainContext *context); - int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); - int (*get_msgfds)(struct CharDriverState *s, int* fds, int num); - int (*set_msgfds)(struct CharDriverState *s, int *fds, int num); - int (*chr_add_client)(struct CharDriverState *chr, int fd); - int (*chr_wait_connected)(struct CharDriverState *chr, Error **errp); - void (*chr_free)(struct CharDriverState *chr); - void (*chr_disconnect)(struct CharDriverState *chr); - void (*chr_accept_input)(struct CharDriverState *chr); - void (*chr_set_echo)(struct CharDriverState *chr, bool echo); - void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open); CharBackend *be; void *opaque; char *label; @@ -125,7 +112,8 @@ struct CharDriverState { * * Returns: a newly allocated CharDriverState, or NULL on error. */ -CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp); +CharDriverState *qemu_chr_alloc(const CharDriver *driver, + ChardevCommon *backend, Error **errp); /** * @qemu_chr_new_from_opts: @@ -475,15 +463,33 @@ void qemu_chr_set_feature(CharDriverState *chr, CharDriverFeature feature); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); -typedef struct CharDriver { +struct CharDriver { ChardevBackendKind kind; const char *alias; void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); - CharDriverState *(*create)(const char *id, + CharDriverState *(*create)(const CharDriver *driver, + const char *id, ChardevBackend *backend, ChardevReturn *ret, bool *be_opened, Error **errp); -} CharDriver; + + int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); + int (*chr_sync_read)(struct CharDriverState *s, + const uint8_t *buf, int len); + GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond); + void (*chr_update_read_handler)(struct CharDriverState *s, + GMainContext *context); + int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); + int (*get_msgfds)(struct CharDriverState *s, int* fds, int num); + int (*set_msgfds)(struct CharDriverState *s, int *fds, int num); + int (*chr_add_client)(struct CharDriverState *chr, int fd); + int (*chr_wait_connected)(struct CharDriverState *chr, Error **errp); + void (*chr_free)(struct CharDriverState *chr); + void (*chr_disconnect)(struct CharDriverState *chr); + void (*chr_accept_input)(struct CharDriverState *chr); + void (*chr_set_echo)(struct CharDriverState *chr, bool echo); + void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open); +}; void register_char_driver(const CharDriver *driver); -- cgit v1.1 From ad5c679c7f4c10cc1bf4899ee2dfba08cc383f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 21 Oct 2016 22:38:41 +0300 Subject: char: introduce generic qemu_chr_get_kind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to remove the "is_mux" field from CharDriverState. Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 2dd0564..7d841ad 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -96,7 +96,6 @@ struct CharDriverState { char *filename; int logfd; int be_open; - int is_mux; guint fd_in_tag; bool replay; DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); @@ -455,7 +454,19 @@ void qemu_chr_be_generic_open(CharDriverState *s); void qemu_chr_fe_accept_input(CharBackend *be); int qemu_chr_add_client(CharDriverState *s, int fd); CharDriverState *qemu_chr_find(const char *name); -bool chr_is_ringbuf(const CharDriverState *chr); + +/** + * @qemu_chr_get_kind: + * + * Returns the kind of char backend, or -1 if unspecified. + */ +ChardevBackendKind qemu_chr_get_kind(const CharDriverState *chr); + +static inline bool qemu_chr_is_ringbuf(const CharDriverState *chr) +{ + return qemu_chr_get_kind(chr) == CHARDEV_BACKEND_KIND_RINGBUF || + qemu_chr_get_kind(chr) == CHARDEV_BACKEND_KIND_MEMORY; +} bool qemu_chr_has_feature(CharDriverState *chr, CharDriverFeature feature); -- cgit v1.1 From 5ebd67030c4e4bc702d07a3e10c909be4520f170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 21 Oct 2016 22:58:45 +0300 Subject: char: use a feature bit for replay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a feature flag rather than a structure field for "replay". Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 7d841ad..b0b4231 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -69,6 +69,8 @@ typedef enum { /* Whether it is possible to send/recv file descriptors * over the data channel */ QEMU_CHAR_FEATURE_FD_PASS, + /* Whether replay or record mode is enabled */ + QEMU_CHAR_FEATURE_REPLAY, QEMU_CHAR_FEATURE_LAST, } CharDriverFeature; @@ -97,7 +99,6 @@ struct CharDriverState { int logfd; int be_open; guint fd_in_tag; - bool replay; DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); QTAILQ_ENTRY(CharDriverState) next; }; -- cgit v1.1 From 41ac54b253f41df924c350ef63564df8e1d8ad88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 21 Oct 2016 23:44:44 +0300 Subject: char: allocate CharDriverState as a single object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a single allocation for CharDriverState, this avoids extra allocations & pointers, and is a step towards more object-oriented CharDriver. Gtk console is a bit peculiar, gd_vc_chr_set_echo() used to have a temporary VirtualConsole to save the echo bit. Instead now, we consider whether vcd->console is set or not, and restore the echo bit saved in VCDriverState when calling gd_vc_vte_init(). The casts added are temporary, they are replaced with QOM type-safe macros in a later patch in this series. Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index b0b4231..8bb94e5 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -93,7 +93,6 @@ struct CharDriverState { const CharDriver *driver; QemuMutex chr_write_lock; CharBackend *be; - void *opaque; char *label; char *filename; int logfd; @@ -484,6 +483,7 @@ struct CharDriver { ChardevBackend *backend, ChardevReturn *ret, bool *be_opened, Error **errp); + size_t instance_size; int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); int (*chr_sync_read)(struct CharDriverState *s, -- cgit v1.1 From 0ec7b3e7f21caf6bfde404528928d600b661ea8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 7 Dec 2016 16:20:22 +0300 Subject: char: rename CharDriverState Chardev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pick a uniform chardev type name. Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/hw/arm/exynos4210.h | 2 +- include/hw/arm/omap.h | 6 +-- include/hw/bt.h | 4 +- include/hw/char/cadence_uart.h | 2 +- include/hw/char/escc.h | 2 +- include/hw/char/pl011.h | 4 +- include/hw/char/serial.h | 4 +- include/hw/char/xilinx_uartlite.h | 2 +- include/hw/cris/etraxfs.h | 2 +- include/hw/devices.h | 2 +- include/hw/i386/pc.h | 2 +- include/hw/m68k/mcf.h | 4 +- include/hw/ppc/spapr_vio.h | 2 +- include/hw/qdev-properties.h | 2 +- include/hw/sh4/sh.h | 2 +- include/hw/sparc/grlib.h | 2 +- include/hw/xen/xen.h | 2 +- include/monitor/monitor.h | 2 +- include/qemu/typedefs.h | 2 +- include/sysemu/char.h | 94 +++++++++++++++++++-------------------- include/sysemu/replay.h | 4 +- include/sysemu/sysemu.h | 4 +- include/ui/gtk.h | 2 +- include/ui/qemu-spice.h | 2 +- 24 files changed, 78 insertions(+), 78 deletions(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 76bb6d4..d9e0801 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -131,7 +131,7 @@ void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev, DeviceState *exynos4210_uart_create(hwaddr addr, int fifo_size, int channel, - CharDriverState *chr, + Chardev *chr, qemu_irq irq); #endif /* EXYNOS4210_H */ diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h index f25870b..cac1b2b 100644 --- a/include/hw/arm/omap.h +++ b/include/hw/arm/omap.h @@ -664,14 +664,14 @@ struct omap_uart_s; struct omap_uart_s *omap_uart_init(hwaddr base, qemu_irq irq, omap_clk fclk, omap_clk iclk, qemu_irq txdma, qemu_irq rxdma, - const char *label, CharDriverState *chr); + const char *label, Chardev *chr); struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem, struct omap_target_agent_s *ta, qemu_irq irq, omap_clk fclk, omap_clk iclk, qemu_irq txdma, qemu_irq rxdma, - const char *label, CharDriverState *chr); + const char *label, Chardev *chr); void omap_uart_reset(struct omap_uart_s *s); -void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr); +void omap_uart_attach(struct omap_uart_s *s, Chardev *chr); struct omap_mpuio_s; qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s); diff --git a/include/hw/bt.h b/include/hw/bt.h index 2fa22bd..b5e11d4 100644 --- a/include/hw/bt.h +++ b/include/hw/bt.h @@ -127,8 +127,8 @@ enum { csrhci_pin_wakeup, __csrhci_pins, }; -qemu_irq *csrhci_pins_get(CharDriverState *chr); -CharDriverState *uart_hci_init(void); +qemu_irq *csrhci_pins_get(Chardev *chr); +Chardev *uart_hci_init(void); /* bt-l2cap.c */ struct bt_l2cap_device_s; diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h index ca75eb5..c836db4 100644 --- a/include/hw/char/cadence_uart.h +++ b/include/hw/char/cadence_uart.h @@ -51,7 +51,7 @@ typedef struct { static inline DeviceState *cadence_uart_create(hwaddr addr, qemu_irq irq, - CharDriverState *chr) + Chardev *chr) { DeviceState *dev; SysBusDevice *s; diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h index 297e2eb..08ae122 100644 --- a/include/hw/char/escc.h +++ b/include/hw/char/escc.h @@ -5,7 +5,7 @@ #define TYPE_ESCC "escc" #define ESCC_SIZE 4 MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB, - CharDriverState *chrA, CharDriverState *chrB, + Chardev *chrA, Chardev *chrB, int clock, int it_shift); void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq, diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h index 0ca7c19..8364932 100644 --- a/include/hw/char/pl011.h +++ b/include/hw/char/pl011.h @@ -17,7 +17,7 @@ static inline DeviceState *pl011_create(hwaddr addr, qemu_irq irq, - CharDriverState *chr) + Chardev *chr) { DeviceState *dev; SysBusDevice *s; @@ -34,7 +34,7 @@ static inline DeviceState *pl011_create(hwaddr addr, static inline DeviceState *pl011_luminary_create(hwaddr addr, qemu_irq irq, - CharDriverState *chr) + Chardev *chr) { DeviceState *dev; SysBusDevice *s; diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index c928d7d..daebb07 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -88,11 +88,11 @@ void serial_set_frequency(SerialState *s, uint32_t frequency); /* legacy pre qom */ SerialState *serial_init(int base, qemu_irq irq, int baudbase, - CharDriverState *chr, MemoryRegion *system_io); + Chardev *chr, MemoryRegion *system_io); SerialState *serial_mm_init(MemoryRegion *address_space, hwaddr base, int it_shift, qemu_irq irq, int baudbase, - CharDriverState *chr, enum device_endian end); + Chardev *chr, enum device_endian end); /* serial-isa.c */ #define TYPE_ISA_SERIAL "isa-serial" diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h index 8b4fc54..634086b 100644 --- a/include/hw/char/xilinx_uartlite.h +++ b/include/hw/char/xilinx_uartlite.h @@ -17,7 +17,7 @@ static inline DeviceState *xilinx_uartlite_create(hwaddr addr, qemu_irq irq, - CharDriverState *chr) + Chardev *chr) { DeviceState *dev; SysBusDevice *s; diff --git a/include/hw/cris/etraxfs.h b/include/hw/cris/etraxfs.h index 723a275..8da965a 100644 --- a/include/hw/cris/etraxfs.h +++ b/include/hw/cris/etraxfs.h @@ -48,7 +48,7 @@ etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr, static inline DeviceState *etraxfs_ser_create(hwaddr addr, qemu_irq irq, - CharDriverState *chr) + Chardev *chr) { DeviceState *dev; SysBusDevice *s; diff --git a/include/hw/devices.h b/include/hw/devices.h index c60bcab..7475b71 100644 --- a/include/hw/devices.h +++ b/include/hw/devices.h @@ -65,6 +65,6 @@ qemu_irq tc6393xb_l3v_get(TC6393xbState *s); /* sm501.c */ void sm501_init(struct MemoryRegion *address_space_mem, uint32_t base, uint32_t local_mem_bytes, qemu_irq irq, - CharDriverState *chr); + Chardev *chr); #endif diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 7c0f5a7..079e8d9 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -181,7 +181,7 @@ void parallel_hds_isa_init(ISABus *bus, int n); bool parallel_mm_init(MemoryRegion *address_space, hwaddr base, int it_shift, qemu_irq irq, - CharDriverState *chr); + Chardev *chr); /* i8259.c */ diff --git a/include/hw/m68k/mcf.h b/include/hw/m68k/mcf.h index bf43998..9a0bcfa 100644 --- a/include/hw/m68k/mcf.h +++ b/include/hw/m68k/mcf.h @@ -11,10 +11,10 @@ uint64_t mcf_uart_read(void *opaque, hwaddr addr, unsigned size); void mcf_uart_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); -void *mcf_uart_init(qemu_irq irq, CharDriverState *chr); +void *mcf_uart_init(qemu_irq irq, Chardev *chr); void mcf_uart_mm_init(struct MemoryRegion *sysmem, hwaddr base, - qemu_irq irq, CharDriverState *chr); + qemu_irq irq, Chardev *chr); /* mcf_intc.c */ qemu_irq *mcf_intc_init(struct MemoryRegion *sysmem, diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 14f5022..fc6f673 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -127,7 +127,7 @@ int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq); VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg); void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len); -void spapr_vty_create(VIOsPAPRBus *bus, CharDriverState *chardev); +void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev); void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd); void spapr_vscsi_create(VIOsPAPRBus *bus); diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 306bbab..7ac3153 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -184,7 +184,7 @@ void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value); void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value); void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value); void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value); -void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value); +void qdev_prop_set_chr(DeviceState *dev, const char *name, Chardev *value); void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value); void qdev_prop_set_drive(DeviceState *dev, const char *name, BlockBackend *value, Error **errp); diff --git a/include/hw/sh4/sh.h b/include/hw/sh4/sh.h index e59b9e7..767a2df 100644 --- a/include/hw/sh4/sh.h +++ b/include/hw/sh4/sh.h @@ -42,7 +42,7 @@ void tmu012_init(struct MemoryRegion *sysmem, hwaddr base, #define SH_SERIAL_FEAT_SCIF (1 << 0) void sh_serial_init(MemoryRegion *sysmem, hwaddr base, int feat, - uint32_t freq, CharDriverState *chr, + uint32_t freq, Chardev *chr, qemu_irq eri_source, qemu_irq rxi_source, qemu_irq txi_source, diff --git a/include/hw/sparc/grlib.h b/include/hw/sparc/grlib.h index afbb9bc..61a345c 100644 --- a/include/hw/sparc/grlib.h +++ b/include/hw/sparc/grlib.h @@ -100,7 +100,7 @@ DeviceState *grlib_gptimer_create(hwaddr base, static inline DeviceState *grlib_apbuart_create(hwaddr base, - CharDriverState *serial, + Chardev *serial, qemu_irq irq) { DeviceState *dev; diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index a8f3afb..09c2ce5 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -37,7 +37,7 @@ int xen_is_pirq_msi(uint32_t msi_data); qemu_irq *xen_interrupt_controller_init(void); -void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); +void xenstore_store_pv_console_info(int i, struct Chardev *chr); void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory); diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 8cc532e..e64b944 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -16,7 +16,7 @@ extern Monitor *cur_mon; bool monitor_cur_is_qmp(void); -void monitor_init(CharDriverState *chr, int flags); +void monitor_init(Chardev *chr, int flags); void monitor_cleanup(void); int monitor_suspend(Monitor *mon); diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 9a8bcbd..e95f28c 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -17,7 +17,7 @@ typedef struct BlockBackendRootState BlockBackendRootState; typedef struct BlockDriverState BlockDriverState; typedef struct BusClass BusClass; typedef struct BusState BusState; -typedef struct CharDriverState CharDriverState; +typedef struct Chardev Chardev; typedef struct CompatProperty CompatProperty; typedef struct CPUAddressSpace CPUAddressSpace; typedef struct CPUState CPUState; diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 8bb94e5..3a82d80 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -76,9 +76,9 @@ typedef enum { } CharDriverFeature; /* This is the backend as seen by frontend, the actual backend is - * CharDriverState */ + * Chardev */ typedef struct CharBackend { - CharDriverState *chr; + Chardev *chr; IOEventHandler *chr_event; IOCanReadHandler *chr_can_read; IOReadHandler *chr_read; @@ -89,7 +89,7 @@ typedef struct CharBackend { typedef struct CharDriver CharDriver; -struct CharDriverState { +struct Chardev { const CharDriver *driver; QemuMutex chr_write_lock; CharBackend *be; @@ -99,7 +99,7 @@ struct CharDriverState { int be_open; guint fd_in_tag; DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); - QTAILQ_ENTRY(CharDriverState) next; + QTAILQ_ENTRY(Chardev) next; }; /** @@ -107,12 +107,12 @@ struct CharDriverState { * @backend: the common backend config * @errp: pointer to a NULL-initialized error object * - * Allocate and initialize a new CharDriverState. + * Allocate and initialize a new Chardev. * - * Returns: a newly allocated CharDriverState, or NULL on error. + * Returns: a newly allocated Chardev, or NULL on error. */ -CharDriverState *qemu_chr_alloc(const CharDriver *driver, - ChardevCommon *backend, Error **errp); +Chardev *qemu_chr_alloc(const CharDriver *driver, + ChardevCommon *backend, Error **errp); /** * @qemu_chr_new_from_opts: @@ -123,8 +123,8 @@ CharDriverState *qemu_chr_alloc(const CharDriver *driver, * * Returns: a new character backend */ -CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, - Error **errp); +Chardev *qemu_chr_new_from_opts(QemuOpts *opts, + Error **errp); /** * @qemu_chr_parse_common: @@ -146,7 +146,7 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); * * Returns: a new character backend */ -CharDriverState *qemu_chr_new(const char *label, const char *filename); +Chardev *qemu_chr_new(const char *label, const char *filename); /** @@ -184,7 +184,7 @@ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp); * * Returns: a new character backend */ -CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename); +Chardev *qemu_chr_new_noreplay(const char *label, const char *filename); /** * @qemu_chr_delete: @@ -192,14 +192,14 @@ CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename); * Destroy a character backend and remove it from the list of * identified character backends. */ -void qemu_chr_delete(CharDriverState *chr); +void qemu_chr_delete(Chardev *chr); /** * @qemu_chr_free: * * Destroy a character backend. */ -void qemu_chr_free(CharDriverState *chr); +void qemu_chr_free(Chardev *chr); /** * @qemu_chr_fe_set_echo: @@ -355,7 +355,7 @@ int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num); * * Returns: the number of bytes the front end can receive via @qemu_chr_be_write */ -int qemu_chr_be_can_write(CharDriverState *s); +int qemu_chr_be_can_write(Chardev *s); /** * @qemu_chr_be_write: @@ -367,7 +367,7 @@ int qemu_chr_be_can_write(CharDriverState *s); * @buf a buffer to receive data from the front end * @len the number of bytes to receive from the front end */ -void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); +void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len); /** * @qemu_chr_be_write_impl: @@ -377,7 +377,7 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); * @buf a buffer to receive data from the front end * @len the number of bytes to receive from the front end */ -void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len); +void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len); /** * @qemu_chr_be_event: @@ -386,7 +386,7 @@ void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len); * * @event the event to send */ -void qemu_chr_be_event(CharDriverState *s, int event); +void qemu_chr_be_event(Chardev *s, int event); /** * @qemu_chr_fe_init: @@ -397,7 +397,7 @@ void qemu_chr_be_event(CharDriverState *s, int event); * * Returns: false on error. */ -bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); +bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp); /** * @qemu_chr_fe_get_driver: @@ -405,7 +405,7 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); * Returns the driver associated with a CharBackend or NULL if no * associated CharDriver. */ -CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); +Chardev *qemu_chr_fe_get_driver(CharBackend *be); /** * @qemu_chr_fe_deinit: @@ -450,27 +450,27 @@ void qemu_chr_fe_set_handlers(CharBackend *b, */ void qemu_chr_fe_take_focus(CharBackend *b); -void qemu_chr_be_generic_open(CharDriverState *s); +void qemu_chr_be_generic_open(Chardev *s); void qemu_chr_fe_accept_input(CharBackend *be); -int qemu_chr_add_client(CharDriverState *s, int fd); -CharDriverState *qemu_chr_find(const char *name); +int qemu_chr_add_client(Chardev *s, int fd); +Chardev *qemu_chr_find(const char *name); /** * @qemu_chr_get_kind: * * Returns the kind of char backend, or -1 if unspecified. */ -ChardevBackendKind qemu_chr_get_kind(const CharDriverState *chr); +ChardevBackendKind qemu_chr_get_kind(const Chardev *chr); -static inline bool qemu_chr_is_ringbuf(const CharDriverState *chr) +static inline bool qemu_chr_is_ringbuf(const Chardev *chr) { return qemu_chr_get_kind(chr) == CHARDEV_BACKEND_KIND_RINGBUF || qemu_chr_get_kind(chr) == CHARDEV_BACKEND_KIND_MEMORY; } -bool qemu_chr_has_feature(CharDriverState *chr, +bool qemu_chr_has_feature(Chardev *chr, CharDriverFeature feature); -void qemu_chr_set_feature(CharDriverState *chr, +void qemu_chr_set_feature(Chardev *chr, CharDriverFeature feature); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); @@ -478,29 +478,29 @@ struct CharDriver { ChardevBackendKind kind; const char *alias; void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); - CharDriverState *(*create)(const CharDriver *driver, - const char *id, - ChardevBackend *backend, - ChardevReturn *ret, bool *be_opened, - Error **errp); + Chardev *(*create)(const CharDriver *driver, + const char *id, + ChardevBackend *backend, + ChardevReturn *ret, bool *be_opened, + Error **errp); size_t instance_size; - int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); - int (*chr_sync_read)(struct CharDriverState *s, + int (*chr_write)(struct Chardev *s, const uint8_t *buf, int len); + int (*chr_sync_read)(struct Chardev *s, const uint8_t *buf, int len); - GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond); - void (*chr_update_read_handler)(struct CharDriverState *s, + GSource *(*chr_add_watch)(struct Chardev *s, GIOCondition cond); + void (*chr_update_read_handler)(struct Chardev *s, GMainContext *context); - int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); - int (*get_msgfds)(struct CharDriverState *s, int* fds, int num); - int (*set_msgfds)(struct CharDriverState *s, int *fds, int num); - int (*chr_add_client)(struct CharDriverState *chr, int fd); - int (*chr_wait_connected)(struct CharDriverState *chr, Error **errp); - void (*chr_free)(struct CharDriverState *chr); - void (*chr_disconnect)(struct CharDriverState *chr); - void (*chr_accept_input)(struct CharDriverState *chr); - void (*chr_set_echo)(struct CharDriverState *chr, bool echo); - void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open); + int (*chr_ioctl)(struct Chardev *s, int cmd, void *arg); + int (*get_msgfds)(struct Chardev *s, int* fds, int num); + int (*set_msgfds)(struct Chardev *s, int *fds, int num); + int (*chr_add_client)(struct Chardev *chr, int fd); + int (*chr_wait_connected)(struct Chardev *chr, Error **errp); + void (*chr_free)(struct Chardev *chr); + void (*chr_disconnect)(struct Chardev *chr); + void (*chr_accept_input)(struct Chardev *chr); + void (*chr_set_echo)(struct Chardev *chr, bool echo); + void (*chr_set_fe_open)(struct Chardev *chr, int fe_open); }; void register_char_driver(const CharDriver *driver); @@ -509,7 +509,7 @@ extern int term_escape_char; /* console.c */ -typedef CharDriverState *(VcHandler)(ChardevVC *vc, Error **errp); +typedef Chardev *(VcHandler)(ChardevVC *vc, Error **errp); void register_vc_handler(VcHandler *handler); #endif diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 740b425..7aad20b 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -128,9 +128,9 @@ uint64_t blkreplay_next_id(void); /* Character device */ /*! Registers char driver to save it's events */ -void replay_register_char_driver(struct CharDriverState *chr); +void replay_register_char_driver(struct Chardev *chr); /*! Saves write to char device event to the log */ -void replay_chr_be_write(struct CharDriverState *s, uint8_t *buf, int len); +void replay_chr_be_write(struct Chardev *s, uint8_t *buf, int len); /*! Writes char write return value to the replay log. */ void replay_char_write_event_save(int res, int offset); /*! Reads char write return value from the replay log. */ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 4ef2eb0..4d50694 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -190,13 +190,13 @@ void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict); #define MAX_SERIAL_PORTS 4 -extern CharDriverState *serial_hds[MAX_SERIAL_PORTS]; +extern Chardev *serial_hds[MAX_SERIAL_PORTS]; /* parallel ports */ #define MAX_PARALLEL_PORTS 3 -extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; +extern Chardev *parallel_hds[MAX_PARALLEL_PORTS]; void hmp_usb_add(Monitor *mon, const QDict *qdict); void hmp_usb_del(Monitor *mon, const QDict *qdict); diff --git a/include/ui/gtk.h b/include/ui/gtk.h index b3b5005..47ffddb 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -64,7 +64,7 @@ typedef struct VirtualVteConsole { GtkWidget *box; GtkWidget *scrollbar; GtkWidget *terminal; - CharDriverState *chr; + Chardev *chr; bool echo; } VirtualVteConsole; #endif diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h index 75e1239..52a9f88 100644 --- a/include/ui/qemu-spice.h +++ b/include/ui/qemu-spice.h @@ -51,7 +51,7 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, #if SPICE_SERVER_VERSION >= 0x000c02 void qemu_spice_register_ports(void); #else -static inline CharDriverState *qemu_chr_open_spice_port(const char *name) +static inline Chardev *qemu_chr_open_spice_port(const char *name) { return NULL; } #endif -- cgit v1.1 From 6f974c843c7c3d142f3ce594498431ba2ac19627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 7 Dec 2016 15:13:50 +0300 Subject: gtk: overwrite the console.c char driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of registering a vc handler to allocate the Gtk VC Chardev, overwrite the console.c char driver. A later patch, when switching to QOM, will register a default console vc QOM class if none has been registered before. Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 3a82d80..baa9e8f 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -507,9 +507,7 @@ void register_char_driver(const CharDriver *driver); extern int term_escape_char; - /* console.c */ -typedef Chardev *(VcHandler)(ChardevVC *vc, Error **errp); -void register_vc_handler(VcHandler *handler); +void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp); #endif -- cgit v1.1 From 777357d758d937c9dd83082c39aff9f1e53e9ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 7 Dec 2016 18:39:10 +0300 Subject: chardev: qom-ify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turn Chardev into Object. qemu_chr_alloc() is replaced by the qemu_chardev_new() constructor. It will call qemu_char_open() to open/intialize the chardev with the ChardevCommon *backend settings. The CharDriver::create() callback is turned into a ChardevClass::open() which is called from the newly introduced qemu_chardev_open(). "chardev-gdb" and "chardev-hci" are internal chardev and aren't creatable directly with -chardev. Use a new internal flag to disable them. We may want to use TYPE_USER_CREATABLE interface instead, or perhaps allow -chardev usage. Although in general we keep typename and macros private, unless the type is being used by some other file, in this patch, all types and common helper macros for qemu-char.c are in char.h. This is to help transition now (some types must be declared early, while some aren't shared) and when splitting in several units. This is to be improved later. Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 107 +++++++++++++++++++++++++++----------------------- include/ui/console.h | 2 + 2 files changed, 60 insertions(+), 49 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index baa9e8f..da0e7dd 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -10,6 +10,7 @@ #include "qapi/qmp/qstring.h" #include "qemu/main-loop.h" #include "qemu/bitmap.h" +#include "qom/object.h" /* character device */ @@ -90,7 +91,8 @@ typedef struct CharBackend { typedef struct CharDriver CharDriver; struct Chardev { - const CharDriver *driver; + Object parent_obj; + QemuMutex chr_write_lock; CharBackend *be; char *label; @@ -103,18 +105,6 @@ struct Chardev { }; /** - * qemu_chr_alloc: - * @backend: the common backend config - * @errp: pointer to a NULL-initialized error object - * - * Allocate and initialize a new Chardev. - * - * Returns: a newly allocated Chardev, or NULL on error. - */ -Chardev *qemu_chr_alloc(const CharDriver *driver, - ChardevCommon *backend, Error **errp); - -/** * @qemu_chr_new_from_opts: * * Create a new character backend from a QemuOpts list. @@ -455,54 +445,73 @@ void qemu_chr_fe_accept_input(CharBackend *be); int qemu_chr_add_client(Chardev *s, int fd); Chardev *qemu_chr_find(const char *name); -/** - * @qemu_chr_get_kind: - * - * Returns the kind of char backend, or -1 if unspecified. - */ -ChardevBackendKind qemu_chr_get_kind(const Chardev *chr); - -static inline bool qemu_chr_is_ringbuf(const Chardev *chr) -{ - return qemu_chr_get_kind(chr) == CHARDEV_BACKEND_KIND_RINGBUF || - qemu_chr_get_kind(chr) == CHARDEV_BACKEND_KIND_MEMORY; -} - bool qemu_chr_has_feature(Chardev *chr, CharDriverFeature feature); void qemu_chr_set_feature(Chardev *chr, CharDriverFeature feature); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); +#define TYPE_CHARDEV "chardev" +#define CHARDEV(obj) OBJECT_CHECK(Chardev, (obj), TYPE_CHARDEV) +#define CHARDEV_CLASS(klass) \ + OBJECT_CLASS_CHECK(ChardevClass, (klass), TYPE_CHARDEV) +#define CHARDEV_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ChardevClass, (obj), TYPE_CHARDEV) + +#define TYPE_CHARDEV_NULL "chardev-null" +#define TYPE_CHARDEV_MUX "chardev-mux" +#define TYPE_CHARDEV_RINGBUF "chardev-ringbuf" +#define TYPE_CHARDEV_PTY "chardev-pty" +#define TYPE_CHARDEV_CONSOLE "chardev-console" +#define TYPE_CHARDEV_STDIO "chardev-stdio" +#define TYPE_CHARDEV_PIPE "chardev-pipe" +#define TYPE_CHARDEV_MEMORY "chardev-memory" +#define TYPE_CHARDEV_PARALLEL "chardev-parallel" +#define TYPE_CHARDEV_FILE "chardev-file" +#define TYPE_CHARDEV_SERIAL "chardev-serial" +#define TYPE_CHARDEV_SOCKET "chardev-socket" +#define TYPE_CHARDEV_UDP "chardev-udp" + +#define CHARDEV_IS_MUX(chr) \ + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_MUX) +#define CHARDEV_IS_RINGBUF(chr) \ + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_RINGBUF) +#define CHARDEV_IS_PTY(chr) \ + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_PTY) + +typedef struct ChardevClass { + ObjectClass parent_class; + + bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ + + void (*open)(Chardev *chr, ChardevBackend *backend, + bool *be_opened, Error **errp); + + int (*chr_write)(Chardev *s, const uint8_t *buf, int len); + int (*chr_sync_read)(Chardev *s, const uint8_t *buf, int len); + GSource *(*chr_add_watch)(Chardev *s, GIOCondition cond); + void (*chr_update_read_handler)(Chardev *s, GMainContext *context); + int (*chr_ioctl)(Chardev *s, int cmd, void *arg); + int (*get_msgfds)(Chardev *s, int* fds, int num); + int (*set_msgfds)(Chardev *s, int *fds, int num); + int (*chr_add_client)(Chardev *chr, int fd); + int (*chr_wait_connected)(Chardev *chr, Error **errp); + void (*chr_free)(Chardev *chr); + void (*chr_disconnect)(Chardev *chr); + void (*chr_accept_input)(Chardev *chr); + void (*chr_set_echo)(Chardev *chr, bool echo); + void (*chr_set_fe_open)(Chardev *chr, int fe_open); +} ChardevClass; + struct CharDriver { ChardevBackendKind kind; const char *alias; void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); - Chardev *(*create)(const CharDriver *driver, - const char *id, - ChardevBackend *backend, - ChardevReturn *ret, bool *be_opened, - Error **errp); - size_t instance_size; - - int (*chr_write)(struct Chardev *s, const uint8_t *buf, int len); - int (*chr_sync_read)(struct Chardev *s, - const uint8_t *buf, int len); - GSource *(*chr_add_watch)(struct Chardev *s, GIOCondition cond); - void (*chr_update_read_handler)(struct Chardev *s, - GMainContext *context); - int (*chr_ioctl)(struct Chardev *s, int cmd, void *arg); - int (*get_msgfds)(struct Chardev *s, int* fds, int num); - int (*set_msgfds)(struct Chardev *s, int *fds, int num); - int (*chr_add_client)(struct Chardev *chr, int fd); - int (*chr_wait_connected)(struct Chardev *chr, Error **errp); - void (*chr_free)(struct Chardev *chr); - void (*chr_disconnect)(struct Chardev *chr); - void (*chr_accept_input)(struct Chardev *chr); - void (*chr_set_echo)(struct Chardev *chr, bool echo); - void (*chr_set_fe_open)(struct Chardev *chr, int fe_open); }; +Chardev *qemu_chardev_new(const char *id, const char *typename, + ChardevBackend *backend, Error **errp); + void register_char_driver(const CharDriver *driver); extern int term_escape_char; diff --git a/include/ui/console.h b/include/ui/console.h index b59e7b8..af6350e 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -383,6 +383,8 @@ void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); void graphic_hw_gl_block(QemuConsole *con, bool block); +void qemu_console_early_init(void); + QemuConsole *qemu_console_lookup_by_index(unsigned int index); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head); QemuConsole *qemu_console_lookup_by_device_name(const char *device_id, -- cgit v1.1