* Longstanding chardev race condition fix (Berto)
* Cleanups and tests from the Meson POC (Marc-André, myself) * Coalesced range cleanup (Peter) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJdXX8PAAoJEL/70l94x66DkR4H/1Phk6zuTQfHISBXGACjDkFS kbVq2WE6gQXwqmbf/04mM/DZzsi9bCsHFlGhf7mFQoq9g2ywm7kgtjF7kiRewlqh YZYSLLEoEVKpZRxC8kQbbbZ/tfYDM7ejnKMPFK6ibNiiN7acuKJuY8z18OLg4PEA V5LfuaGPjsx98NUAuU6bHRs5ZDCL25DzBQ9pdcE5wkJ2pVJXpP6UBafN55l8Clzq PzuuNnP18QyuqbdRVm5YrY+0nUeDCdlU2clCC3/H9rS57Ts/z3gocs71VT8GKqIa ppNRg3wVADXtfql3MkpnmvZefx+QK6DguAAiKR4CtPax7Xx6WoA4DwtMKfsLHsY= =RwuS -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging * Longstanding chardev race condition fix (Berto) * Cleanups and tests from the Meson POC (Marc-André, myself) * Coalesced range cleanup (Peter) # gpg: Signature made Wed 21 Aug 2019 18:27:43 BST # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: char-socket: Lock tcp_chr_disconnect() and socket_reconnect_timeout() main-loop: Fix GSource leak in qio_task_thread_worker() memory: Fix up memory_region_{add|del}_coalescing memory: Remove has_coalesced_range counter memory: Split zones when do coalesced_io_del() memory: Refactor memory_region_clear_coalescing minikconf: don't print CONFIG_FOO=n lines configure: remove AUTOCONF_HOST tests: add module loading test module: return success on module load module: use g_hash_table_add() configure: define CONFIG_TOOLS here qemu-ga: clean up TOOLS variable Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8109234808
9
Makefile
9
Makefile
@ -84,8 +84,7 @@ endif
|
|||||||
|
|
||||||
include $(SRC_PATH)/rules.mak
|
include $(SRC_PATH)/rules.mak
|
||||||
|
|
||||||
# notempy and lor are defined in rules.mak
|
# lor is defined in rules.mak
|
||||||
CONFIG_TOOLS := $(call notempty,$(TOOLS))
|
|
||||||
CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS))
|
CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS))
|
||||||
|
|
||||||
# Create QEMU_PKGVERSION and FULL_VERSION strings
|
# Create QEMU_PKGVERSION and FULL_VERSION strings
|
||||||
@ -681,7 +680,7 @@ clean: recurse-clean
|
|||||||
! -path ./roms/edk2/BaseTools/Source/Python/UPT/Dll/sqlite3.dll \
|
! -path ./roms/edk2/BaseTools/Source/Python/UPT/Dll/sqlite3.dll \
|
||||||
-exec rm {} +
|
-exec rm {} +
|
||||||
rm -f $(edk2-decompressed)
|
rm -f $(edk2-decompressed)
|
||||||
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga$(EXESUF) TAGS cscope.* *.pod *~ */*~
|
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) TAGS cscope.* *.pod *~ */*~
|
||||||
rm -f fsdev/*.pod scsi/*.pod
|
rm -f fsdev/*.pod scsi/*.pod
|
||||||
rm -f qemu-img-cmds.h
|
rm -f qemu-img-cmds.h
|
||||||
rm -f ui/shader/*-vert.h ui/shader/*-frag.h
|
rm -f ui/shader/*-vert.h ui/shader/*-frag.h
|
||||||
@ -809,7 +808,7 @@ ifdef CONFIG_POSIX
|
|||||||
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
|
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
|
||||||
$(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
|
$(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
|
||||||
$(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
|
$(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
|
||||||
ifneq ($(TOOLS),)
|
ifeq ($(CONFIG_TOOLS),y)
|
||||||
$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
|
$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
|
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
|
||||||
$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
|
$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
|
||||||
@ -845,7 +844,7 @@ install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-localstated
|
|||||||
$(if $(INSTALL_BLOBS),$(edk2-decompressed)) \
|
$(if $(INSTALL_BLOBS),$(edk2-decompressed)) \
|
||||||
recurse-install
|
recurse-install
|
||||||
ifneq ($(TOOLS),)
|
ifneq ($(TOOLS),)
|
||||||
$(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir))
|
$(call install-prog,$(TOOLS),$(DESTDIR)$(bindir))
|
||||||
endif
|
endif
|
||||||
ifneq ($(CONFIG_MODULES),)
|
ifneq ($(CONFIG_MODULES),)
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
|
$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
|
||||||
|
@ -150,7 +150,7 @@ static void tcp_chr_accept(QIONetListener *listener,
|
|||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
static int tcp_chr_read_poll(void *opaque);
|
static int tcp_chr_read_poll(void *opaque);
|
||||||
static void tcp_chr_disconnect(Chardev *chr);
|
static void tcp_chr_disconnect_locked(Chardev *chr);
|
||||||
|
|
||||||
/* Called with chr_write_lock held. */
|
/* Called with chr_write_lock held. */
|
||||||
static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
||||||
@ -174,7 +174,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
|||||||
|
|
||||||
if (ret < 0 && errno != EAGAIN) {
|
if (ret < 0 && errno != EAGAIN) {
|
||||||
if (tcp_chr_read_poll(chr) <= 0) {
|
if (tcp_chr_read_poll(chr) <= 0) {
|
||||||
tcp_chr_disconnect(chr);
|
tcp_chr_disconnect_locked(chr);
|
||||||
return len;
|
return len;
|
||||||
} /* else let the read handler finish it properly */
|
} /* else let the read handler finish it properly */
|
||||||
}
|
}
|
||||||
@ -469,8 +469,9 @@ static void update_disconnected_filename(SocketChardev *s)
|
|||||||
/* NB may be called even if tcp_chr_connect has not been
|
/* NB may be called even if tcp_chr_connect has not been
|
||||||
* reached, due to TLS or telnet initialization failure,
|
* reached, due to TLS or telnet initialization failure,
|
||||||
* so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
|
* so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
|
||||||
|
* This must be called with chr->chr_write_lock held.
|
||||||
*/
|
*/
|
||||||
static void tcp_chr_disconnect(Chardev *chr)
|
static void tcp_chr_disconnect_locked(Chardev *chr)
|
||||||
{
|
{
|
||||||
SocketChardev *s = SOCKET_CHARDEV(chr);
|
SocketChardev *s = SOCKET_CHARDEV(chr);
|
||||||
bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
|
bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
|
||||||
@ -490,6 +491,13 @@ static void tcp_chr_disconnect(Chardev *chr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tcp_chr_disconnect(Chardev *chr)
|
||||||
|
{
|
||||||
|
qemu_mutex_lock(&chr->chr_write_lock);
|
||||||
|
tcp_chr_disconnect_locked(chr);
|
||||||
|
qemu_mutex_unlock(&chr->chr_write_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
|
static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
|
||||||
{
|
{
|
||||||
Chardev *chr = CHARDEV(opaque);
|
Chardev *chr = CHARDEV(opaque);
|
||||||
@ -1131,8 +1139,10 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
|
|||||||
Chardev *chr = CHARDEV(opaque);
|
Chardev *chr = CHARDEV(opaque);
|
||||||
SocketChardev *s = SOCKET_CHARDEV(opaque);
|
SocketChardev *s = SOCKET_CHARDEV(opaque);
|
||||||
|
|
||||||
|
qemu_mutex_lock(&chr->chr_write_lock);
|
||||||
g_source_unref(s->reconnect_timer);
|
g_source_unref(s->reconnect_timer);
|
||||||
s->reconnect_timer = NULL;
|
s->reconnect_timer = NULL;
|
||||||
|
qemu_mutex_unlock(&chr->chr_write_lock);
|
||||||
|
|
||||||
if (chr->be_open) {
|
if (chr->be_open) {
|
||||||
return false;
|
return false;
|
||||||
|
10
configure
vendored
10
configure
vendored
@ -6129,7 +6129,7 @@ if [ "$guest_agent" != "no" ]; then
|
|||||||
if [ "$softmmu" = no -a "$want_tools" = no ] ; then
|
if [ "$softmmu" = no -a "$want_tools" = no ] ; then
|
||||||
guest_agent=no
|
guest_agent=no
|
||||||
elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
|
elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
|
||||||
tools="qemu-ga $tools"
|
tools="qemu-ga\$(EXESUF) $tools"
|
||||||
guest_agent=yes
|
guest_agent=yes
|
||||||
elif [ "$guest_agent" != yes ]; then
|
elif [ "$guest_agent" != yes ]; then
|
||||||
guest_agent=no
|
guest_agent=no
|
||||||
@ -6614,6 +6614,9 @@ fi
|
|||||||
if test "$profiler" = "yes" ; then
|
if test "$profiler" = "yes" ; then
|
||||||
echo "CONFIG_PROFILER=y" >> $config_host_mak
|
echo "CONFIG_PROFILER=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
if test "$want_tools" = "yes" ; then
|
||||||
|
echo "CONFIG_TOOLS=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
if test "$slirp" != "no"; then
|
if test "$slirp" != "no"; then
|
||||||
echo "CONFIG_SLIRP=y" >> $config_host_mak
|
echo "CONFIG_SLIRP=y" >> $config_host_mak
|
||||||
echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
|
echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
|
||||||
@ -7360,11 +7363,6 @@ if test "$sparse" = "yes" ; then
|
|||||||
echo "HOST_CC := REAL_CC=\"\$(HOST_CC)\" cgcc" >> $config_host_mak
|
echo "HOST_CC := REAL_CC=\"\$(HOST_CC)\" cgcc" >> $config_host_mak
|
||||||
echo "QEMU_CFLAGS += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
|
echo "QEMU_CFLAGS += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
if test "$cross_prefix" != ""; then
|
|
||||||
echo "AUTOCONF_HOST := --host=${cross_prefix%-}" >> $config_host_mak
|
|
||||||
else
|
|
||||||
echo "AUTOCONF_HOST := " >> $config_host_mak
|
|
||||||
fi
|
|
||||||
echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
|
echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
|
||||||
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
|
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
|
||||||
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
|
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
|
||||||
|
@ -65,6 +65,6 @@ void register_module_init(void (*fn)(void), module_init_type type);
|
|||||||
void register_dso_module_init(void (*fn)(void), module_init_type type);
|
void register_dso_module_init(void (*fn)(void), module_init_type type);
|
||||||
|
|
||||||
void module_call_init(module_init_type type);
|
void module_call_init(module_init_type type);
|
||||||
void module_load_one(const char *prefix, const char *lib_name);
|
bool module_load_one(const char *prefix, const char *lib_name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -136,6 +136,7 @@ static gpointer qio_task_thread_worker(gpointer opaque)
|
|||||||
qio_task_thread_result, task, NULL);
|
qio_task_thread_result, task, NULL);
|
||||||
g_source_attach(task->thread->completion,
|
g_source_attach(task->thread->completion,
|
||||||
task->thread->context);
|
task->thread->context);
|
||||||
|
g_source_unref(task->thread->completion);
|
||||||
trace_qio_task_thread_source_attach(task, task->thread->completion);
|
trace_qio_task_thread_source_attach(task, task->thread->completion);
|
||||||
|
|
||||||
qemu_cond_signal(&task->thread_cond);
|
qemu_cond_signal(&task->thread_cond);
|
||||||
|
103
memory.c
103
memory.c
@ -217,7 +217,6 @@ struct FlatRange {
|
|||||||
bool romd_mode;
|
bool romd_mode;
|
||||||
bool readonly;
|
bool readonly;
|
||||||
bool nonvolatile;
|
bool nonvolatile;
|
||||||
int has_coalesced_range;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FOR_EACH_FLAT_RANGE(var, view) \
|
#define FOR_EACH_FLAT_RANGE(var, view) \
|
||||||
@ -654,7 +653,6 @@ static void render_memory_region(FlatView *view,
|
|||||||
fr.romd_mode = mr->romd_mode;
|
fr.romd_mode = mr->romd_mode;
|
||||||
fr.readonly = readonly;
|
fr.readonly = readonly;
|
||||||
fr.nonvolatile = nonvolatile;
|
fr.nonvolatile = nonvolatile;
|
||||||
fr.has_coalesced_range = 0;
|
|
||||||
|
|
||||||
/* Render the region itself into any gaps left by the current view. */
|
/* Render the region itself into any gaps left by the current view. */
|
||||||
for (i = 0; i < view->nr && int128_nz(remain); ++i) {
|
for (i = 0; i < view->nr && int128_nz(remain); ++i) {
|
||||||
@ -855,46 +853,55 @@ static void address_space_update_ioeventfds(AddressSpace *as)
|
|||||||
flatview_unref(view);
|
flatview_unref(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify the memory listeners about the coalesced IO change events of
|
||||||
|
* range `cmr'. Only the part that has intersection of the specified
|
||||||
|
* FlatRange will be sent.
|
||||||
|
*/
|
||||||
|
static void flat_range_coalesced_io_notify(FlatRange *fr, AddressSpace *as,
|
||||||
|
CoalescedMemoryRange *cmr, bool add)
|
||||||
|
{
|
||||||
|
AddrRange tmp;
|
||||||
|
|
||||||
|
tmp = addrrange_shift(cmr->addr,
|
||||||
|
int128_sub(fr->addr.start,
|
||||||
|
int128_make64(fr->offset_in_region)));
|
||||||
|
if (!addrrange_intersects(tmp, fr->addr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tmp = addrrange_intersection(tmp, fr->addr);
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add,
|
||||||
|
int128_get64(tmp.start),
|
||||||
|
int128_get64(tmp.size));
|
||||||
|
} else {
|
||||||
|
MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del,
|
||||||
|
int128_get64(tmp.start),
|
||||||
|
int128_get64(tmp.size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as)
|
static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as)
|
||||||
{
|
{
|
||||||
if (!fr->has_coalesced_range) {
|
CoalescedMemoryRange *cmr;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (--fr->has_coalesced_range > 0) {
|
QTAILQ_FOREACH(cmr, &fr->mr->coalesced, link) {
|
||||||
return;
|
flat_range_coalesced_io_notify(fr, as, cmr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del,
|
|
||||||
int128_get64(fr->addr.start),
|
|
||||||
int128_get64(fr->addr.size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flat_range_coalesced_io_add(FlatRange *fr, AddressSpace *as)
|
static void flat_range_coalesced_io_add(FlatRange *fr, AddressSpace *as)
|
||||||
{
|
{
|
||||||
MemoryRegion *mr = fr->mr;
|
MemoryRegion *mr = fr->mr;
|
||||||
CoalescedMemoryRange *cmr;
|
CoalescedMemoryRange *cmr;
|
||||||
AddrRange tmp;
|
|
||||||
|
|
||||||
if (QTAILQ_EMPTY(&mr->coalesced)) {
|
if (QTAILQ_EMPTY(&mr->coalesced)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fr->has_coalesced_range++) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
|
QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
|
||||||
tmp = addrrange_shift(cmr->addr,
|
flat_range_coalesced_io_notify(fr, as, cmr, true);
|
||||||
int128_sub(fr->addr.start,
|
|
||||||
int128_make64(fr->offset_in_region)));
|
|
||||||
if (!addrrange_intersects(tmp, fr->addr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tmp = addrrange_intersection(tmp, fr->addr);
|
|
||||||
MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add,
|
|
||||||
int128_get64(tmp.start),
|
|
||||||
int128_get64(tmp.size));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2236,27 +2243,26 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
|
|||||||
qemu_ram_resize(mr->ram_block, newsize, errp);
|
qemu_ram_resize(mr->ram_block, newsize, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
|
/*
|
||||||
|
* Call proper memory listeners about the change on the newly
|
||||||
|
* added/removed CoalescedMemoryRange.
|
||||||
|
*/
|
||||||
|
static void memory_region_update_coalesced_range(MemoryRegion *mr,
|
||||||
|
CoalescedMemoryRange *cmr,
|
||||||
|
bool add)
|
||||||
{
|
{
|
||||||
|
AddressSpace *as;
|
||||||
FlatView *view;
|
FlatView *view;
|
||||||
FlatRange *fr;
|
FlatRange *fr;
|
||||||
|
|
||||||
view = address_space_get_flatview(as);
|
|
||||||
FOR_EACH_FLAT_RANGE(fr, view) {
|
|
||||||
if (fr->mr == mr) {
|
|
||||||
flat_range_coalesced_io_del(fr, as);
|
|
||||||
flat_range_coalesced_io_add(fr, as);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flatview_unref(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void memory_region_update_coalesced_range(MemoryRegion *mr)
|
|
||||||
{
|
|
||||||
AddressSpace *as;
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
|
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
|
||||||
memory_region_update_coalesced_range_as(mr, as);
|
view = address_space_get_flatview(as);
|
||||||
|
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||||
|
if (fr->mr == mr) {
|
||||||
|
flat_range_coalesced_io_notify(fr, as, cmr, add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flatview_unref(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2274,14 +2280,17 @@ void memory_region_add_coalescing(MemoryRegion *mr,
|
|||||||
|
|
||||||
cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
|
cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
|
||||||
QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
|
QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
|
||||||
memory_region_update_coalesced_range(mr);
|
memory_region_update_coalesced_range(mr, cmr, true);
|
||||||
memory_region_set_flush_coalesced(mr);
|
memory_region_set_flush_coalesced(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_region_clear_coalescing(MemoryRegion *mr)
|
void memory_region_clear_coalescing(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
CoalescedMemoryRange *cmr;
|
CoalescedMemoryRange *cmr;
|
||||||
bool updated = false;
|
|
||||||
|
if (QTAILQ_EMPTY(&mr->coalesced)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qemu_flush_coalesced_mmio_buffer();
|
qemu_flush_coalesced_mmio_buffer();
|
||||||
mr->flush_coalesced_mmio = false;
|
mr->flush_coalesced_mmio = false;
|
||||||
@ -2289,12 +2298,8 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
|
|||||||
while (!QTAILQ_EMPTY(&mr->coalesced)) {
|
while (!QTAILQ_EMPTY(&mr->coalesced)) {
|
||||||
cmr = QTAILQ_FIRST(&mr->coalesced);
|
cmr = QTAILQ_FIRST(&mr->coalesced);
|
||||||
QTAILQ_REMOVE(&mr->coalesced, cmr, link);
|
QTAILQ_REMOVE(&mr->coalesced, cmr, link);
|
||||||
|
memory_region_update_coalesced_range(mr, cmr, false);
|
||||||
g_free(cmr);
|
g_free(cmr);
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updated) {
|
|
||||||
memory_region_update_coalesced_range(mr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
qtest.c
9
qtest.c
@ -661,6 +661,15 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
|||||||
qtest_send_prefix(chr);
|
qtest_send_prefix(chr);
|
||||||
qtest_sendf(chr, "OK %"PRIi64"\n",
|
qtest_sendf(chr, "OK %"PRIi64"\n",
|
||||||
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||||
|
} else if (strcmp(words[0], "module_load") == 0) {
|
||||||
|
g_assert(words[1] && words[2]);
|
||||||
|
|
||||||
|
qtest_send_prefix(chr);
|
||||||
|
if (module_load_one(words[1], words[2])) {
|
||||||
|
qtest_sendf(chr, "OK\n");
|
||||||
|
} else {
|
||||||
|
qtest_sendf(chr, "FAIL\n");
|
||||||
|
}
|
||||||
} else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
|
} else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
|
||||||
int64_t ns;
|
int64_t ns;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -702,8 +702,8 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
config = data.compute_config()
|
config = data.compute_config()
|
||||||
for key in sorted(config.keys()):
|
for key in sorted(config.keys()):
|
||||||
if key not in external_vars:
|
if key not in external_vars and config[key]:
|
||||||
print ('CONFIG_%s=%s' % (key, ('y' if config[key] else 'n')))
|
print ('CONFIG_%s=y' % key)
|
||||||
|
|
||||||
deps = open(argv[2], 'w')
|
deps = open(argv[2], 'w')
|
||||||
for fname in data.previously_included:
|
for fname in data.previously_included:
|
||||||
|
@ -149,6 +149,7 @@ check-block-$(call land,$(CONFIG_POSIX),$(CONFIG_SOFTMMU)) += tests/check-block.
|
|||||||
|
|
||||||
check-qtest-generic-y += tests/qmp-test$(EXESUF)
|
check-qtest-generic-y += tests/qmp-test$(EXESUF)
|
||||||
check-qtest-generic-y += tests/qmp-cmd-test$(EXESUF)
|
check-qtest-generic-y += tests/qmp-cmd-test$(EXESUF)
|
||||||
|
check-qtest-generic-$(CONFIG_MODULES) += tests/modules-test$(EXESUF)
|
||||||
|
|
||||||
check-qtest-generic-y += tests/device-introspect-test$(EXESUF)
|
check-qtest-generic-y += tests/device-introspect-test$(EXESUF)
|
||||||
check-qtest-generic-y += tests/cdrom-test$(EXESUF)
|
check-qtest-generic-y += tests/cdrom-test$(EXESUF)
|
||||||
|
@ -811,6 +811,12 @@ bool qtest_get_irq(QTestState *s, int num)
|
|||||||
return s->irq_level[num];
|
return s->irq_level[num];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qtest_module_load(QTestState *s, const char *prefix, const char *libname)
|
||||||
|
{
|
||||||
|
qtest_sendf(s, "module_load %s %s\n", prefix, libname);
|
||||||
|
qtest_rsp(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int64_t qtest_clock_rsp(QTestState *s)
|
static int64_t qtest_clock_rsp(QTestState *s)
|
||||||
{
|
{
|
||||||
gchar **words;
|
gchar **words;
|
||||||
|
@ -262,6 +262,8 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
|||||||
char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
|
char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
|
||||||
GCC_FMT_ATTR(2, 0);
|
GCC_FMT_ATTR(2, 0);
|
||||||
|
|
||||||
|
void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qtest_get_irq:
|
* qtest_get_irq:
|
||||||
* @s: #QTestState instance to operate on.
|
* @s: #QTestState instance to operate on.
|
||||||
|
71
tests/modules-test.c
Normal file
71
tests/modules-test.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "libqtest.h"
|
||||||
|
|
||||||
|
static void test_modules_load(const void *data)
|
||||||
|
{
|
||||||
|
QTestState *qts;
|
||||||
|
const char **args = data;
|
||||||
|
|
||||||
|
qts = qtest_init(NULL);
|
||||||
|
qtest_module_load(qts, args[0], args[1]);
|
||||||
|
qtest_quit(qts);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const char *modules[] = {
|
||||||
|
#ifdef CONFIG_CURL
|
||||||
|
"block-", "curl",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GLUSTERFS
|
||||||
|
"block-", "gluster",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_LIBISCSI
|
||||||
|
"block-", "iscsi",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_LIBNFS
|
||||||
|
"block-", "nfs",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_LIBSSH
|
||||||
|
"block-", "ssh",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_RBD
|
||||||
|
"block-", "rbd",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_AUDIO_ALSA
|
||||||
|
"audio-", "alsa",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_AUDIO_OSS
|
||||||
|
"audio-", "oss",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_AUDIO_PA
|
||||||
|
"audio-", "pa",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_AUDIO_SDL
|
||||||
|
"audio-", "sdl",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_CURSES
|
||||||
|
"ui-", "curses",
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_GTK) && defined(CONFIG_VTE)
|
||||||
|
"ui-", "gtk",
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SDL
|
||||||
|
"ui-", "sdl",
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_SPICE) && defined(CONFIG_GIO)
|
||||||
|
"ui-", "spice-app",
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_test_init(&argc, &argv, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS(modules); i += 2) {
|
||||||
|
char *testname = g_strdup_printf("/module/load/%s", modules[i + 1]);
|
||||||
|
qtest_add_data_func(testname, modules + i, test_modules_load);
|
||||||
|
g_free(testname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_test_run();
|
||||||
|
}
|
@ -156,8 +156,10 @@ out:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void module_load_one(const char *prefix, const char *lib_name)
|
bool module_load_one(const char *prefix, const char *lib_name)
|
||||||
{
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
#ifdef CONFIG_MODULES
|
#ifdef CONFIG_MODULES
|
||||||
char *fname = NULL;
|
char *fname = NULL;
|
||||||
char *exec_dir;
|
char *exec_dir;
|
||||||
@ -170,7 +172,7 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||||||
|
|
||||||
if (!g_module_supported()) {
|
if (!g_module_supported()) {
|
||||||
fprintf(stderr, "Module is not supported by system.\n");
|
fprintf(stderr, "Module is not supported by system.\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loaded_modules) {
|
if (!loaded_modules) {
|
||||||
@ -179,11 +181,10 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||||||
|
|
||||||
module_name = g_strdup_printf("%s%s", prefix, lib_name);
|
module_name = g_strdup_printf("%s%s", prefix, lib_name);
|
||||||
|
|
||||||
if (g_hash_table_lookup(loaded_modules, module_name)) {
|
if (!g_hash_table_add(loaded_modules, module_name)) {
|
||||||
g_free(module_name);
|
g_free(module_name);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
g_hash_table_insert(loaded_modules, module_name, module_name);
|
|
||||||
|
|
||||||
exec_dir = qemu_get_exec_dir();
|
exec_dir = qemu_get_exec_dir();
|
||||||
search_dir = getenv("QEMU_MODULE_DIR");
|
search_dir = getenv("QEMU_MODULE_DIR");
|
||||||
@ -206,13 +207,19 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||||||
fname = NULL;
|
fname = NULL;
|
||||||
/* Try loading until loaded a module file */
|
/* Try loading until loaded a module file */
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
success = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
g_hash_table_remove(loaded_modules, module_name);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < n_dirs; i++) {
|
for (i = 0; i < n_dirs; i++) {
|
||||||
g_free(dirs[i]);
|
g_free(dirs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user