diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/exec/memory.h | 6 | ||||
-rw-r--r-- | include/exec/ram_addr.h | 46 | ||||
-rw-r--r-- | include/exec/ramlist.h | 72 | ||||
-rw-r--r-- | include/hw/hw.h | 6 | ||||
-rw-r--r-- | include/hw/i386/pc.h | 7 | ||||
-rw-r--r-- | include/hw/smbios/smbios.h | 2 | ||||
-rw-r--r-- | include/io/dns-resolver.h | 228 | ||||
-rw-r--r-- | include/io/task.h | 154 | ||||
-rw-r--r-- | include/qemu/event_notifier.h | 3 | ||||
-rw-r--r-- | include/qemu/main-loop.h | 15 | ||||
-rw-r--r-- | include/qemu/sockets.h | 2 | ||||
-rw-r--r-- | include/qom/cpu.h | 5 | ||||
-rw-r--r-- | include/sysemu/arch_init.h | 2 | ||||
-rw-r--r-- | include/sysemu/hax.h | 56 | ||||
-rw-r--r-- | include/sysemu/hw_accel.h | 48 | ||||
-rw-r--r-- | include/sysemu/kvm.h | 23 | ||||
-rw-r--r-- | include/sysemu/reset.h | 10 | ||||
-rw-r--r-- | include/sysemu/sysemu.h | 1 |
18 files changed, 555 insertions, 131 deletions
diff --git a/include/exec/memory.h b/include/exec/memory.h index bec9756667..a10044f08f 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -16,16 +16,12 @@ #ifndef CONFIG_USER_ONLY -#define DIRTY_MEMORY_VGA 0 -#define DIRTY_MEMORY_CODE 1 -#define DIRTY_MEMORY_MIGRATION 2 -#define DIRTY_MEMORY_NUM 3 /* num of dirty bits */ - #include "exec/cpu-common.h" #ifndef CONFIG_USER_ONLY #include "exec/hwaddr.h" #endif #include "exec/memattrs.h" +#include "exec/ramlist.h" #include "qemu/queue.h" #include "qemu/int128.h" #include "qemu/notify.h" diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index 54d7108a9e..3e79466a44 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -21,6 +21,7 @@ #ifndef CONFIG_USER_ONLY #include "hw/xen/xen.h" +#include "exec/ramlist.h" struct RAMBlock { struct rcu_head rcu; @@ -35,6 +36,7 @@ struct RAMBlock { char idstr[256]; /* RCU-enabled, writes protected by the ramlist lock */ QLIST_ENTRY(RAMBlock) next; + QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers; int fd; size_t page_size; }; @@ -50,51 +52,7 @@ static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset) return (char *)block->host + offset; } -/* The dirty memory bitmap is split into fixed-size blocks to allow growth - * under RCU. The bitmap for a block can be accessed as follows: - * - * rcu_read_lock(); - * - * DirtyMemoryBlocks *blocks = - * atomic_rcu_read(&ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]); - * - * ram_addr_t idx = (addr >> TARGET_PAGE_BITS) / DIRTY_MEMORY_BLOCK_SIZE; - * unsigned long *block = blocks.blocks[idx]; - * ...access block bitmap... - * - * rcu_read_unlock(); - * - * Remember to check for the end of the block when accessing a range of - * addresses. Move on to the next block if you reach the end. - * - * Organization into blocks allows dirty memory to grow (but not shrink) under - * RCU. When adding new RAMBlocks requires the dirty memory to grow, a new - * DirtyMemoryBlocks array is allocated with pointers to existing blocks kept - * the same. Other threads can safely access existing blocks while dirty - * memory is being grown. When no threads are using the old DirtyMemoryBlocks - * anymore it is freed by RCU (but the underlying blocks stay because they are - * pointed to from the new DirtyMemoryBlocks). - */ -#define DIRTY_MEMORY_BLOCK_SIZE ((ram_addr_t)256 * 1024 * 8) -typedef struct { - struct rcu_head rcu; - unsigned long *blocks[]; -} DirtyMemoryBlocks; - -typedef struct RAMList { - QemuMutex mutex; - RAMBlock *mru_block; - /* RCU-enabled, writes protected by the ramlist lock. */ - QLIST_HEAD(, RAMBlock) blocks; - DirtyMemoryBlocks *dirty_memory[DIRTY_MEMORY_NUM]; - uint32_t version; -} RAMList; -extern RAMList ram_list; - ram_addr_t last_ram_offset(void); -void qemu_mutex_lock_ramlist(void); -void qemu_mutex_unlock_ramlist(void); - RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, bool share, const char *mem_path, Error **errp); diff --git a/include/exec/ramlist.h b/include/exec/ramlist.h new file mode 100644 index 0000000000..c59880de82 --- /dev/null +++ b/include/exec/ramlist.h @@ -0,0 +1,72 @@ +#ifndef RAMLIST_H +#define RAMLIST_H + +#include "qemu/queue.h" +#include "qemu/thread.h" +#include "qemu/rcu.h" + +typedef struct RAMBlockNotifier RAMBlockNotifier; + +#define DIRTY_MEMORY_VGA 0 +#define DIRTY_MEMORY_CODE 1 +#define DIRTY_MEMORY_MIGRATION 2 +#define DIRTY_MEMORY_NUM 3 /* num of dirty bits */ + +/* The dirty memory bitmap is split into fixed-size blocks to allow growth + * under RCU. The bitmap for a block can be accessed as follows: + * + * rcu_read_lock(); + * + * DirtyMemoryBlocks *blocks = + * atomic_rcu_read(&ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]); + * + * ram_addr_t idx = (addr >> TARGET_PAGE_BITS) / DIRTY_MEMORY_BLOCK_SIZE; + * unsigned long *block = blocks.blocks[idx]; + * ...access block bitmap... + * + * rcu_read_unlock(); + * + * Remember to check for the end of the block when accessing a range of + * addresses. Move on to the next block if you reach the end. + * + * Organization into blocks allows dirty memory to grow (but not shrink) under + * RCU. When adding new RAMBlocks requires the dirty memory to grow, a new + * DirtyMemoryBlocks array is allocated with pointers to existing blocks kept + * the same. Other threads can safely access existing blocks while dirty + * memory is being grown. When no threads are using the old DirtyMemoryBlocks + * anymore it is freed by RCU (but the underlying blocks stay because they are + * pointed to from the new DirtyMemoryBlocks). + */ +#define DIRTY_MEMORY_BLOCK_SIZE ((ram_addr_t)256 * 1024 * 8) +typedef struct { + struct rcu_head rcu; + unsigned long *blocks[]; +} DirtyMemoryBlocks; + +typedef struct RAMList { + QemuMutex mutex; + RAMBlock *mru_block; + /* RCU-enabled, writes protected by the ramlist lock. */ + QLIST_HEAD(, RAMBlock) blocks; + DirtyMemoryBlocks *dirty_memory[DIRTY_MEMORY_NUM]; + uint32_t version; + QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers; +} RAMList; +extern RAMList ram_list; + +void qemu_mutex_lock_ramlist(void); +void qemu_mutex_unlock_ramlist(void); + +struct RAMBlockNotifier { + void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size); + void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size); + QLIST_ENTRY(RAMBlockNotifier) next; +}; + +void ram_block_notifier_add(RAMBlockNotifier *n); +void ram_block_notifier_remove(RAMBlockNotifier *n); +void ram_block_notify_add(void *host, size_t size); +void ram_block_notify_remove(void *host, size_t size); + + +#endif /* RAMLIST_H */ diff --git a/include/hw/hw.h b/include/hw/hw.h index 3669ebd916..e22d4ce5fa 100644 --- a/include/hw/hw.h +++ b/include/hw/hw.h @@ -12,11 +12,7 @@ #include "hw/irq.h" #include "migration/vmstate.h" #include "qemu/module.h" - -typedef void QEMUResetHandler(void *opaque); - -void qemu_register_reset(QEMUResetHandler *func, void *opaque); -void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); +#include "sysemu/reset.h" void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 230e9e70c5..738bfd6c60 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -376,15 +376,14 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_2_8 \ HW_COMPAT_2_8 \ - - -#define PC_COMPAT_2_7 \ - HW_COMPAT_2_7 \ {\ .driver = "kvmclock",\ .property = "x-mach-use-reliable-get-clock",\ .value = "off",\ },\ + +#define PC_COMPAT_2_7 \ + HW_COMPAT_2_7 \ {\ .driver = TYPE_X86_CPU,\ .property = "l3-cache",\ diff --git a/include/hw/smbios/smbios.h b/include/hw/smbios/smbios.h index 1cd53cc58c..31e8d5f47e 100644 --- a/include/hw/smbios/smbios.h +++ b/include/hw/smbios/smbios.h @@ -257,7 +257,7 @@ struct smbios_type_127 { struct smbios_structure_header header; } QEMU_PACKED; -void smbios_entry_add(QemuOpts *opts); +void smbios_entry_add(QemuOpts *opts, Error **errp); void smbios_set_cpuid(uint32_t version, uint32_t features); void smbios_set_defaults(const char *manufacturer, const char *product, const char *version, bool legacy_mode, diff --git a/include/io/dns-resolver.h b/include/io/dns-resolver.h new file mode 100644 index 0000000000..2f69c08c13 --- /dev/null +++ b/include/io/dns-resolver.h @@ -0,0 +1,228 @@ +/* + * QEMU DNS resolver + * + * Copyright (c) 2016-2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef QIO_DNS_RESOLVER_H +#define QIO_DNS_RESOLVER_H + +#include "qemu-common.h" +#include "qom/object.h" +#include "io/task.h" + +#define TYPE_QIO_DNS_RESOLVER "qio-dns-resolver" +#define QIO_DNS_RESOLVER(obj) \ + OBJECT_CHECK(QIODNSResolver, (obj), TYPE_QIO_DNS_RESOLVER) +#define QIO_DNS_RESOLVER_CLASS(klass) \ + OBJECT_CLASS_CHECK(QIODNSResolverClass, klass, TYPE_QIO_DNS_RESOLVER) +#define QIO_DNS_RESOLVER_GET_CLASS(obj) \ + OBJECT_GET_CLASS(QIODNSResolverClass, obj, TYPE_QIO_DNS_RESOLVER) + +typedef struct QIODNSResolver QIODNSResolver; +typedef struct QIODNSResolverClass QIODNSResolverClass; + +/** + * QIODNSResolver: + * + * The QIODNSResolver class provides a framework for doing + * DNS resolution on SocketAddress objects, independently + * of socket creation. + * + * <example> + * <title>Resolving addresses synchronously</title> + * <programlisting> + * int mylisten(SocketAddress *addr, Error **errp) { + * QIODNSResolver *resolver = qio_dns_resolver_get_instance(); + * SocketAddress **rawaddrs = NULL; + * size_t nrawaddrs = 0; + * Error *err = NULL; + * QIOChannel **socks = NULL; + * size_t nsocks = 0; + * + * if (qio_dns_resolver_lookup_sync(dns, addr, &nrawaddrs, + * &rawaddrs, errp) < 0) { + * return -1; + * } + * + * for (i = 0; i < nrawaddrs; i++) { + * QIOChannel *sock = qio_channel_new(); + * Error *local_err = NULL; + * qio_channel_listen_sync(sock, rawaddrs[i], &local_err); + * if (local_err) { + * error_propagate(&err, local_err); + * } else { + * socks = g_renew(QIOChannelSocket *, socks, nsocks + 1); + * socks[nsocks++] = sock; + * } + * qapi_free_SocketAddress(rawaddrs[i]); + * } + * g_free(rawaddrs); + * + * if (nsocks == 0) { + * error_propagate(errp, err); + * } else { + * error_free(err); + * } + * } + * </programlisting> + * </example> + * + * <example> + * <title>Resolving addresses asynchronously</title> + * <programlisting> + * typedef struct MyListenData { + * Error *err; + * QIOChannelSocket **socks; + * size_t nsocks; + * } MyListenData; + * + * void mylistenresult(QIOTask *task, void *opaque) { + * MyListenData *data = opaque; + * QIODNSResolver *resolver = + * QIO_DNS_RESOLVER(qio_task_get_source(task); + * SocketAddress **rawaddrs = NULL; + * size_t nrawaddrs = 0; + * Error *err = NULL; + * + * if (qio_task_propagate_error(task, &data->err)) { + * return; + * } + * + * qio_dns_resolver_lookup_result(resolver, task, + * &nrawaddrs, &rawaddrs); + * + * for (i = 0; i < nrawaddrs; i++) { + * QIOChannel *sock = qio_channel_new(); + * Error *local_err = NULL; + * qio_channel_listen_sync(sock, rawaddrs[i], &local_err); + * if (local_err) { + * error_propagate(&err, local_err); + * } else { + * socks = g_renew(QIOChannelSocket *, socks, nsocks + 1); + * socks[nsocks++] = sock; + * } + * qapi_free_SocketAddress(rawaddrs[i]); + * } + * g_free(rawaddrs); + * + * if (nsocks == 0) { + * error_propagate(&data->err, err); + * } else { + * error_free(err); + * } + * } + * + * void mylisten(SocketAddress *addr, MyListenData *data) { + * QIODNSResolver *resolver = qio_dns_resolver_get_instance(); + * qio_dns_resolver_lookup_async(dns, addr, + * mylistenresult, data, NULL); + * } + * </programlisting> + * </example> + */ +struct QIODNSResolver { + Object parent; +}; + +struct QIODNSResolverClass { + ObjectClass parent; +}; + + +/** + * qio_dns_resolver_get_instance: + * + * Get the singleton dns resolver instance. The caller + * does not own a reference on the returned object. + * + * Returns: the single dns resolver instance + */ +QIODNSResolver *qio_dns_resolver_get_instance(void); + +/** + * qio_dns_resolver_lookup_sync: + * @resolver: the DNS resolver instance + * @addr: the address to resolve + * @naddr: pointer to hold number of resolved addresses + * @addrs: pointer to hold resolved addresses + * @errp: pointer to NULL initialized error object + * + * This will attempt to resolve the address provided + * in @addr. If resolution succeeds, @addrs will be filled + * with all the resolved addresses. @naddrs will specify + * the number of entries allocated in @addrs. The caller + * is responsible for freeing each entry in @addrs, as + * well as @addrs itself. @naddrs is guaranteed to be + * greater than zero on success. + * + * DNS resolution will be done synchronously so execution + * of the caller may be blocked for an arbitrary length + * of time. + * + * Returns: 0 if resolution was successful, -1 on error + */ +int qio_dns_resolver_lookup_sync(QIODNSResolver *resolver, + SocketAddress *addr, + size_t *naddrs, + SocketAddress ***addrs, + Error **errp); + +/** + * qio_dns_resolver_lookup_async: + * @resolver: the DNS resolver instance + * @addr: the address to resolve + * @func: the callback to invoke on lookup completion + * @opaque: data blob to pass to @func + * @notify: the callback to free @opaque, or NULL + * + * This will attempt to resolve the address provided + * in @addr. The callback @func will be invoked when + * resolution has either completed or failed. On + * success, the @func should call the method + * qio_dns_resolver_lookup_result() to obtain the + * results. + * + * DNS resolution will be done asynchronously so execution + * of the caller will not be blocked. + */ +void qio_dns_resolver_lookup_async(QIODNSResolver *resolver, + SocketAddress *addr, + QIOTaskFunc func, + gpointer opaque, + GDestroyNotify notify); + +/** + * qio_dns_resolver_lookup_result: + * @resolver: the DNS resolver instance + * @task: the task object to get results for + * @naddr: pointer to hold number of resolved addresses + * @addrs: pointer to hold resolved addresses + * + * This method should be called from the callback passed + * to qio_dns_resolver_lookup_async() in order to obtain + * results. @addrs will be filled with all the resolved + * addresses. @naddrs will specify the number of entries + * allocated in @addrs. The caller is responsible for + * freeing each entry in @addrs, as well as @addrs itself. + */ +void qio_dns_resolver_lookup_result(QIODNSResolver *resolver, + QIOTask *task, + size_t *naddrs, + SocketAddress ***addrs); + +#endif /* QIO_DNS_RESOLVER_H */ diff --git a/include/io/task.h b/include/io/task.h index 42028cb424..6021f51336 100644 --- a/include/io/task.h +++ b/include/io/task.h @@ -26,13 +26,11 @@ typedef struct QIOTask QIOTask; -typedef void (*QIOTaskFunc)(Object *source, - Error *err, +typedef void (*QIOTaskFunc)(QIOTask *task, gpointer opaque); -typedef int (*QIOTaskWorker)(QIOTask *task, - Error **errp, - gpointer opaque); +typedef void (*QIOTaskWorker)(QIOTask *task, + gpointer opaque); /** * QIOTask: @@ -44,12 +42,12 @@ typedef int (*QIOTaskWorker)(QIOTask *task, * a public API which accepts a task callback: * * <example> - * <title>Task callback function signature</title> + * <title>Task function signature</title> * <programlisting> * void myobject_operation(QMyObject *obj, * QIOTaskFunc *func, * gpointer opaque, - * GDestroyNotify *notify); + * GDestroyNotify notify); * </programlisting> * </example> * @@ -57,17 +55,41 @@ typedef int (*QIOTaskWorker)(QIOTask *task, * is data to pass to it. The optional 'notify' function is used * to free 'opaque' when no longer needed. * - * Now, lets say the implementation of this method wants to set - * a timer to run once a second checking for completion of some - * activity. It would do something like + * When the operation completes, the 'func' callback will be + * invoked, allowing the calling code to determine the result + * of the operation. An example QIOTaskFunc implementation may + * look like * * <example> - * <title>Task callback function implementation</title> + * <title>Task callback implementation</title> + * <programlisting> + * static void myobject_operation_notify(QIOTask *task, + * gpointer opaque) + * { + * Error *err = NULL; + * if (qio_task_propagate_error(task, &err)) { + * ...deal with the failure... + * error_free(err); + * } else { + * QMyObject *src = QMY_OBJECT(qio_task_get_source(task)); + * ...deal with the completion... + * } + * } + * </programlisting> + * </example> + * + * Now, lets say the implementation of the method using the + * task wants to set a timer to run once a second checking + * for completion of some activity. It would do something + * like + * + * <example> + * <title>Task function implementation</title> * <programlisting> * void myobject_operation(QMyObject *obj, * QIOTaskFunc *func, * gpointer opaque, - * GDestroyNotify *notify) + * GDestroyNotify notify) * { * QIOTask *task; * @@ -102,8 +124,8 @@ typedef int (*QIOTaskWorker)(QIOTask *task, * * ...check something important... * if (err) { - * qio_task_abort(task, err); - * error_free(task); + * qio_task_set_error(task, err); + * qio_task_complete(task); * return FALSE; * } else if (...work is completed ...) { * qio_task_complete(task); @@ -115,6 +137,10 @@ typedef int (*QIOTaskWorker)(QIOTask *task, * </programlisting> * </example> * + * The 'qio_task_complete' call in this method will trigger + * the callback func 'myobject_operation_notify' shown + * earlier to deal with the results. + * * Once this function returns false, object_unref will be called * automatically on the task causing it to be released and the * ref on QMyObject dropped too. @@ -136,25 +162,23 @@ typedef int (*QIOTaskWorker)(QIOTask *task, * socket listen using QIOTask would require: * * <example> - * static int myobject_listen_worker(QIOTask *task, - * Error **errp, - * gpointer opaque) + * static void myobject_listen_worker(QIOTask *task, + * gpointer opaque) * { * QMyObject obj = QMY_OBJECT(qio_task_get_source(task)); * SocketAddress *addr = opaque; + * Error *err = NULL; * - * obj->fd = socket_listen(addr, errp); - * if (obj->fd < 0) { - * return -1; - * } - * return 0; + * obj->fd = socket_listen(addr, &err); + * + qio_task_set_error(task, err); * } * * void myobject_listen_async(QMyObject *obj, * SocketAddress *addr, * QIOTaskFunc *func, * gpointer opaque, - * GDestroyNotify *notify) + * GDestroyNotify notify) * { * QIOTask *task; * SocketAddress *addrCopy; @@ -187,8 +211,8 @@ typedef int (*QIOTaskWorker)(QIOTask *task, * 'err' attribute in the task object to determine if * the operation was successful or not. * - * The returned task will be released when one of - * qio_task_abort() or qio_task_complete() are invoked. + * The returned task will be released when qio_task_complete() + * is invoked. * * Returns: the task struct */ @@ -204,10 +228,8 @@ QIOTask *qio_task_new(Object *source, * @opaque: opaque data to pass to @worker * @destroy: function to free @opaque * - * Run a task in a background thread. If @worker - * returns 0 it will call qio_task_complete() in - * the main event thread context. If @worker - * returns -1 it will call qio_task_abort() in + * Run a task in a background thread. When @worker + * returns it will call qio_task_complete() in * the main event thread context. */ void qio_task_run_in_thread(QIOTask *task, @@ -219,24 +241,69 @@ void qio_task_run_in_thread(QIOTask *task, * qio_task_complete: * @task: the task struct * - * Mark the operation as successfully completed - * and free the memory for @task. + * Invoke the completion callback for @task and + * then free its memory. */ void qio_task_complete(QIOTask *task); + +/** + * qio_task_set_error: + * @task: the task struct + * @err: pointer to the error, or NULL + * + * Associate an error with the task, which can later + * be retrieved with the qio_task_propagate_error() + * method. This method takes ownership of @err, so + * it is not valid to access it after this call + * completes. If @err is NULL this is a no-op. If + * this is call multiple times, only the first + * provided @err will be recorded, later ones will + * be discarded and freed. + */ +void qio_task_set_error(QIOTask *task, + Error *err); + + /** - * qio_task_abort: + * qio_task_propagate_error: * @task: the task struct - * @err: the error to record for the operation + * @errp: pointer to a NULL-initialized error object + * + * Propagate the error associated with @task + * into @errp. + * + * Returns: true if an error was propagated, false otherwise + */ +bool qio_task_propagate_error(QIOTask *task, + Error **errp); + + +/** + * qio_task_set_result_pointer: + * @task: the task struct + * @result: pointer to the result data + * + * Associate an opaque result with the task, + * which can later be retrieved with the + * qio_task_get_result_pointer() method + * + */ +void qio_task_set_result_pointer(QIOTask *task, + gpointer result, + GDestroyNotify notify); + + +/** + * qio_task_get_result_pointer: + * @task: the task struct + * + * Retrieve the opaque result data associated + * with the task, if any. * - * Mark the operation as failed, with @err providing - * details about the failure. The @err may be freed - * afer the function returns, as the notification - * callback is invoked synchronously. The @task will - * be freed when this call completes. + * Returns: the task result, or NULL */ -void qio_task_abort(QIOTask *task, - Error *err); +gpointer qio_task_get_result_pointer(QIOTask *task); /** @@ -244,9 +311,10 @@ void qio_task_abort(QIOTask *task, * @task: the task struct * * Get the source object associated with the background - * task. This returns a new reference to the object, - * which the caller must released with object_unref() - * when no longer required. + * task. The caller does not own a reference on the + * returned Object, and so should call object_ref() + * if it wants to keep the object pointer outside the + * lifetime of the QIOTask object. * * Returns: the source object */ diff --git a/include/qemu/event_notifier.h b/include/qemu/event_notifier.h index e326990db4..599c99f1a5 100644 --- a/include/qemu/event_notifier.h +++ b/include/qemu/event_notifier.h @@ -34,9 +34,6 @@ int event_notifier_init(EventNotifier *, int active); void event_notifier_cleanup(EventNotifier *); int event_notifier_set(EventNotifier *); int event_notifier_test_and_clear(EventNotifier *); -int event_notifier_set_handler(EventNotifier *, - bool is_external, - EventNotifierHandler *); #ifdef CONFIG_POSIX void event_notifier_init_fd(EventNotifier *, int fd); diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index a9d4f23cd9..d7e24af78d 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -203,6 +203,21 @@ void qemu_set_fd_handler(int fd, IOHandler *fd_write, void *opaque); + +/** + * event_notifier_set_handler: Register an EventNotifier with the main loop + * + * This function tells the main loop to wake up whenever the + * #EventNotifier was set. + * + * @e: The #EventNotifier to be observed. + * + * @handler: A level-triggered callback that is fired when @e + * has been set. @e is passed to it as a parameter. + */ +void event_notifier_set_handler(EventNotifier *e, + EventNotifierHandler *handler); + GSource *iohandler_get_g_source(void); AioContext *iohandler_get_aio_context(void); #ifdef CONFIG_POSIX diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 5589e6842b..5f1bab9b3e 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -32,6 +32,8 @@ int socket_set_fast_reuse(int fd); */ typedef void NonBlockingConnectHandler(int fd, Error *err, void *opaque); +int inet_ai_family_from_address(InetSocketAddress *addr, + Error **errp); InetSocketAddress *inet_parse(const char *str, Error **errp); int inet_connect(const char *str, Error **errp); int inet_connect_saddr(InetSocketAddress *saddr, Error **errp, diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 3f79a8e955..ca4d0fb1b4 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -227,6 +227,8 @@ struct CPUWatchpoint { struct KVMState; struct kvm_run; +struct hax_vcpu_state; + #define TB_JMP_CACHE_BITS 12 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) @@ -392,6 +394,9 @@ struct CPUState { (absolute value) offset as small as possible. This reduces code size, especially for hosts without large memory offsets. */ uint32_t tcg_exit_req; + + bool hax_vcpu_dirty; + struct hax_vcpu_state *hax_vcpu; }; QTAILQ_HEAD(CPUTailQ, CPUState); diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index 1c9dad1b72..20b01e3004 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -28,8 +28,6 @@ enum { extern const uint32_t arch_type; void select_soundhw(const char *optarg); -void do_acpitable_option(const QemuOpts *opts); -void do_smbios_option(QemuOpts *opts); void audio_init(void); int kvm_available(void); int xen_available(void); diff --git a/include/sysemu/hax.h b/include/sysemu/hax.h new file mode 100644 index 0000000000..d9f023918e --- /dev/null +++ b/include/sysemu/hax.h @@ -0,0 +1,56 @@ +/* + * QEMU HAXM support + * + * Copyright IBM, Corp. 2008 + * + * Authors: + * Anthony Liguori <aliguori@us.ibm.com> + * + * Copyright (c) 2011 Intel Corporation + * Written by: + * Jiang Yunhong<yunhong.jiang@intel.com> + * Xin Xiaohui<xiaohui.xin@intel.com> + * Zhang Xiantao<xiantao.zhang@intel.com> + * + * Copyright 2016 Google, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_HAX_H +#define QEMU_HAX_H + +#include "config-host.h" +#include "qemu-common.h" + +int hax_sync_vcpus(void); +int hax_init_vcpu(CPUState *cpu); +int hax_smp_cpu_exec(CPUState *cpu); +int hax_populate_ram(uint64_t va, uint32_t size); + +void hax_cpu_synchronize_state(CPUState *cpu); +void hax_cpu_synchronize_post_reset(CPUState *cpu); +void hax_cpu_synchronize_post_init(CPUState *cpu); + +#ifdef CONFIG_HAX + +int hax_enabled(void); + +#include "hw/hw.h" +#include "qemu/bitops.h" +#include "exec/memory.h" +int hax_vcpu_destroy(CPUState *cpu); +void hax_raise_event(CPUState *cpu); +void hax_reset_vcpu_state(void *opaque); +#include "target/i386/hax-interface.h" +#include "target/i386/hax-i386.h" + +#else /* CONFIG_HAX */ + +#define hax_enabled() (0) + +#endif /* CONFIG_HAX */ + +#endif /* QEMU_HAX_H */ diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h new file mode 100644 index 0000000000..c9b3105bc7 --- /dev/null +++ b/include/sysemu/hw_accel.h @@ -0,0 +1,48 @@ +/* + * QEMU Hardware accelertors support + * + * Copyright 2016 Google, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_HW_ACCEL_H +#define QEMU_HW_ACCEL_H + +#include "qom/cpu.h" +#include "sysemu/hax.h" +#include "sysemu/kvm.h" + +static inline void cpu_synchronize_state(CPUState *cpu) +{ + if (kvm_enabled()) { + kvm_cpu_synchronize_state(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_state(cpu); + } +} + +static inline void cpu_synchronize_post_reset(CPUState *cpu) +{ + if (kvm_enabled()) { + kvm_cpu_synchronize_post_reset(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_post_reset(cpu); + } +} + +static inline void cpu_synchronize_post_init(CPUState *cpu) +{ + if (kvm_enabled()) { + kvm_cpu_synchronize_post_init(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_post_init(cpu); + } +} + +#endif /* QEMU_HW_ACCEL_H */ diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index df67cc0672..3045ee7678 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -461,29 +461,6 @@ void kvm_cpu_synchronize_state(CPUState *cpu); void kvm_cpu_synchronize_post_reset(CPUState *cpu); void kvm_cpu_synchronize_post_init(CPUState *cpu); -/* generic hooks - to be moved/refactored once there are more users */ - -static inline void cpu_synchronize_state(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_state(cpu); - } -} - -static inline void cpu_synchronize_post_reset(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_post_reset(cpu); - } -} - -static inline void cpu_synchronize_post_init(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_post_init(cpu); - } -} - /** * kvm_irqchip_add_msi_route - Add MSI route for specific vector * @s: KVM state diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h new file mode 100644 index 0000000000..0b0d6d7598 --- /dev/null +++ b/include/sysemu/reset.h @@ -0,0 +1,10 @@ +#ifndef QEMU_SYSEMU_RESET_H +#define QEMU_SYSEMU_RESET_H + +typedef void QEMUResetHandler(void *opaque); + +void qemu_register_reset(QEMUResetHandler *func, void *opaque); +void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); +void qemu_devices_reset(void); + +#endif diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index cccde56454..ff8ffb5e47 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -63,7 +63,6 @@ void qemu_system_vmstop_request_prepare(void); int qemu_shutdown_requested_get(void); int qemu_reset_requested_get(void); void qemu_system_killed(int signal, pid_t pid); -void qemu_devices_reset(void); void qemu_system_reset(bool report); void qemu_system_guest_panicked(void); size_t qemu_target_page_bits(void); |