Skip to content

Commit

Permalink
Merge tag 'pull-tcg-20230116' of https://gitlab.com/rth7680/qemu into…
Browse files Browse the repository at this point in the history
… staging

- Reorg cpu_tb_exec around setjmp.
- Use __attribute__((target)) for buffer_is_zero.
- Add perfmap and jitdump for perf support.

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmPFtXgdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+62Af/YLdd77+IO8wcPN1n
# 2esKNlrrYQ2/x40Hede6L4pp+Qz6M810YgNbhMchBS3u8YGIFzmVLaiz5N4nBGTq
# ricOit6Jj2KonlxWaxgma1BW36ydBIwphC20WjrLTVgdNGvxmy4JKbfklTd4oIZ+
# +Kf1VTN1bbt7vfDntd454ck2rhtVZBEvYTynikA3LJ1W7EVN5etDUnrN3VwbaTTK
# 0aY8MbDfGUASyrDzmaRcF5F90K+V2STuEUs1whgOuTBusZ6n3+FSDhW8CuDhsy/l
# rXtPkQba3rtUWfJ1+o7bx3Gg4nbfn/9lxIfGwhQ79ywD9InjqLqu9etwVyhijx+n
# k+tvPw==
# =xFfF
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 16 Jan 2023 20:37:12 GMT
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-tcg-20230116' of https://gitlab.com/rth7680/qemu:
  accel/tcg: Split out cpu_exec_{setjmp,loop}
  util/bufferiszero: Use __attribute__((target)) for avx2/avx512
  tcg: add perfmap and jitdump
  accel/tcg: Add debuginfo support
  linux-user: Clean up when exiting due to a signal

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jan 17, 2023
2 parents 2f8d6a8 + 61710a7 commit 7c9236d
Show file tree
Hide file tree
Showing 19 changed files with 763 additions and 101 deletions.
111 changes: 54 additions & 57 deletions accel/tcg/cpu-exec.c
Expand Up @@ -909,64 +909,10 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,

/* main execution loop */

int cpu_exec(CPUState *cpu)
static int __attribute__((noinline))
cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
{
int ret;
SyncClocks sc = { 0 };

/* replay_interrupt may need current_cpu */
current_cpu = cpu;

if (cpu_handle_halt(cpu)) {
return EXCP_HALTED;
}

rcu_read_lock();

cpu_exec_enter(cpu);

/* Calculate difference between guest clock and host clock.
* This delay includes the delay of the last cycle, so
* what we have to do is sleep until it is 0. As for the
* advance/delay we gain here, we try to fix it next time.
*/
init_delay_params(&sc, cpu);

/* prepare setjmp context for exception handling */
if (sigsetjmp(cpu->jmp_env, 0) != 0) {
#if defined(__clang__)
/*
* Some compilers wrongly smash all local variables after
* siglongjmp (the spec requires that only non-volatile locals
* which are changed between the sigsetjmp and siglongjmp are
* permitted to be trashed). There were bug reports for gcc
* 4.5.0 and clang. The bug is fixed in all versions of gcc
* that we support, but is still unfixed in clang:
* https://bugs.llvm.org/show_bug.cgi?id=21183
*
* Reload an essential local variable here for those compilers.
* Newer versions of gcc would complain about this code (-Wclobbered),
* so we only perform the workaround for clang.
*/
cpu = current_cpu;
#else
/* Non-buggy compilers preserve this; assert the correct value. */
g_assert(cpu == current_cpu);
#endif

#ifndef CONFIG_SOFTMMU
clear_helper_retaddr();
if (have_mmap_lock()) {
mmap_unlock();
}
#endif
if (qemu_mutex_iothread_locked()) {
qemu_mutex_unlock_iothread();
}
qemu_plugin_disable_mem_helpers(cpu);

assert_no_pages_locked();
}

/* if an exception is pending, we execute it here */
while (!cpu_handle_exception(cpu, &ret)) {
Expand Down Expand Up @@ -1033,9 +979,60 @@ int cpu_exec(CPUState *cpu)

/* Try to align the host and virtual clocks
if the guest is in advance */
align_clocks(&sc, cpu);
align_clocks(sc, cpu);
}
}
return ret;
}

static int cpu_exec_setjmp(CPUState *cpu, SyncClocks *sc)
{
/* Prepare setjmp context for exception handling. */
if (unlikely(sigsetjmp(cpu->jmp_env, 0) != 0)) {
/* Non-buggy compilers preserve this; assert the correct value. */
g_assert(cpu == current_cpu);

#ifndef CONFIG_SOFTMMU
clear_helper_retaddr();
if (have_mmap_lock()) {
mmap_unlock();
}
#endif
if (qemu_mutex_iothread_locked()) {
qemu_mutex_unlock_iothread();
}
qemu_plugin_disable_mem_helpers(cpu);

assert_no_pages_locked();
}

return cpu_exec_loop(cpu, sc);
}

int cpu_exec(CPUState *cpu)
{
int ret;
SyncClocks sc = { 0 };

/* replay_interrupt may need current_cpu */
current_cpu = cpu;

if (cpu_handle_halt(cpu)) {
return EXCP_HALTED;
}

rcu_read_lock();
cpu_exec_enter(cpu);

/*
* Calculate difference between guest clock and host clock.
* This delay includes the delay of the last cycle, so
* what we have to do is sleep until it is 0. As for the
* advance/delay we gain here, we try to fix it next time.
*/
init_delay_params(&sc, cpu);

ret = cpu_exec_setjmp(cpu, &sc);

cpu_exec_exit(cpu);
rcu_read_unlock();
Expand Down
96 changes: 96 additions & 0 deletions accel/tcg/debuginfo.c
@@ -0,0 +1,96 @@
/*
* Debug information support.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "qemu/osdep.h"
#include "qemu/lockable.h"

#include <elfutils/libdwfl.h>

#include "debuginfo.h"

static QemuMutex lock;
static Dwfl *dwfl;
static const Dwfl_Callbacks dwfl_callbacks = {
.find_elf = NULL,
.find_debuginfo = dwfl_standard_find_debuginfo,
.section_address = NULL,
.debuginfo_path = NULL,
};

__attribute__((constructor))
static void debuginfo_init(void)
{
qemu_mutex_init(&lock);
}

void debuginfo_report_elf(const char *name, int fd, uint64_t bias)
{
QEMU_LOCK_GUARD(&lock);

if (dwfl) {
dwfl_report_begin_add(dwfl);
} else {
dwfl = dwfl_begin(&dwfl_callbacks);
}

if (dwfl) {
dwfl_report_elf(dwfl, name, name, fd, bias, true);
dwfl_report_end(dwfl, NULL, NULL);
}
}

void debuginfo_lock(void)
{
qemu_mutex_lock(&lock);
}

void debuginfo_query(struct debuginfo_query *q, size_t n)
{
const char *symbol, *file;
Dwfl_Module *dwfl_module;
Dwfl_Line *dwfl_line;
GElf_Off dwfl_offset;
GElf_Sym dwfl_sym;
size_t i;
int line;

if (!dwfl) {
return;
}

for (i = 0; i < n; i++) {
dwfl_module = dwfl_addrmodule(dwfl, q[i].address);
if (!dwfl_module) {
continue;
}

if (q[i].flags & DEBUGINFO_SYMBOL) {
symbol = dwfl_module_addrinfo(dwfl_module, q[i].address,
&dwfl_offset, &dwfl_sym,
NULL, NULL, NULL);
if (symbol) {
q[i].symbol = symbol;
q[i].offset = dwfl_offset;
}
}

if (q[i].flags & DEBUGINFO_LINE) {
dwfl_line = dwfl_module_getsrc(dwfl_module, q[i].address);
if (dwfl_line) {
file = dwfl_lineinfo(dwfl_line, NULL, &line, 0, NULL, NULL);
if (file) {
q[i].file = file;
q[i].line = line;
}
}
}
}
}

void debuginfo_unlock(void)
{
qemu_mutex_unlock(&lock);
}
77 changes: 77 additions & 0 deletions accel/tcg/debuginfo.h
@@ -0,0 +1,77 @@
/*
* Debug information support.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef ACCEL_TCG_DEBUGINFO_H
#define ACCEL_TCG_DEBUGINFO_H

/*
* Debuginfo describing a certain address.
*/
struct debuginfo_query {
uint64_t address; /* Input: address. */
int flags; /* Input: debuginfo subset. */
const char *symbol; /* Symbol that the address is part of. */
uint64_t offset; /* Offset from the symbol. */
const char *file; /* Source file associated with the address. */
int line; /* Line number in the source file. */
};

/*
* Debuginfo subsets.
*/
#define DEBUGINFO_SYMBOL BIT(1)
#define DEBUGINFO_LINE BIT(2)

#if defined(CONFIG_TCG) && defined(CONFIG_LIBDW)
/*
* Load debuginfo for the specified guest ELF image.
* Return true on success, false on failure.
*/
void debuginfo_report_elf(const char *name, int fd, uint64_t bias);

/*
* Take the debuginfo lock.
*/
void debuginfo_lock(void);

/*
* Fill each on N Qs with the debuginfo about Q->ADDRESS as specified by
* Q->FLAGS:
*
* - DEBUGINFO_SYMBOL: update Q->SYMBOL and Q->OFFSET. If symbol debuginfo is
* missing, then leave them as is.
* - DEBUINFO_LINE: update Q->FILE and Q->LINE. If line debuginfo is missing,
* then leave them as is.
*
* This function must be called under the debuginfo lock. The results can be
* accessed only until the debuginfo lock is released.
*/
void debuginfo_query(struct debuginfo_query *q, size_t n);

/*
* Release the debuginfo lock.
*/
void debuginfo_unlock(void);
#else
static inline void debuginfo_report_elf(const char *image_name, int image_fd,
uint64_t load_bias)
{
}

static inline void debuginfo_lock(void)
{
}

static inline void debuginfo_query(struct debuginfo_query *q, size_t n)
{
}

static inline void debuginfo_unlock(void)
{
}
#endif

#endif
2 changes: 2 additions & 0 deletions accel/tcg/meson.build
Expand Up @@ -12,6 +12,8 @@ tcg_ss.add(files(
tcg_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
tcg_ss.add(when: 'CONFIG_SOFTMMU', if_false: files('user-exec-stub.c'))
tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c')])
tcg_ss.add(when: libdw, if_true: files('debuginfo.c'))
tcg_ss.add(when: 'CONFIG_LINUX', if_true: files('perf.c'))
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)

specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files(
Expand Down

0 comments on commit 7c9236d

Please sign in to comment.