Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* hot-unplug fixes for ioport
* purge qatomic_mb_read/set from monitor
* build system fixes
* OHCI fix from gitlab
* provide EPYC-Rome CPU model not susceptible to XSAVES erratum

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmRvGpEUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroOa/Af/WS5/tmIlEYgH7UOPERQXNqf7+Jwj
# bA2wgqv3ZoQwcgp5f4EVjfA8ABfpGxLZy6xIdUSbWANb8lDJNuh/nPd/em3rWUAU
# LnJGGdo1vF31gfsVQnlzb7hJi3ur+e2f8JqkRVskDCk3a7YY44OCN42JdKWLrN9u
# CFf2zYqxMqXHjrYrY0Kx2oTkfGDZrfwUlx0vM4dHb8IEoxaplfDd8lJXQzjO4htr
# 3nPBPjQ+h08EeC7mObH4XoJE0omzovR10GkBo8K4q952xGOQ041Y/2YY7JwLfx0D
# na7IanVo+ZAmvTJZoJFSBwNnXkTMHvDH5+Hc45NSTsDBtz0YJhRxPw/z/A==
# =A5Lp
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 25 May 2023 01:21:37 AM PDT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [undefined]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# 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

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
  monitor: do not use mb_read/mb_set
  monitor: extract request dequeuing to a new function
  monitor: introduce qmp_dispatcher_co_wake
  monitor: cleanup fetching of QMP requests
  monitor: cleanup detection of qmp_dispatcher_co shutting down
  monitor: do not use mb_read/mb_set for suspend_cnt
  monitor: add more *_locked() functions
  monitor: allow calling monitor_resume under mon_lock
  monitor: use QEMU_LOCK_GUARD a bit more
  softmmu/ioport.c: make MemoryRegionPortioList owner of portio_list MemoryRegions
  softmmu/ioport.c: QOMify MemoryRegionPortioList
  softmmu/ioport.c: allocate MemoryRegionPortioList ports on the heap
  usb/ohci: Set pad to 0 after frame update
  meson: move -no-pie from linker to compiler
  meson: fix rule for qemu-ga installer
  meson.build: Fix glib -Wno-unused-function workaround
  target/i386: EPYC-Rome model without XSAVES

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed May 25, 2023
2 parents b300c13 + eea7cd3 commit 6ad2c71
Show file tree
Hide file tree
Showing 12 changed files with 214 additions and 127 deletions.
2 changes: 2 additions & 0 deletions hw/usb/hcd-ohci.c
Expand Up @@ -1239,6 +1239,8 @@ static void ohci_frame_boundary(void *opaque)
/* Increment frame number and take care of endianness. */
ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
hcca.frame = cpu_to_le16(ohci->frame_number);
/* When the HC updates frame number, set pad to 0. Ref OHCI Spec 4.4.1*/
hcca.pad = 0;

if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
if (!ohci->done) {
Expand Down
3 changes: 3 additions & 0 deletions include/monitor/monitor.h
Expand Up @@ -40,6 +40,9 @@ void monitor_flush(Monitor *mon);
int monitor_set_cpu(Monitor *mon, int cpu_index);
int monitor_get_cpu_index(Monitor *mon);

int monitor_puts_locked(Monitor *mon, const char *str);
void monitor_flush_locked(Monitor *mon);

void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp);

void monitor_read_command(MonitorHMP *mon, int show_prompt);
Expand Down
21 changes: 15 additions & 6 deletions meson.build
Expand Up @@ -265,12 +265,21 @@ endif

# Meson currently only handles pie as a boolean for now, so if the user
# has explicitly disabled PIE we need to extend our cflags.
#
# -no-pie is supposedly a linker flag that has no effect on the compiler
# command line, but some distros, that didn't quite know what they were
# doing, made local changes to gcc's specs file that turned it into
# a compiler command-line flag.
#
# What about linker flags? For a static build, no PIE is implied by -static
# which we added above (and if it's not because of the same specs patching,
# there's nothing we can do: compilation will fail, report a bug to your
# distro and do not use --disable-pie in the meanwhile). For dynamic linking,
# instead, we can't add -no-pie because it overrides -shared: the linker then
# tries to build an executable instead of a shared library and fails. So
# don't add -no-pie anywhere and cross fingers. :(
if not get_option('b_pie')
qemu_common_flags += cc.get_supported_arguments('-fno-pie')
if not get_option('prefer_static')
# No PIE is implied by -static which we added above.
qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
endif
qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
endif

if not get_option('stack_protector').disabled()
Expand Down Expand Up @@ -780,7 +789,7 @@ if not cc.compiles('''
g_free(f);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Werror'])
int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Wunused-function', '-Werror'])
glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
endif
glib = declare_dependency(dependencies: [glib_pc, gmodule],
Expand Down
35 changes: 16 additions & 19 deletions monitor/hmp.c
Expand Up @@ -1401,45 +1401,42 @@ static void monitor_read(void *opaque, const uint8_t *buf, int size)
static void monitor_event(void *opaque, QEMUChrEvent event)
{
Monitor *mon = opaque;
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);

switch (event) {
case CHR_EVENT_MUX_IN:
qemu_mutex_lock(&mon->mon_lock);
mon->mux_out = 0;
qemu_mutex_unlock(&mon->mon_lock);
if (mon->reset_seen) {
readline_restart(hmp_mon->rs);
if (mon->mux_out) {
mon->mux_out = 0;
monitor_resume(mon);
monitor_flush(mon);
} else {
qatomic_mb_set(&mon->suspend_cnt, 0);
}
qemu_mutex_unlock(&mon->mon_lock);
break;

case CHR_EVENT_MUX_OUT:
if (mon->reset_seen) {
if (qatomic_mb_read(&mon->suspend_cnt) == 0) {
monitor_printf(mon, "\n");
qemu_mutex_lock(&mon->mon_lock);
if (!mon->mux_out) {
if (mon->reset_seen && !mon->suspend_cnt) {
monitor_puts_locked(mon, "\n");
} else {
monitor_flush_locked(mon);
}
monitor_flush(mon);
monitor_suspend(mon);
} else {
qatomic_inc(&mon->suspend_cnt);
mon->mux_out = 1;
}
qemu_mutex_lock(&mon->mon_lock);
mon->mux_out = 1;
qemu_mutex_unlock(&mon->mon_lock);
break;

case CHR_EVENT_OPENED:
monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
"information\n", QEMU_VERSION);
qemu_mutex_lock(&mon->mon_lock);
mon->reset_seen = 1;
if (!mon->mux_out) {
readline_restart(hmp_mon->rs);
readline_show_prompt(hmp_mon->rs);
/* Suspend-resume forces the prompt to be printed. */
monitor_suspend(mon);
monitor_resume(mon);
}
mon->reset_seen = 1;
qemu_mutex_unlock(&mon->mon_lock);
mon_refcount++;
break;

Expand Down
5 changes: 2 additions & 3 deletions monitor/monitor-internal.h
Expand Up @@ -94,7 +94,6 @@ typedef struct HMPCommand {

struct Monitor {
CharBackend chr;
int reset_seen;
int suspend_cnt; /* Needs to be accessed atomically */
bool is_qmp;
bool skip_flush;
Expand All @@ -115,8 +114,8 @@ struct Monitor {
QLIST_HEAD(, mon_fd_t) fds;
GString *outbuf;
guint out_watch;
/* Read under either BQL or mon_lock, written with BQL+mon_lock. */
int mux_out;
int reset_seen;
};

struct MonitorHMP {
Expand Down Expand Up @@ -166,7 +165,6 @@ typedef QTAILQ_HEAD(MonitorList, Monitor) MonitorList;
extern IOThread *mon_iothread;
extern Coroutine *qmp_dispatcher_co;
extern bool qmp_dispatcher_co_shutdown;
extern bool qmp_dispatcher_co_busy;
extern QmpCommandList qmp_commands, qmp_cap_negotiation_commands;
extern QemuMutex monitor_lock;
extern MonitorList mon_list;
Expand All @@ -184,6 +182,7 @@ void monitor_fdsets_cleanup(void);
void qmp_send_response(MonitorQMP *mon, const QDict *rsp);
void monitor_data_destroy_qmp(MonitorQMP *mon);
void coroutine_fn monitor_qmp_dispatcher_co(void *data);
void qmp_dispatcher_co_wake(void);

int get_monitor_def(Monitor *mon, int64_t *pval, const char *name);
void handle_hmp_command(MonitorHMP *mon, const char *cmdline);
Expand Down
72 changes: 29 additions & 43 deletions monitor/monitor.c
Expand Up @@ -56,29 +56,11 @@ IOThread *mon_iothread;
/* Coroutine to dispatch the requests received from I/O thread */
Coroutine *qmp_dispatcher_co;

/* Set to true when the dispatcher coroutine should terminate */
bool qmp_dispatcher_co_shutdown;

/*
* qmp_dispatcher_co_busy is used for synchronisation between the
* monitor thread and the main thread to ensure that the dispatcher
* coroutine never gets scheduled a second time when it's already
* scheduled (scheduling the same coroutine twice is forbidden).
*
* It is true if the coroutine is active and processing requests.
* Additional requests may then be pushed onto mon->qmp_requests,
* and @qmp_dispatcher_co_shutdown may be set without further ado.
* @qmp_dispatcher_co_busy must not be woken up in this case.
*
* If false, you also have to set @qmp_dispatcher_co_busy to true and
* wake up @qmp_dispatcher_co after pushing the new requests.
*
* The coroutine will automatically change this variable back to false
* before it yields. Nobody else may set the variable to false.
*
* Access must be atomic for thread safety.
* Set to true when the dispatcher coroutine should terminate. Protected
* by monitor_lock.
*/
bool qmp_dispatcher_co_busy;
bool qmp_dispatcher_co_shutdown;

/*
* Protects mon_list, monitor_qapi_event_state, coroutine_mon,
Expand Down Expand Up @@ -154,22 +136,19 @@ static inline bool monitor_is_hmp_non_interactive(const Monitor *mon)
return !monitor_uses_readline(container_of(mon, MonitorHMP, common));
}

static void monitor_flush_locked(Monitor *mon);

static gboolean monitor_unblocked(void *do_not_use, GIOCondition cond,
void *opaque)
{
Monitor *mon = opaque;

qemu_mutex_lock(&mon->mon_lock);
QEMU_LOCK_GUARD(&mon->mon_lock);
mon->out_watch = 0;
monitor_flush_locked(mon);
qemu_mutex_unlock(&mon->mon_lock);
return FALSE;
}

/* Caller must hold mon->mon_lock */
static void monitor_flush_locked(Monitor *mon)
void monitor_flush_locked(Monitor *mon)
{
int rc;
size_t len;
Expand Down Expand Up @@ -203,18 +182,16 @@ static void monitor_flush_locked(Monitor *mon)

void monitor_flush(Monitor *mon)
{
qemu_mutex_lock(&mon->mon_lock);
QEMU_LOCK_GUARD(&mon->mon_lock);
monitor_flush_locked(mon);
qemu_mutex_unlock(&mon->mon_lock);
}

/* flush at every end of line */
int monitor_puts(Monitor *mon, const char *str)
int monitor_puts_locked(Monitor *mon, const char *str)
{
int i;
char c;

qemu_mutex_lock(&mon->mon_lock);
for (i = 0; str[i]; i++) {
c = str[i];
if (c == '\n') {
Expand All @@ -225,11 +202,16 @@ int monitor_puts(Monitor *mon, const char *str)
monitor_flush_locked(mon);
}
}
qemu_mutex_unlock(&mon->mon_lock);

return i;
}

int monitor_puts(Monitor *mon, const char *str)
{
QEMU_LOCK_GUARD(&mon->mon_lock);
return monitor_puts_locked(mon, str);
}

int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
{
char *buf;
Expand Down Expand Up @@ -569,6 +551,17 @@ static void monitor_accept_input(void *opaque)
{
Monitor *mon = opaque;

qemu_mutex_lock(&mon->mon_lock);
if (!monitor_is_qmp(mon) && mon->reset_seen) {
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
assert(hmp_mon->rs);
readline_restart(hmp_mon->rs);
qemu_mutex_unlock(&mon->mon_lock);
readline_show_prompt(hmp_mon->rs);
} else {
qemu_mutex_unlock(&mon->mon_lock);
}

qemu_chr_fe_accept_input(&mon->chr);
}

Expand All @@ -587,12 +580,6 @@ void monitor_resume(Monitor *mon)
ctx = qemu_get_aio_context();
}

if (!monitor_is_qmp(mon)) {
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
assert(hmp_mon->rs);
readline_show_prompt(hmp_mon->rs);
}

aio_bh_schedule_oneshot(ctx, monitor_accept_input, mon);
}

Expand All @@ -603,7 +590,7 @@ int monitor_can_read(void *opaque)
{
Monitor *mon = opaque;

return !qatomic_mb_read(&mon->suspend_cnt);
return !qatomic_read(&mon->suspend_cnt);
}

void monitor_list_append(Monitor *mon)
Expand Down Expand Up @@ -674,14 +661,14 @@ void monitor_cleanup(void)
* we'll just leave them in the queue without sending a response
* and monitor_data_destroy() will free them.
*/
qmp_dispatcher_co_shutdown = true;
if (!qatomic_xchg(&qmp_dispatcher_co_busy, true)) {
aio_co_wake(qmp_dispatcher_co);
WITH_QEMU_LOCK_GUARD(&monitor_lock) {
qmp_dispatcher_co_shutdown = true;
}
qmp_dispatcher_co_wake();

AIO_WAIT_WHILE_UNLOCKED(NULL,
(aio_poll(iohandler_get_aio_context(), false),
qatomic_mb_read(&qmp_dispatcher_co_busy)));
qatomic_read(&qmp_dispatcher_co)));

/*
* We need to explicitly stop the I/O thread (but not destroy it),
Expand Down Expand Up @@ -732,7 +719,6 @@ void monitor_init_globals(void)
* rid of those assumptions.
*/
qmp_dispatcher_co = qemu_coroutine_create(monitor_qmp_dispatcher_co, NULL);
qatomic_mb_set(&qmp_dispatcher_co_busy, true);
aio_co_schedule(iohandler_get_aio_context(), qmp_dispatcher_co);
}

Expand Down

0 comments on commit 6ad2c71

Please sign in to comment.