From f1ee86963b9a7bc6a60b823dbf682fd0a62ffcc4 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 19 Sep 2016 10:50:38 +0200 Subject: atomic: introduce smp_mb_acquire and smp_mb_release Signed-off-by: Paolo Bonzini --- include/qemu/atomic.h | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h index c4f6950..b108df0 100644 --- a/include/qemu/atomic.h +++ b/include/qemu/atomic.h @@ -72,16 +72,16 @@ * Add one here, and similarly in smp_rmb() and smp_read_barrier_depends(). */ -#define smp_mb() ({ barrier(); __atomic_thread_fence(__ATOMIC_SEQ_CST); }) -#define smp_wmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); }) -#define smp_rmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); }) +#define smp_mb() ({ barrier(); __atomic_thread_fence(__ATOMIC_SEQ_CST); }) +#define smp_mb_release() ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); }) +#define smp_mb_acquire() ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); }) /* Most compilers currently treat consume and acquire the same, but really * no processors except Alpha need a barrier here. Leave it in if * using Thread Sanitizer to avoid warnings, otherwise optimize it away. */ #if defined(__SANITIZE_THREAD__) -#define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); }) +#define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); }) #elif defined(__alpha__) #define smp_read_barrier_depends() asm volatile("mb":::"memory") #else @@ -149,13 +149,13 @@ QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ typeof_strip_qual(*ptr) _val; \ __atomic_load(ptr, &_val, __ATOMIC_RELAXED); \ - smp_rmb(); \ + smp_mb_acquire(); \ _val; \ }) #define atomic_mb_set(ptr, i) do { \ QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ - smp_wmb(); \ + smp_mb_release(); \ __atomic_store_n(ptr, i, __ATOMIC_RELAXED); \ smp_mb(); \ } while(0) @@ -238,8 +238,8 @@ * here (a compiler barrier only). QEMU doesn't do accesses to write-combining * qemu memory or non-temporal load/stores from C code. */ -#define smp_wmb() barrier() -#define smp_rmb() barrier() +#define smp_mb_release() barrier() +#define smp_mb_acquire() barrier() /* * __sync_lock_test_and_set() is documented to be an acquire barrier only, @@ -263,13 +263,15 @@ * smp_mb has the same problem as on x86 for not-very-new GCC * (http://patchwork.ozlabs.org/patch/126184/, Nov 2011). */ -#define smp_wmb() ({ asm volatile("eieio" ::: "memory"); (void)0; }) +#define smp_wmb() ({ asm volatile("eieio" ::: "memory"); (void)0; }) #if defined(__powerpc64__) -#define smp_rmb() ({ asm volatile("lwsync" ::: "memory"); (void)0; }) +#define smp_mb_release() ({ asm volatile("lwsync" ::: "memory"); (void)0; }) +#define smp_mb_acquire() ({ asm volatile("lwsync" ::: "memory"); (void)0; }) #else -#define smp_rmb() ({ asm volatile("sync" ::: "memory"); (void)0; }) +#define smp_mb_release() ({ asm volatile("sync" ::: "memory"); (void)0; }) +#define smp_mb_acquire() ({ asm volatile("sync" ::: "memory"); (void)0; }) #endif -#define smp_mb() ({ asm volatile("sync" ::: "memory"); (void)0; }) +#define smp_mb() ({ asm volatile("sync" ::: "memory"); (void)0; }) #endif /* _ARCH_PPC */ @@ -277,18 +279,18 @@ * For (host) platforms we don't have explicit barrier definitions * for, we use the gcc __sync_synchronize() primitive to generate a * full barrier. This should be safe on all platforms, though it may - * be overkill for smp_wmb() and smp_rmb(). + * be overkill for smp_mb_acquire() and smp_mb_release(). */ #ifndef smp_mb -#define smp_mb() __sync_synchronize() +#define smp_mb() __sync_synchronize() #endif -#ifndef smp_wmb -#define smp_wmb() __sync_synchronize() +#ifndef smp_mb_acquire +#define smp_mb_acquire() __sync_synchronize() #endif -#ifndef smp_rmb -#define smp_rmb() __sync_synchronize() +#ifndef smp_mb_release +#define smp_mb_release() __sync_synchronize() #endif #ifndef smp_read_barrier_depends @@ -365,13 +367,13 @@ */ #define atomic_mb_read(ptr) ({ \ typeof(*ptr) _val = atomic_read(ptr); \ - smp_rmb(); \ + smp_mb_acquire(); \ _val; \ }) #ifndef atomic_mb_set #define atomic_mb_set(ptr, i) do { \ - smp_wmb(); \ + smp_mb_release(); \ atomic_set(ptr, i); \ smp_mb(); \ } while (0) @@ -404,4 +406,12 @@ #define atomic_or(ptr, n) ((void) __sync_fetch_and_or(ptr, n)) #endif /* __ATOMIC_RELAXED */ + +#ifndef smp_wmb +#define smp_wmb() smp_mb_release() +#endif +#ifndef smp_rmb +#define smp_rmb() smp_mb_acquire() +#endif + #endif /* QEMU_ATOMIC_H */ -- cgit v1.1 From 803cf26a9e019b5d2256a8edeb22e3538c4f3261 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 19 Sep 2016 11:36:44 +0200 Subject: atomic: base mb_read/mb_set on load-acquire and store-release This introduces load-acquire and store-release operations in QEMU. For now, just use them as an implementation detail of atomic_mb_read and atomic_mb_set. Since docs/atomics.txt documents that atomic_mb_read only synchronizes with an atomic_mb_set of the same variable, we can use the new implementation everywhere instead of seq-cst loads and stores. Signed-off-by: Paolo Bonzini --- include/qemu/atomic.h | 95 ++++++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 62 deletions(-) (limited to 'include') diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h index b108df0..c09fce7 100644 --- a/include/qemu/atomic.h +++ b/include/qemu/atomic.h @@ -135,44 +135,18 @@ __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \ } while(0) -/* atomic_mb_read/set semantics map Java volatile variables. They are - * less expensive on some platforms (notably POWER & ARMv7) than fully - * sequentially consistent operations. - * - * As long as they are used as paired operations they are safe to - * use. See docs/atomic.txt for more discussion. - */ - -#if defined(_ARCH_PPC) -#define atomic_mb_read(ptr) \ +#define atomic_load_acquire(ptr) \ ({ \ QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ typeof_strip_qual(*ptr) _val; \ - __atomic_load(ptr, &_val, __ATOMIC_RELAXED); \ - smp_mb_acquire(); \ + __atomic_load(ptr, &_val, __ATOMIC_ACQUIRE); \ _val; \ }) -#define atomic_mb_set(ptr, i) do { \ +#define atomic_store_release(ptr, i) do { \ QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ - smp_mb_release(); \ - __atomic_store_n(ptr, i, __ATOMIC_RELAXED); \ - smp_mb(); \ + __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \ } while(0) -#else -#define atomic_mb_read(ptr) \ - ({ \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ - typeof_strip_qual(*ptr) _val; \ - __atomic_load(ptr, &_val, __ATOMIC_SEQ_CST); \ - _val; \ - }) - -#define atomic_mb_set(ptr, i) do { \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ - __atomic_store_n(ptr, i, __ATOMIC_SEQ_CST); \ -} while(0) -#endif /* All the remaining operations are fully sequentially consistent */ @@ -248,11 +222,6 @@ */ #define atomic_xchg(ptr, i) (barrier(), __sync_lock_test_and_set(ptr, i)) -/* - * Load/store with Java volatile semantics. - */ -#define atomic_mb_set(ptr, i) ((void)atomic_xchg(ptr, i)) - #elif defined(_ARCH_PPC) /* @@ -343,41 +312,16 @@ atomic_set(ptr, i); \ } while (0) -/* These have the same semantics as Java volatile variables. - * See http://gee.cs.oswego.edu/dl/jmm/cookbook.html: - * "1. Issue a StoreStore barrier (wmb) before each volatile store." - * 2. Issue a StoreLoad barrier after each volatile store. - * Note that you could instead issue one before each volatile load, but - * this would be slower for typical programs using volatiles in which - * reads greatly outnumber writes. Alternatively, if available, you - * can implement volatile store as an atomic instruction (for example - * XCHG on x86) and omit the barrier. This may be more efficient if - * atomic instructions are cheaper than StoreLoad barriers. - * 3. Issue LoadLoad and LoadStore barriers after each volatile load." - * - * If you prefer to think in terms of "pairing" of memory barriers, - * an atomic_mb_read pairs with an atomic_mb_set. - * - * And for the few ia64 lovers that exist, an atomic_mb_read is a ld.acq, - * while an atomic_mb_set is a st.rel followed by a memory barrier. - * - * These are a bit weaker than __atomic_load/store with __ATOMIC_SEQ_CST - * (see docs/atomics.txt), and I'm not sure that __ATOMIC_ACQ_REL is enough. - * Just always use the barriers manually by the rules above. - */ -#define atomic_mb_read(ptr) ({ \ +#define atomic_load_acquire(ptr) ({ \ typeof(*ptr) _val = atomic_read(ptr); \ smp_mb_acquire(); \ _val; \ }) -#ifndef atomic_mb_set -#define atomic_mb_set(ptr, i) do { \ +#define atomic_store_release(ptr, i) do { \ smp_mb_release(); \ atomic_set(ptr, i); \ - smp_mb(); \ } while (0) -#endif #ifndef atomic_xchg #if defined(__clang__) @@ -414,4 +358,31 @@ #define smp_rmb() smp_mb_acquire() #endif +/* This is more efficient than a store plus a fence. */ +#if !defined(__SANITIZE_THREAD__) +#if defined(__i386__) || defined(__x86_64__) || defined(__s390x__) +#define atomic_mb_set(ptr, i) ((void)atomic_xchg(ptr, i)) +#endif +#endif + +/* atomic_mb_read/set semantics map Java volatile variables. They are + * less expensive on some platforms (notably POWER) than fully + * sequentially consistent operations. + * + * As long as they are used as paired operations they are safe to + * use. See docs/atomic.txt for more discussion. + */ + +#ifndef atomic_mb_read +#define atomic_mb_read(ptr) \ + atomic_load_acquire(ptr) +#endif + +#ifndef atomic_mb_set +#define atomic_mb_set(ptr, i) do { \ + atomic_store_release(ptr, i); \ + smp_mb(); \ +} while(0) +#endif + #endif /* QEMU_ATOMIC_H */ -- cgit v1.1 From d45fa784cd0c111131696808d1168259d66b7519 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 22 Sep 2016 16:11:54 +0200 Subject: memory: eliminate global MemoryListeners There is none, so just drop the code. 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 10d7eac..39f3410 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -255,7 +255,7 @@ struct MemoryListener { hwaddr addr, hwaddr len); /* Lower = earlier (during add), later (during del) */ unsigned priority; - AddressSpace *address_space_filter; + AddressSpace *address_space; QTAILQ_ENTRY(MemoryListener) link; }; -- cgit v1.1 From 9a54635dcb51a3fcf7507af630168f514a8cd4e7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 22 Sep 2016 16:23:06 +0200 Subject: memory: add a per-AddressSpace list of listeners This speeds up MEMORY_LISTENER_CALL noticeably. Right now, with many PCI devices you have N regions added to M AddressSpaces (M = # PCI devices with bus-master enabled) and each call looks up the whole listener list, with at least M listeners in it. Because most of the regions in N are BARs, which are also roughly proportional to M, the whole thing is O(M^3). This changes it to O(M^2), which is the best we can do without rewriting the whole thing. Signed-off-by: Paolo Bonzini --- include/exec/memory.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/exec/memory.h b/include/exec/memory.h index 39f3410..79ccaab 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -257,6 +257,7 @@ struct MemoryListener { unsigned priority; AddressSpace *address_space; QTAILQ_ENTRY(MemoryListener) link; + QTAILQ_ENTRY(MemoryListener) link_as; }; /** @@ -278,7 +279,7 @@ struct AddressSpace { struct AddressSpaceDispatch *dispatch; struct AddressSpaceDispatch *next_dispatch; MemoryListener dispatch_listener; - + QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners; QTAILQ_ENTRY(AddressSpace) address_spaces_link; }; -- cgit v1.1 From f0b454ebf8a3c51acead0d53e5f2b53576159dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Tue, 11 Oct 2016 19:20:12 +0400 Subject: char.h: misc doc fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau Message-Id: <20161011152012.3228-1-marcandre.lureau@redhat.com> 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 19dad3f..d0ffdbd 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -380,7 +380,7 @@ int qemu_chr_fe_claim(CharDriverState *s); void qemu_chr_fe_claim_no_fail(CharDriverState *s); /** - * @qemu_chr_fe_claim: + * @qemu_chr_fe_release: * * Release a backend for use by another frontend. * -- cgit v1.1 From 4496dc49ec9a6e24e9eeb2da970ed0ec0051968e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:44 +0300 Subject: sun4uv: fix serial initialization regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit b6607a1a204d, serial_hds_isa_init() was introduced to factor out serial_isa_init() loops. However, sun4uv shouldn't start from 0 when there is a mm serial on 0 already. Add a "from" argument to serial_hds_isa_init(). Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-5-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/hw/char/serial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index a4fd3d5..4f3b73c 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -94,6 +94,6 @@ SerialState *serial_mm_init(MemoryRegion *address_space, /* serial-isa.c */ #define TYPE_ISA_SERIAL "isa-serial" -void serial_hds_isa_init(ISABus *bus, int n); +void serial_hds_isa_init(ISABus *bus, int from, int to); #endif -- cgit v1.1 From b4948be93e53c3b471666e51ce59303082626a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:46 +0300 Subject: char: remove init callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CharDriverState.init() callback is no longer set since commit a61ae7f88ce and thus unused. The only user, the malta FGPA display has been converted to use an event "opened" callback instead. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-7-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index d0ffdbd..eba77e0 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -75,7 +75,6 @@ typedef enum { struct CharDriverState { QemuMutex chr_write_lock; - void (*init)(struct CharDriverState *s); 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); @@ -130,13 +129,11 @@ CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp); * Create a new character backend from a QemuOpts list. * * @opts see qemu-config.c for a list of valid options - * @init not sure.. * * Returns: a new character backend */ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, - void (*init)(struct CharDriverState *s), - Error **errp); + Error **errp); /** * @qemu_chr_parse_common: @@ -155,12 +152,10 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); * * @label the name of the backend * @filename the URI - * @init not sure.. * * Returns: a new character backend */ -CharDriverState *qemu_chr_new(const char *label, const char *filename, - void (*init)(struct CharDriverState *s)); +CharDriverState *qemu_chr_new(const char *label, const char *filename); /** * @qemu_chr_disconnect: * @@ -191,12 +186,10 @@ int qemu_chr_wait_connected(CharDriverState *chr, Error **errp); * * @label the name of the backend * @filename the URI - * @init not sure.. * * Returns: a new character backend */ -CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename, - void (*init)(struct CharDriverState *s)); +CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename); /** * @qemu_chr_delete: -- cgit v1.1 From 6dfa8298faa0fce47c68659fd4d92e76745d4edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:48 +0300 Subject: mux: split mux_chr_update_read_handler() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make qemu_chr_add_handlers_full() aware of mux handling. This allows introduction of a tag associated with the fe handlers and a qemu_chr_set_handlers() function to set the handler for a particular tag. That will allow to get rid of qemu_chr_add_handlers*() in later changes, in favor of qemu_chr_fe_set_handler(). To this end, chr_update_read_handler callback is enhanced with a tag argument, and mux_chr_update_read_handler() is splitted in new functions: mux_chr_new_handler_tag(), mux_chr_set_handlers(), mux_set_focus(). Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-9-marcandre.lureau@redhat.com> 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 eba77e0..36b5d30 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -80,7 +80,7 @@ struct CharDriverState { 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); + GMainContext *context, int tag); 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); -- cgit v1.1 From 94a40fc56036b5058b0b194d9e372a22e65ce7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:49 +0300 Subject: char: introduce CharBackend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new structure is meant to keep the details associated with a char driver usage. On initialization, it gets a tag from the mux backend. It can change its handlers thanks to qemu_chr_fe_set_handlers(). This structure is introduced so that all frontend will be moved to hold and use a CharBackend. This will allow to better track char usage and allocation, and help prevent some memory leaks or corruption. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-10-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 36b5d30..c518c2f 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -72,6 +72,12 @@ typedef enum { QEMU_CHAR_FEATURE_LAST, } CharDriverFeature; +/* This is the backend as seen by frontend, the actual backend is + * CharDriverState */ +typedef struct CharBackend { + CharDriverState *chr; + int tag; +} CharBackend; struct CharDriverState { QemuMutex chr_write_lock; @@ -156,6 +162,8 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); * Returns: a new character backend */ CharDriverState *qemu_chr_new(const char *label, const char *filename); + + /** * @qemu_chr_disconnect: * @@ -425,6 +433,48 @@ void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len); */ void qemu_chr_be_event(CharDriverState *s, int event); +/** + * @qemu_chr_fe_init: + * + * Initializes a front end for the given CharBackend and CharDriver. + * + * Returns: false on error. + */ +bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); + +/** + * @qemu_chr_fe_get_driver: + * + * Returns the driver associated with a CharBackend or NULL. + */ +CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); + +/** + * @qemu_chr_fe_set_handlers: + * @b: a CharBackend + * @fd_can_read: callback to get the amount of data the frontend may + * receive + * @fd_read: callback to receive data from char + * @fd_event: event callback + * @opaque: an opaque pointer for the callbacks + * @context: a main loop context or NULL for the default + * + * Set the front end char handlers. + */ +void qemu_chr_fe_set_handlers(CharBackend *b, + IOCanReadHandler *fd_can_read, + IOReadHandler *fd_read, + IOEventHandler *fd_event, + void *opaque, + GMainContext *context); + +/** + * @qemu_chr_fe_take_focus: + * + * Take the focus (if the front end is muxed) + */ +void qemu_chr_fe_take_focus(CharBackend *b); + void qemu_chr_add_handlers(CharDriverState *s, IOCanReadHandler *fd_can_read, IOReadHandler *fd_read, -- cgit v1.1 From becdfa00cfa2995e859ccefa4b7d72a72eb96581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:51 +0300 Subject: char: replace PROP_CHR with CharBackend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store the property in a CharBackend instead of CharDriverState*. This also replace systematically chr by chr.chr to access the CharDriverState*. The following patches will replace it with calls to qemu_chr_fe CharBackend functions. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-12-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/hw/char/bcm2835_aux.h | 2 +- include/hw/char/cadence_uart.h | 2 +- include/hw/char/digic-uart.h | 3 ++- include/hw/char/imx_serial.h | 3 ++- include/hw/char/serial.h | 3 ++- include/hw/char/stm32f2xx_usart.h | 2 +- include/hw/qdev-properties.h | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/hw/char/bcm2835_aux.h b/include/hw/char/bcm2835_aux.h index 42f0ee7..6865f15 100644 --- a/include/hw/char/bcm2835_aux.h +++ b/include/hw/char/bcm2835_aux.h @@ -22,7 +22,7 @@ typedef struct { /*< public >*/ MemoryRegion iomem; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN]; diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h index a12773c..ca75eb5 100644 --- a/include/hw/char/cadence_uart.h +++ b/include/hw/char/cadence_uart.h @@ -44,7 +44,7 @@ typedef struct { uint32_t rx_count; uint32_t tx_count; uint64_t char_tx_time; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; QEMUTimer *fifo_trigger_handle; } CadenceUARTState; diff --git a/include/hw/char/digic-uart.h b/include/hw/char/digic-uart.h index 7b3f145..340c8e1 100644 --- a/include/hw/char/digic-uart.h +++ b/include/hw/char/digic-uart.h @@ -19,6 +19,7 @@ #define HW_CHAR_DIGIC_UART_H #include "hw/sysbus.h" +#include "sysemu/char.h" #define TYPE_DIGIC_UART "digic-uart" #define DIGIC_UART(obj) \ @@ -37,7 +38,7 @@ typedef struct DigicUartState { /*< public >*/ MemoryRegion regs_region; - CharDriverState *chr; + CharBackend chr; uint32_t reg_rx; uint32_t reg_st; diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h index 6cd75c0..4cc3fbc 100644 --- a/include/hw/char/imx_serial.h +++ b/include/hw/char/imx_serial.h @@ -19,6 +19,7 @@ #define IMX_SERIAL_H #include "hw/sysbus.h" +#include "sysemu/char.h" #define TYPE_IMX_SERIAL "imx.serial" #define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL) @@ -96,7 +97,7 @@ typedef struct IMXSerialState { uint32_t ucr3; qemu_irq irq; - CharDriverState *chr; + CharBackend chr; } IMXSerialState; #endif diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 4f3b73c..c3312fb 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -30,6 +30,7 @@ #include "sysemu/sysemu.h" #include "exec/memory.h" #include "qemu/fifo8.h" +#include "sysemu/char.h" #define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */ @@ -52,7 +53,7 @@ struct SerialState { it can be reset while reading iir */ int thr_ipending; qemu_irq irq; - CharDriverState *chr; + CharBackend chr; int last_break_enable; int it_shift; int baudbase; diff --git a/include/hw/char/stm32f2xx_usart.h b/include/hw/char/stm32f2xx_usart.h index b97f192..3267523 100644 --- a/include/hw/char/stm32f2xx_usart.h +++ b/include/hw/char/stm32f2xx_usart.h @@ -67,7 +67,7 @@ typedef struct { uint32_t usart_cr3; uint32_t usart_gtpr; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; } STM32F2XXUsartState; #endif /* HW_STM32F2XX_USART_H */ diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 2a9d2f9..306bbab 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -146,7 +146,7 @@ extern PropertyInfo qdev_prop_arraylen; DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) #define DEFINE_PROP_CHR(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*) + DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend) #define DEFINE_PROP_STRING(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*) #define DEFINE_PROP_NETDEV(_n, _s, _f) \ -- cgit v1.1 From 7fa47e2a80e1c204533340f65909b7fc7c6b276f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:53 +0300 Subject: char: rename some frontend functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qemu_chr_accept_input() and qemu_chr_disconnect() are only used by frontend, so use qemu_chr_fe prefix. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-14-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index c518c2f..5881094 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -165,11 +165,11 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename); /** - * @qemu_chr_disconnect: + * @qemu_chr_fe_disconnect: * * Close a fd accpeted by character backend. */ -void qemu_chr_disconnect(CharDriverState *chr); +void qemu_chr_fe_disconnect(CharDriverState *chr); /** * @qemu_chr_cleanup: @@ -490,7 +490,7 @@ void qemu_chr_add_handlers_full(CharDriverState *s, GMainContext *context); void qemu_chr_be_generic_open(CharDriverState *s); -void qemu_chr_accept_input(CharDriverState *s); +void qemu_chr_fe_accept_input(CharDriverState *s); int qemu_chr_add_client(CharDriverState *s, int fd); CharDriverState *qemu_chr_find(const char *name); bool chr_is_ringbuf(const CharDriverState *chr); -- cgit v1.1 From 5345fdb4467816c44f6752b3a1f4e73aa25919f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:55 +0300 Subject: char: use qemu_chr_fe* functions with CharBackend argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also switches from qemu_chr_add_handlers() to qemu_chr_fe_set_handlers(). Note that qemu_chr_fe_set_handlers() now takes the focus when fe_open (qemu_chr_add_handlers() did take the focus) Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-16-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/hw/char/serial.h | 1 + include/sysemu/char.h | 51 ++++++++++++++++++------------------------------ 2 files changed, 20 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index c3312fb..c928d7d 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -28,6 +28,7 @@ #include "hw/hw.h" #include "sysemu/sysemu.h" +#include "sysemu/char.h" #include "exec/memory.h" #include "qemu/fifo8.h" #include "sysemu/char.h" diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 5881094..816c536 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -169,7 +169,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename); * * Close a fd accpeted by character backend. */ -void qemu_chr_fe_disconnect(CharDriverState *chr); +void qemu_chr_fe_disconnect(CharBackend *be); /** * @qemu_chr_cleanup: @@ -179,11 +179,11 @@ void qemu_chr_fe_disconnect(CharDriverState *chr); void qemu_chr_cleanup(void); /** - * @qemu_chr_wait_connected: + * @qemu_chr_fe_wait_connected: * * Wait for characted backend to be connected. */ -int qemu_chr_wait_connected(CharDriverState *chr, Error **errp); +int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp); /** * @qemu_chr_new_noreplay: @@ -223,7 +223,7 @@ void qemu_chr_free(CharDriverState *chr); * * @echo true to enable echo, false to disable echo */ -void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo); +void qemu_chr_fe_set_echo(CharBackend *be, bool echo); /** * @qemu_chr_fe_set_open: @@ -231,7 +231,7 @@ void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo); * Set character frontend open status. This is an indication that the * front end is ready (or not) to begin doing I/O. */ -void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open); +void qemu_chr_fe_set_open(CharBackend *be, int fe_open); /** * @qemu_chr_fe_event: @@ -240,7 +240,7 @@ void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open); * * @event the event to send */ -void qemu_chr_fe_event(CharDriverState *s, int event); +void qemu_chr_fe_event(CharBackend *be, int event); /** * @qemu_chr_fe_printf: @@ -250,7 +250,7 @@ void qemu_chr_fe_event(CharDriverState *s, int event); * * @fmt see #printf */ -void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) +void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...) GCC_FMT_ATTR(2, 3); /** @@ -265,7 +265,7 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) * @func the function to call when the condition happens * @user_data the opaque pointer to pass to @func */ -guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, +guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, GIOFunc func, void *user_data); /** @@ -280,7 +280,7 @@ guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, * * Returns: the number of bytes consumed */ -int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); +int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len); /** * @qemu_chr_fe_write_all: @@ -295,7 +295,7 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); * * Returns: the number of bytes consumed */ -int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len); +int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len); /** * @qemu_chr_fe_read_all: @@ -307,7 +307,7 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len); * * Returns: the number of bytes read */ -int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len); +int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len); /** * @qemu_chr_fe_ioctl: @@ -320,7 +320,7 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len); * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the * return value depends on the semantics of @cmd */ -int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg); +int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg); /** * @qemu_chr_fe_get_msgfd: @@ -333,7 +333,7 @@ int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg); * this function will return -1 until a client sends a new file * descriptor. */ -int qemu_chr_fe_get_msgfd(CharDriverState *s); +int qemu_chr_fe_get_msgfd(CharBackend *be); /** * @qemu_chr_fe_get_msgfds: @@ -346,7 +346,7 @@ int qemu_chr_fe_get_msgfd(CharDriverState *s); * this function will return -1 until a client sends a new set of file * descriptors. */ -int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num); +int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num); /** * @qemu_chr_fe_set_msgfds: @@ -359,13 +359,13 @@ int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num); * * Returns: -1 if fd passing isn't supported. */ -int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num); +int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num); /** * @qemu_chr_fe_claim: * * Claim a backend before using it, should be called before calling - * qemu_chr_add_handlers(). + * qemu_chr_fe_set_handlers(). * * Returns: -1 if the backend is already in use by another frontend, 0 on * success. @@ -436,7 +436,8 @@ void qemu_chr_be_event(CharDriverState *s, int event); /** * @qemu_chr_fe_init: * - * Initializes a front end for the given CharBackend and CharDriver. + * Initializes a front end for the given CharBackend and + * CharDriver. * * Returns: false on error. */ @@ -475,22 +476,8 @@ void qemu_chr_fe_set_handlers(CharBackend *b, */ void qemu_chr_fe_take_focus(CharBackend *b); -void qemu_chr_add_handlers(CharDriverState *s, - IOCanReadHandler *fd_can_read, - IOReadHandler *fd_read, - IOEventHandler *fd_event, - void *opaque); - -/* This API can make handler run in the context what you pass to. */ -void qemu_chr_add_handlers_full(CharDriverState *s, - IOCanReadHandler *fd_can_read, - IOReadHandler *fd_read, - IOEventHandler *fd_event, - void *opaque, - GMainContext *context); - void qemu_chr_be_generic_open(CharDriverState *s); -void qemu_chr_fe_accept_input(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); -- cgit v1.1 From 386f07d1fc02fb4316039994b855c4feb9b091ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:56 +0300 Subject: char: fold qemu_chr_set_handlers in qemu_chr_fe_set_handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qemu_chr_add_handlers*() have been removed in previous change, so the common qemu_chr_set_handlers() is no longer needed. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-17-marcandre.lureau@redhat.com> 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 816c536..f2b3999 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -460,7 +460,8 @@ CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); * @opaque: an opaque pointer for the callbacks * @context: a main loop context or NULL for the default * - * Set the front end char handlers. + * Set the front end char handlers. The front end takes the focus if + * any of the handler is non-NULL. */ void qemu_chr_fe_set_handlers(CharBackend *b, IOCanReadHandler *fd_can_read, -- cgit v1.1 From c39860e6dc90f6ee2e82ee078f978c5d7f3df86a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:58 +0300 Subject: char: replace qemu_chr_claim/release with qemu_chr_fe_init/deinit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that all front end use qemu_chr_fe_init(), we can move chardev claiming in init(), and add a function deinit() to release the chardev and cleanup handlers. The qemu_chr_fe_claim_no_fail() for property are gone, since the property will raise an error instead. In other cases, where there is already an error path, an error is raised instead. Finally, other cases are handled by &error_abort in qemu_chr_fe_init(). Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-19-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index f2b3999..b81dbcc 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -362,35 +362,6 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num); int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num); /** - * @qemu_chr_fe_claim: - * - * Claim a backend before using it, should be called before calling - * qemu_chr_fe_set_handlers(). - * - * Returns: -1 if the backend is already in use by another frontend, 0 on - * success. - */ -int qemu_chr_fe_claim(CharDriverState *s); - -/** - * @qemu_chr_fe_claim_no_fail: - * - * Like qemu_chr_fe_claim, but will exit qemu with an error when the - * backend is already in use. - */ -void qemu_chr_fe_claim_no_fail(CharDriverState *s); - -/** - * @qemu_chr_fe_release: - * - * Release a backend for use by another frontend. - * - * Returns: -1 if the backend is already in use by another frontend, 0 on - * success. - */ -void qemu_chr_fe_release(CharDriverState *s); - -/** * @qemu_chr_be_can_write: * * Determine how much data the front end can currently accept. This function @@ -437,7 +408,8 @@ void qemu_chr_be_event(CharDriverState *s, int event); * @qemu_chr_fe_init: * * Initializes a front end for the given CharBackend and - * CharDriver. + * CharDriver. Call qemu_chr_fe_deinit() to remove the association and + * release the driver. * * Returns: false on error. */ @@ -451,6 +423,13 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); /** + * @qemu_chr_fe_deinit: + * + * Dissociate the CharBackend from the CharDriver. + */ +void qemu_chr_fe_deinit(CharBackend *b); + +/** * @qemu_chr_fe_set_handlers: * @b: a CharBackend * @fd_can_read: callback to get the amount of data the frontend may -- cgit v1.1 From fa394ed625731c18f904578903718bf16617fe92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:52:59 +0300 Subject: char: make some qemu_chr_fe skip if no driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In most cases, front ends do not care about the side effect of CharBackend, so we can simply skip the checks and call the qemu_chr_fe functions even without associated CharDriver. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-20-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index b81dbcc..2f60a10 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -168,6 +168,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename); * @qemu_chr_fe_disconnect: * * Close a fd accpeted by character backend. + * Without associated CharDriver, do nothing. */ void qemu_chr_fe_disconnect(CharBackend *be); @@ -181,7 +182,8 @@ void qemu_chr_cleanup(void); /** * @qemu_chr_fe_wait_connected: * - * Wait for characted backend to be connected. + * Wait for characted backend to be connected, return < 0 on error or + * if no assicated CharDriver. */ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp); @@ -220,6 +222,7 @@ void qemu_chr_free(CharDriverState *chr); * Ask the backend to override its normal echo setting. This only really * applies to the stdio backend and is used by the QMP server such that you * can see what you type if you try to type QMP commands. + * Without associated CharDriver, do nothing. * * @echo true to enable echo, false to disable echo */ @@ -230,13 +233,15 @@ void qemu_chr_fe_set_echo(CharBackend *be, bool echo); * * Set character frontend open status. This is an indication that the * front end is ready (or not) to begin doing I/O. + * Without associated CharDriver, do nothing. */ void qemu_chr_fe_set_open(CharBackend *be, int fe_open); /** * @qemu_chr_fe_event: * - * Send an event from the front end to the back end. + * Send an event from the front end to the back end. It does nothing + * without associated CharDriver. * * @event the event to send */ @@ -245,8 +250,9 @@ void qemu_chr_fe_event(CharBackend *be, int event); /** * @qemu_chr_fe_printf: * - * Write to a character backend using a printf style interface. - * This function is thread-safe. + * Write to a character backend using a printf style interface. This + * function is thread-safe. It does nothing without associated + * CharDriver. * * @fmt see #printf */ @@ -259,7 +265,7 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...) * If the backend is connected, create and add a #GSource that fires * when the given condition (typically G_IO_OUT|G_IO_HUP or G_IO_HUP) * is active; return the #GSource's tag. If it is disconnected, - * return 0. + * or without associated CharDriver, return 0. * * @cond the condition to poll for * @func the function to call when the condition happens @@ -278,7 +284,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, * @buf the data * @len the number of bytes to send * - * Returns: the number of bytes consumed + * Returns: the number of bytes consumed (0 if no assicated CharDriver) */ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len); @@ -293,7 +299,7 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len); * @buf the data * @len the number of bytes to send * - * Returns: the number of bytes consumed + * Returns: the number of bytes consumed (0 if no assicated CharDriver) */ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len); @@ -305,7 +311,7 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len); * @buf the data buffer * @len the number of bytes to read * - * Returns: the number of bytes read + * Returns: the number of bytes read (0 if no assicated CharDriver) */ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len); @@ -317,8 +323,9 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len); * @cmd see CHR_IOCTL_* * @arg the data associated with @cmd * - * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the - * return value depends on the semantics of @cmd + * Returns: if @cmd is not supported by the backend or there is no + * associated CharDriver, -ENOTSUP, otherwise the return + * value depends on the semantics of @cmd */ int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg); @@ -357,7 +364,7 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num); * result in overwriting the fd array with the new value without being send. * Upon writing the message the fd array is freed. * - * Returns: -1 if fd passing isn't supported. + * Returns: -1 if fd passing isn't supported or no associated CharDriver. */ int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num); @@ -418,7 +425,8 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); /** * @qemu_chr_fe_get_driver: * - * Returns the driver associated with a CharBackend or NULL. + * Returns the driver associated with a CharBackend or NULL if no + * associated CharDriver. */ CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); @@ -426,6 +434,8 @@ CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); * @qemu_chr_fe_deinit: * * Dissociate the CharBackend from the CharDriver. + * + * Safe to call without associated CharDriver. */ void qemu_chr_fe_deinit(CharBackend *b); @@ -441,6 +451,8 @@ void qemu_chr_fe_deinit(CharBackend *b); * * Set the front end char handlers. The front end takes the focus if * any of the handler is non-NULL. + * + * Without associated CharDriver, nothing is changed. */ void qemu_chr_fe_set_handlers(CharBackend *b, IOCanReadHandler *fd_can_read, @@ -452,7 +464,9 @@ void qemu_chr_fe_set_handlers(CharBackend *b, /** * @qemu_chr_fe_take_focus: * - * Take the focus (if the front end is muxed) + * Take the focus (if the front end is muxed). + * + * Without associated CharDriver, nothing is changed. */ void qemu_chr_fe_take_focus(CharBackend *b); -- cgit v1.1 From a4afa548fc6dd9842ed86639b4d37d4d1c4ad480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:53:01 +0300 Subject: char: move front end handlers in CharBackend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the hanlders are associated with a CharBackend, rather than the CharDriverState, it is more appropriate to store in CharBackend. This avoids the handler copy dance in qemu_chr_fe_set_handlers() then mux_chr_update_read_handler(), by storing the CharBackend pointer directly. Also a mux CharDriver should go through mux->backends[focused], since chr->be will stay NULL. Before that, it was possible to call chr->handler by mistake with surprising results, for ex through qemu_chr_be_can_write(), which would result in calling the last set handler front end, not the one with focus. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-22-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 2f60a10..7187c3e 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -76,6 +76,10 @@ typedef enum { * CharDriverState */ typedef struct CharBackend { CharDriverState *chr; + IOEventHandler *chr_event; + IOCanReadHandler *chr_can_read; + IOReadHandler *chr_read; + void *opaque; int tag; } CharBackend; @@ -86,22 +90,19 @@ struct CharDriverState { 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 tag); + 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); - IOEventHandler *chr_event; - IOCanReadHandler *chr_can_read; - IOReadHandler *chr_read; - void *handler_opaque; void (*chr_close)(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 (*chr_fe_event)(struct CharDriverState *chr, int event); + CharBackend *be; void *opaque; char *label; char *filename; -- cgit v1.1 From 72ac876248ca2d33b3e1170b2f86fb68daaacdc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:53:02 +0300 Subject: char: rename chr_close/chr_free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function is used to free the backend opaque pointer, let's name it accordingly. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-23-marcandre.lureau@redhat.com> 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 7187c3e..d029d54 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -96,7 +96,7 @@ struct CharDriverState { 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_close)(struct CharDriverState *chr); + 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); -- cgit v1.1 From 39ab61c6d0757ed95badc9315857effdb64e4aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 12:53:03 +0300 Subject: char: remove explicit_fe_open, use a set_handlers argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to keep explicit_fe_open around if it affects only a qemu_chr_fe_set_handlers(). Use an additional argument instead. Signed-off-by: Marc-André Lureau Message-Id: <20161022095318.17775-24-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index d029d54..ae32e1c 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -109,7 +109,6 @@ struct CharDriverState { int logfd; int be_open; int fe_open; - int explicit_fe_open; int explicit_be_open; int avail_connections; int is_mux; @@ -449,6 +448,8 @@ void qemu_chr_fe_deinit(CharBackend *b); * @fd_event: event callback * @opaque: an opaque pointer for the callbacks * @context: a main loop context or NULL for the default + * @set_open: whether to call qemu_chr_fe_set_open() implicitely when + * any of the handler is non-NULL * * Set the front end char handlers. The front end takes the focus if * any of the handler is non-NULL. @@ -460,7 +461,8 @@ void qemu_chr_fe_set_handlers(CharBackend *b, IOReadHandler *fd_read, IOEventHandler *fd_event, void *opaque, - GMainContext *context); + GMainContext *context, + bool set_open); /** * @qemu_chr_fe_take_focus: -- cgit v1.1 From 830896afe3d0ba74f023faba88eac2b5ef91a11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 13:09:37 +0300 Subject: char: move fe_open in CharBackend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fe_open state belongs to front end. Signed-off-by: Marc-André Lureau Message-Id: <20161022100951.19562-1-marcandre.lureau@redhat.com> 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 ae32e1c..2c3060c 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -81,6 +81,7 @@ typedef struct CharBackend { IOReadHandler *chr_read; void *opaque; int tag; + int fe_open; } CharBackend; struct CharDriverState { @@ -108,7 +109,6 @@ struct CharDriverState { char *filename; int logfd; int be_open; - int fe_open; int explicit_be_open; int avail_connections; int is_mux; -- cgit v1.1 From 8cd35662af605a253a629a1adff0cfe8d7045a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 13:09:38 +0300 Subject: char: remove unused CHR_EVENT_FOCUS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usage has long been removed, since commit f220174de8d9. Signed-off-by: Marc-André Lureau Message-Id: <20161022100951.19562-2-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 2c3060c..43da4ac 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -14,7 +14,6 @@ /* character device */ #define CHR_EVENT_BREAK 0 /* serial break char */ -#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */ #define CHR_EVENT_OPENED 2 /* new connection established */ #define CHR_EVENT_MUX_IN 3 /* mux-focus was set to this terminal */ #define CHR_EVENT_MUX_OUT 4 /* mux-focus will move on */ -- cgit v1.1 From 8c260cb13c2d9a889b660e829c3f5769ae030ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 13:09:39 +0300 Subject: char: use an enum for CHR_EVENT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This may help to catch unhandled cases, and avoid having to maintain numbering. Signed-off-by: Marc-André Lureau Message-Id: <20161022100951.19562-3-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 43da4ac..de0d99b 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -13,11 +13,13 @@ /* character device */ -#define CHR_EVENT_BREAK 0 /* serial break char */ -#define CHR_EVENT_OPENED 2 /* new connection established */ -#define CHR_EVENT_MUX_IN 3 /* mux-focus was set to this terminal */ -#define CHR_EVENT_MUX_OUT 4 /* mux-focus will move on */ -#define CHR_EVENT_CLOSED 5 /* connection closed */ +typedef enum { + CHR_EVENT_BREAK, /* serial break char */ + CHR_EVENT_OPENED, /* new connection established */ + CHR_EVENT_MUX_IN, /* mux-focus was set to this terminal */ + CHR_EVENT_MUX_OUT, /* mux-focus will move on */ + CHR_EVENT_CLOSED /* connection closed */ +} QEMUChrEvent; #define CHR_IOCTL_SERIAL_SET_PARAMS 1 -- cgit v1.1 From 58fa54947e6b8a26aaeb1b719eabfd0e1461a2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 13:09:40 +0300 Subject: char: remove unused qemu_chr_fe_event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I introduced this function in d61b0c9a2f7f, but it isn't used. Furthermore, it was incomplete, as it would need to translate QEMU chr events to Spice port events. (presumably it was used in the follow-up NBD-spice series that was not completed: http://lists.gnu.org/archive/html/qemu-devel/2013-11/msg02024.html) Signed-off-by: Marc-André Lureau Message-Id: <20161022100951.19562-4-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index de0d99b..6bad856 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -103,7 +103,6 @@ struct CharDriverState { 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 (*chr_fe_event)(struct CharDriverState *chr, int event); CharBackend *be; void *opaque; char *label; @@ -239,16 +238,6 @@ void qemu_chr_fe_set_echo(CharBackend *be, bool echo); void qemu_chr_fe_set_open(CharBackend *be, int fe_open); /** - * @qemu_chr_fe_event: - * - * Send an event from the front end to the back end. It does nothing - * without associated CharDriver. - * - * @event the event to send - */ -void qemu_chr_fe_event(CharBackend *be, int event); - -/** * @qemu_chr_fe_printf: * * Write to a character backend using a printf style interface. This -- cgit v1.1 From 3aef23d7d8ba559c6e74e931702c63b4c5e23dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 13:09:41 +0300 Subject: char: replace avail_connections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to count the users of a CharDriverState, it can rely on the fact of whether there is a CharBackend associated or if there is enough space in the muxer. Simplify and fold chr_mux_new_fe() in qemu_chr_fe_init() since there is a single user now. Also switch from fprintf to raising error instead. Signed-off-by: Marc-André Lureau Message-Id: <20161022100951.19562-5-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 6bad856..0628b14 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -110,7 +110,6 @@ struct CharDriverState { int logfd; int be_open; int explicit_be_open; - int avail_connections; int is_mux; guint fd_in_tag; bool replay; -- cgit v1.1 From 82878dac6fcd16cb4fa47266bcd3dd03df436dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Sat, 22 Oct 2016 13:09:43 +0300 Subject: char: remove explicit_be_open from CharDriverState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's only used in qmp_chardev_add(), so use a create() argument instead. Also switched to typedef functions for CharDriverParse/CharDriverCreate. Signed-off-by: Marc-André Lureau Message-Id: <20161022100951.19562-7-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 0628b14..0a14942 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -109,7 +109,6 @@ struct CharDriverState { char *filename; int logfd; int be_open; - int explicit_be_open; int is_mux; guint fd_in_tag; bool replay; @@ -474,10 +473,15 @@ 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, - void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp), - CharDriverState *(*create)(const char *id, ChardevBackend *backend, - ChardevReturn *ret, Error **errp)); + CharDriverParse *parse, CharDriverCreate *create); extern int term_escape_char; -- cgit v1.1