Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-tcg-p…
Browse files Browse the repository at this point in the history
…lugins-150520-2' into staging

Various testing, tcg and plugin updates

  - fix bug in gdbstub tests that leave hanging QEMUs
  - tweak s390x travis test
  - re-factor guest_base handling
  - support "notes" in disassembler output
  - include guest address notes in out_asm
  - cleanup plugin headers and and constify hwaddr
  - updates MAINTAINERS for cpu-common.c

# gpg: Signature made Fri 15 May 2020 15:40:40 BST
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* remotes/stsquad/tags/pull-testing-tcg-plugins-150520-2:
  MAINTAINERS: update the orphaned cpus-common.c file
  qemu/qemu-plugin: Make qemu_plugin_hwaddr_is_io() hwaddr argument const
  qemu/plugin: Move !CONFIG_PLUGIN stubs altogether
  qemu/plugin: Trivial code movement
  translate-all: include guest address in out_asm output
  disas: add optional note support to cap_disas
  disas: include an optional note for the start of disassembly
  accel/tcg: don't disable exec_tb trace events
  accel/tcg: Relax va restrictions on 64-bit guests
  exec/cpu-all: Use bool for have_guest_base
  linux-user: completely re-write init_guest_space
  travis.yml: Improve the --disable-tcg test on s390x
  tests/guest-debug: catch hanging guests

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed May 15, 2020
2 parents 2478b8e + adf1cfb commit 6670619
Show file tree
Hide file tree
Showing 19 changed files with 424 additions and 392 deletions.
18 changes: 4 additions & 14 deletions .travis.yml
Expand Up @@ -502,9 +502,10 @@ jobs:
$(exit $BUILD_RC);
fi
- name: "[s390x] GCC check (KVM)"
- name: "[s390x] Clang (disable-tcg)"
arch: s390x
dist: bionic
compiler: clang
addons:
apt_packages:
- libaio-dev
Expand All @@ -528,21 +529,10 @@ jobs:
- libusb-1.0-0-dev
- libvdeplug-dev
- libvte-2.91-dev
# Tests dependencies
- genisoimage
env:
- TEST_CMD="make check-unit"
- CONFIG="--disable-containers --disable-tcg --enable-kvm --disable-tools"
script:
- ( cd ${SRC_DIR} ; git submodule update --init roms/SLOF )
- BUILD_RC=0 && make -j${JOBS} || BUILD_RC=$?
- |
if [ "$BUILD_RC" -eq 0 ] ; then
mv pc-bios/s390-ccw/*.img pc-bios/ ;
${TEST_CMD} ;
else
$(exit $BUILD_RC);
fi
- CONFIG="--disable-containers --disable-tcg --enable-kvm
--disable-tools --host-cc=clang --cxx=clang++"

# Release builds
# The make-release script expect a QEMU version, so our tag must start with a 'v'.
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Expand Up @@ -115,6 +115,7 @@ M: Richard Henderson <rth@twiddle.net>
R: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: cpus.c
F: cpus-common.c
F: exec.c
F: accel/tcg/
F: accel/stubs/tcg-stub.c
Expand Down
8 changes: 4 additions & 4 deletions accel/tcg/trace-events
@@ -1,10 +1,10 @@
# See docs/devel/tracing.txt for syntax documentation.

# TCG related tracing (mostly disabled by default)
# TCG related tracing
# cpu-exec.c
disable exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
disable exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
disable exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=0x%x"
exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=0x%x"

# translate-all.c
translate_block(void *tb, uintptr_t pc, uint8_t *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
54 changes: 42 additions & 12 deletions accel/tcg/translate-all.c
Expand Up @@ -173,16 +173,21 @@ struct page_collection {
#define TB_FOR_EACH_JMP(head_tb, tb, n) \
TB_FOR_EACH_TAGGED((head_tb)->jmp_list_head, tb, n, jmp_list_next)

/* In system mode we want L1_MAP to be based on ram offsets,
while in user mode we want it to be based on virtual addresses. */
/*
* In system mode we want L1_MAP to be based on ram offsets,
* while in user mode we want it to be based on virtual addresses.
*
* TODO: For user mode, see the caveat re host vs guest virtual
* address spaces near GUEST_ADDR_MAX.
*/
#if !defined(CONFIG_USER_ONLY)
#if HOST_LONG_BITS < TARGET_PHYS_ADDR_SPACE_BITS
# define L1_MAP_ADDR_SPACE_BITS HOST_LONG_BITS
#else
# define L1_MAP_ADDR_SPACE_BITS TARGET_PHYS_ADDR_SPACE_BITS
#endif
#else
# define L1_MAP_ADDR_SPACE_BITS TARGET_VIRT_ADDR_SPACE_BITS
# define L1_MAP_ADDR_SPACE_BITS MIN(HOST_LONG_BITS, TARGET_ABI_BITS)
#endif

/* Size of the L2 (and L3, etc) page tables. */
Expand Down Expand Up @@ -1789,14 +1794,43 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
qemu_log_in_addr_range(tb->pc)) {
FILE *logfile = qemu_log_lock();
int code_size, data_size = 0;
g_autoptr(GString) note = g_string_new("[tb header & initial instruction]");
size_t chunk_start = 0;
int insn = 0;
qemu_log("OUT: [size=%d]\n", gen_code_size);
if (tcg_ctx->data_gen_ptr) {
size_t code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr;
size_t data_size = gen_code_size - code_size;
size_t i;
code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr;
data_size = gen_code_size - code_size;
} else {
code_size = gen_code_size;
}

/* Dump header and the first instruction */
chunk_start = tcg_ctx->gen_insn_end_off[insn];
log_disas(tb->tc.ptr, chunk_start, note->str);

log_disas(tb->tc.ptr, code_size);
/*
* Dump each instruction chunk, wrapping up empty chunks into
* the next instruction. The whole array is offset so the
* first entry is the beginning of the 2nd instruction.
*/
while (insn <= tb->icount && chunk_start < code_size) {
size_t chunk_end = tcg_ctx->gen_insn_end_off[insn];
if (chunk_end > chunk_start) {
g_string_printf(note, "[guest addr: " TARGET_FMT_lx "]",
tcg_ctx->gen_insn_data[insn][0]);
log_disas(tb->tc.ptr + chunk_start, chunk_end - chunk_start,
note->str);
chunk_start = chunk_end;
}
insn++;
}

/* Finally dump any data we may have after the block */
if (data_size) {
int i;
qemu_log(" data: [size=%d]\n", data_size);
for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
if (sizeof(tcg_target_ulong) == 8) {
qemu_log("0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
Expand All @@ -1808,8 +1842,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
*(uint32_t *)(tcg_ctx->data_gen_ptr + i));
}
}
} else {
log_disas(tb->tc.ptr, gen_code_size);
}
qemu_log("\n");
qemu_log_flush();
Expand Down Expand Up @@ -2497,9 +2529,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
/* This function should never be called with addresses outside the
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
assert(end <= ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif
assert(end - 1 <= GUEST_ADDR_MAX);
assert(start < end);
assert_memory_lock();

Expand Down
4 changes: 2 additions & 2 deletions bsd-user/main.c
Expand Up @@ -42,7 +42,7 @@
int singlestep;
unsigned long mmap_min_addr;
unsigned long guest_base;
int have_guest_base;
bool have_guest_base;
unsigned long reserved_va;

static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
Expand Down Expand Up @@ -828,7 +828,7 @@ int main(int argc, char **argv)
}
} else if (!strcmp(r, "B")) {
guest_base = strtol(argv[optind++], NULL, 0);
have_guest_base = 1;
have_guest_base = true;
} else if (!strcmp(r, "drop-ld-preload")) {
(void) envlist_unsetenv(envlist, "LD_PRELOAD");
} else if (!strcmp(r, "bsd")) {
Expand Down
37 changes: 25 additions & 12 deletions disas.c
Expand Up @@ -260,7 +260,8 @@ static void cap_dump_insn_units(disassemble_info *info, cs_insn *insn,
}
}

static void cap_dump_insn(disassemble_info *info, cs_insn *insn)
static void cap_dump_insn(disassemble_info *info, cs_insn *insn,
const char *note)
{
fprintf_function print = info->fprintf_func;
int i, n, split;
Expand All @@ -281,7 +282,11 @@ static void cap_dump_insn(disassemble_info *info, cs_insn *insn)
}

/* Print the actual instruction. */
print(info->stream, " %-8s %s\n", insn->mnemonic, insn->op_str);
print(info->stream, " %-8s %s", insn->mnemonic, insn->op_str);
if (note) {
print(info->stream, "\t\t%s", note);
}
print(info->stream, "\n");

/* Dump any remaining part of the insn on subsequent lines. */
for (i = split; i < n; i += split) {
Expand Down Expand Up @@ -313,7 +318,7 @@ static bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size)
size -= tsize;

while (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
cap_dump_insn(info, insn);
cap_dump_insn(info, insn, NULL);
}

/* If the target memory is not consumed, go back for more... */
Expand Down Expand Up @@ -342,7 +347,8 @@ static bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size)
}

/* Disassemble SIZE bytes at CODE for the host. */
static bool cap_disas_host(disassemble_info *info, void *code, size_t size)
static bool cap_disas_host(disassemble_info *info, void *code, size_t size,
const char *note)
{
csh handle;
const uint8_t *cbuf;
Expand All @@ -358,7 +364,8 @@ static bool cap_disas_host(disassemble_info *info, void *code, size_t size)
pc = (uintptr_t)code;

while (cs_disasm_iter(handle, &cbuf, &size, &pc, insn)) {
cap_dump_insn(info, insn);
cap_dump_insn(info, insn, note);
note = NULL;
}
if (size != 0) {
(*info->fprintf_func)(info->stream,
Expand Down Expand Up @@ -402,7 +409,7 @@ static bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
csize += tsize;

if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
cap_dump_insn(info, insn);
cap_dump_insn(info, insn, NULL);
if (--count <= 0) {
break;
}
Expand All @@ -416,7 +423,7 @@ static bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
#endif /* !CONFIG_USER_ONLY */
#else
# define cap_disas_target(i, p, s) false
# define cap_disas_host(i, p, s) false
# define cap_disas_host(i, p, s, n) false
# define cap_disas_monitor(i, p, c) false
# define cap_disas_plugin(i, p, c) false
#endif /* CONFIG_CAPSTONE */
Expand Down Expand Up @@ -586,7 +593,7 @@ char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size)
}

/* Disassemble this for me please... (debugging). */
void disas(FILE *out, void *code, unsigned long size)
void disas(FILE *out, void *code, unsigned long size, const char *note)
{
uintptr_t pc;
int count;
Expand Down Expand Up @@ -664,7 +671,7 @@ void disas(FILE *out, void *code, unsigned long size)
print_insn = print_insn_hppa;
#endif

if (s.info.cap_arch >= 0 && cap_disas_host(&s.info, code, size)) {
if (s.info.cap_arch >= 0 && cap_disas_host(&s.info, code, size, note)) {
return;
}

Expand All @@ -674,10 +681,16 @@ void disas(FILE *out, void *code, unsigned long size)
for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
fprintf(out, "0x%08" PRIxPTR ": ", pc);
count = print_insn(pc, &s.info);
fprintf(out, "\n");
if (count < 0)
break;
if (note) {
fprintf(out, "\t\t%s", note);
note = NULL;
}
fprintf(out, "\n");
if (count < 0) {
break;
}
}

}

/* Look up symbol for debugging purpose. Returns "" if unknown. */
Expand Down
2 changes: 1 addition & 1 deletion include/disas/disas.h
Expand Up @@ -7,7 +7,7 @@
#include "cpu.h"

/* Disassemble this for me please... (debugging). */
void disas(FILE *out, void *code, unsigned long size);
void disas(FILE *out, void *code, unsigned long size, const char *note);
void target_disas(FILE *out, CPUState *cpu, target_ulong code,
target_ulong size);

Expand Down
25 changes: 20 additions & 5 deletions include/exec/cpu-all.h
Expand Up @@ -159,15 +159,30 @@ static inline void tswap64s(uint64_t *s)
* This allows the guest address space to be offset to a convenient location.
*/
extern unsigned long guest_base;
extern int have_guest_base;
extern bool have_guest_base;
extern unsigned long reserved_va;

#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
#define GUEST_ADDR_MAX (~0ul)
/*
* Limit the guest addresses as best we can.
*
* When not using -R reserved_va, we cannot really limit the guest
* to less address space than the host. For 32-bit guests, this
* acts as a sanity check that we're not giving the guest an address
* that it cannot even represent. For 64-bit guests... the address
* might not be what the real kernel would give, but it is at least
* representable in the guest.
*
* TODO: Improve address allocation to avoid this problem, and to
* avoid setting bits at the top of guest addresses that might need
* to be used for tags.
*/
#if MIN(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32
# define GUEST_ADDR_MAX_ UINT32_MAX
#else
#define GUEST_ADDR_MAX (reserved_va ? reserved_va - 1 : \
(1ul << TARGET_VIRT_ADDR_SPACE_BITS) - 1)
# define GUEST_ADDR_MAX_ (~0ul)
#endif
#define GUEST_ADDR_MAX (reserved_va ? reserved_va - 1 : GUEST_ADDR_MAX_)

#else

#include "exec/hwaddr.h"
Expand Down
4 changes: 2 additions & 2 deletions include/exec/log.h
Expand Up @@ -56,13 +56,13 @@ static inline void log_target_disas(CPUState *cpu, target_ulong start,
rcu_read_unlock();
}

static inline void log_disas(void *code, unsigned long size)
static inline void log_disas(void *code, unsigned long size, const char *note)
{
QemuLogFile *logfile;
rcu_read_lock();
logfile = atomic_rcu_read(&qemu_logfile);
if (logfile) {
disas(logfile->fd, code, size);
disas(logfile->fd, code, size, note);
}
rcu_read_unlock();
}
Expand Down

0 comments on commit 6670619

Please sign in to comment.