diff options
| -rw-r--r-- | .travis.yml | 2 | ||||
| -rw-r--r-- | MAINTAINERS | 2 | ||||
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | VERSION | 2 | ||||
| -rwxr-xr-x | configure | 17 | ||||
| -rw-r--r-- | contrib/ivshmem-server/ivshmem-server.c | 6 | ||||
| -rw-r--r-- | contrib/ivshmem-server/main.c | 5 | ||||
| -rw-r--r-- | hw/core/numa.c | 2 | ||||
| -rw-r--r-- | include/qemu/qemu-plugin.h | 19 | ||||
| -rw-r--r-- | linux-user/syscall.c | 9 | ||||
| -rw-r--r-- | plugins/loader.c | 21 | ||||
| -rw-r--r-- | plugins/plugin.h | 2 | ||||
| -rw-r--r-- | qom/object.c | 10 | ||||
| -rw-r--r-- | target/microblaze/translate.c | 77 | ||||
| -rw-r--r-- | tests/Makefile.include | 2 | ||||
| -rw-r--r-- | tests/cpu-plug-test.c | 2 | ||||
| -rw-r--r-- | tests/libqtest.c | 1 | ||||
| -rw-r--r-- | tests/migration-test.c | 9 | ||||
| -rw-r--r-- | tests/plugin/bb.c | 2 | ||||
| -rw-r--r-- | tests/plugin/empty.c | 2 | ||||
| -rw-r--r-- | tests/plugin/hotblocks.c | 2 | ||||
| -rw-r--r-- | tests/plugin/hotpages.c | 2 | ||||
| -rw-r--r-- | tests/plugin/howvec.c | 2 | ||||
| -rw-r--r-- | tests/plugin/insn.c | 2 | ||||
| -rw-r--r-- | tests/plugin/mem.c | 2 | ||||
| -rwxr-xr-x | tests/vm/basevm.py | 29 | ||||
| -rwxr-xr-x | tests/vm/netbsd | 188 |
27 files changed, 353 insertions, 70 deletions
diff --git a/.travis.yml b/.travis.yml index 678e33decc..b9a026c8ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -77,7 +77,7 @@ env: - SRC_DIR="." - BUILD_DIR="." - BASE_CONFIG="--disable-docs --disable-tools" - - TEST_CMD="make check -j3 V=1" + - TEST_CMD="make check V=1" # This is broadly a list of "mainline" softmmu targets which have support across the major distros - MAIN_SOFTMMU_TARGETS="aarch64-softmmu,arm-softmmu,i386-softmmu,mips-softmmu,mips64-softmmu,ppc64-softmmu,riscv64-softmmu,s390x-softmmu,x86_64-softmmu" - CCACHE_SLOPPINESS="include_file_ctime,include_file_mtime" diff --git a/MAINTAINERS b/MAINTAINERS index 363e72a467..ff8d0d29f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2143,13 +2143,11 @@ F: include/hw/registerfields.h SLIRP M: Samuel Thibault <samuel.thibault@ens-lyon.org> -M: Jan Kiszka <jan.kiszka@siemens.com> S: Maintained F: slirp/ F: net/slirp.c F: include/net/slirp.h T: git https://people.debian.org/~sthibault/qemu.git slirp -T: git git://git.kiszka.org/qemu.git queues/slirp Stubs M: Paolo Bonzini <pbonzini@redhat.com> diff --git a/Makefile b/Makefile index aa9d1a42aa..b437a346d7 100644 --- a/Makefile +++ b/Makefile @@ -480,7 +480,9 @@ $(SOFTMMU_ALL_RULES): $(chardev-obj-y) $(SOFTMMU_ALL_RULES): $(crypto-obj-y) $(SOFTMMU_ALL_RULES): $(io-obj-y) $(SOFTMMU_ALL_RULES): config-all-devices.mak +ifdef DECOMPRESS_EDK2_BLOBS $(SOFTMMU_ALL_RULES): $(edk2-decompressed) +endif .PHONY: $(TARGET_DIRS_RULES) # The $(TARGET_DIRS_RULES) are of the form SUBDIR/GOAL, so that @@ -771,7 +773,7 @@ de-ch es fo fr-ca hu ja mk pt sl tr \ bepo cz ifdef INSTALL_BLOBS -BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ +BLOBS=bios.bin bios-256k.bin bios-microvm.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-virtio.bin \ vgabios-ramfb.bin vgabios-bochs-display.bin vgabios-ati.bin \ ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin QEMU,cgthree.bin \ diff --git a/VERSION b/VERSION index b9d9a6438b..cfcbdd75dd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.90 +4.1.91 diff --git a/configure b/configure index efe165edf9..6099be1d84 100755 --- a/configure +++ b/configure @@ -427,6 +427,7 @@ softmmu="yes" linux_user="no" bsd_user="no" blobs="yes" +edk2_blobs="no" pkgversion="" pie="" qom_cast_debug="yes" @@ -2146,6 +2147,18 @@ case " $target_list " in ;; esac +for target in $target_list; do + case "$target" in + arm-softmmu | aarch64-softmmu | i386-softmmu | x86_64-softmmu) + edk2_blobs="yes" + ;; + esac +done +# The EDK2 binaries are compressed with bzip2 +if test "$edk2_blobs" = "yes" && ! has bzip2; then + error_exit "The bzip2 program is required for building QEMU" +fi + feature_not_found() { feature=$1 remedy=$2 @@ -7526,6 +7539,10 @@ if test "$libudev" != "no"; then echo "LIBUDEV_LIBS=$libudev_libs" >> $config_host_mak fi +if test "$edk2_blobs" = "yes" ; then + echo "DECOMPRESS_EDK2_BLOBS=y" >> $config_host_mak +fi + # use included Linux headers if test "$linux" = "yes" ; then mkdir -p linux-headers diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c index 77f97b209c..88daee812d 100644 --- a/contrib/ivshmem-server/ivshmem-server.c +++ b/contrib/ivshmem-server/ivshmem-server.c @@ -353,6 +353,9 @@ ivshmem_server_start(IvshmemServer *server) err_close_sock: close(sock_fd); err_close_shm: + if (server->use_shm_open) { + shm_unlink(server->shm_path); + } close(shm_fd); return -1; } @@ -370,6 +373,9 @@ ivshmem_server_close(IvshmemServer *server) } unlink(server->unix_sock_path); + if (server->use_shm_open) { + shm_unlink(server->shm_path); + } close(server->sock_fd); close(server->shm_fd); server->sock_fd = -1; diff --git a/contrib/ivshmem-server/main.c b/contrib/ivshmem-server/main.c index 197c79c57e..e4cd35f74c 100644 --- a/contrib/ivshmem-server/main.c +++ b/contrib/ivshmem-server/main.c @@ -223,8 +223,9 @@ main(int argc, char *argv[]) sa_quit.sa_handler = ivshmem_server_quit_cb; sa_quit.sa_flags = 0; if (sigemptyset(&sa_quit.sa_mask) == -1 || - sigaction(SIGTERM, &sa_quit, 0) == -1) { - perror("failed to add SIGTERM handler; sigaction"); + sigaction(SIGTERM, &sa_quit, 0) == -1 || + sigaction(SIGINT, &sa_quit, 0) == -1) { + perror("failed to add signal handler; sigaction"); goto err; } diff --git a/hw/core/numa.c b/hw/core/numa.c index 038c96d4ab..e3332a984f 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -503,7 +503,7 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner, warn_report("falling back to regular RAM allocation"); error_printf("This is deprecated. Make sure that -mem-path " " specified path has sufficient resources to allocate" - " -m specified RAM amount"); + " -m specified RAM amount\n"); /* Legacy behavior: if allocation failed, fall back to * regular RAM allocation. */ diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index a00a7deb46..5502e112c8 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -38,9 +38,28 @@ typedef uint64_t qemu_plugin_id_t; +/* + * Versioning plugins: + * + * The plugin API will pass a minimum and current API version that + * QEMU currently supports. The minimum API will be incremented if an + * API needs to be deprecated. + * + * The plugins export the API they were built against by exposing the + * symbol qemu_plugin_version which can be checked. + */ + +extern QEMU_PLUGIN_EXPORT int qemu_plugin_version; + +#define QEMU_PLUGIN_VERSION 0 + typedef struct { /* string describing architecture */ const char *target_name; + struct { + int min; + int cur; + } version; /* is this a full system emulation? */ bool system_emulation; union { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ab9d933e53..ce399a55f0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2632,6 +2632,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, default: goto unimplemented; } + break; #endif /* SOL_NETLINK */ default: unimplemented: @@ -7763,10 +7764,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_stime /* not on alpha */ case TARGET_NR_stime: { - time_t host_time; - if (get_user_sal(host_time, arg1)) + struct timespec ts; + ts.tv_nsec = 0; + if (get_user_sal(ts.tv_sec, arg1)) { return -TARGET_EFAULT; - return get_errno(stime(&host_time)); + } + return get_errno(clock_settime(CLOCK_REALTIME, &ts)); } #endif #ifdef TARGET_NR_alarm /* not on alpha */ diff --git a/plugins/loader.c b/plugins/loader.c index ce724ed583..15fc7e5515 100644 --- a/plugins/loader.c +++ b/plugins/loader.c @@ -178,6 +178,25 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info) goto err_symbol; } + if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) { + error_report("TCG plugin %s does not declare API version %s", + desc->path, g_module_error()); + goto err_symbol; + } else { + int version = *(int *)sym; + if (version < QEMU_PLUGIN_MIN_VERSION) { + error_report("TCG plugin %s requires API version %d, but " + "this QEMU supports only a minimum version of %d", + desc->path, version, QEMU_PLUGIN_MIN_VERSION); + goto err_symbol; + } else if (version > QEMU_PLUGIN_VERSION) { + error_report("TCG plugin %s requires API version %d, but " + "this QEMU supports only up to version %d", + desc->path, version, QEMU_PLUGIN_VERSION); + goto err_symbol; + } + } + qemu_rec_mutex_lock(&plugin.lock); /* find an unused random id with &ctx as the seed */ @@ -248,6 +267,8 @@ int qemu_plugin_load_list(QemuPluginList *head) g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1); info->target_name = TARGET_NAME; + info->version.min = QEMU_PLUGIN_MIN_VERSION; + info->version.cur = QEMU_PLUGIN_VERSION; #ifndef CONFIG_USER_ONLY MachineState *ms = MACHINE(qdev_get_machine()); info->system_emulation = true; diff --git a/plugins/plugin.h b/plugins/plugin.h index 5482168d79..1aa29dcadd 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -14,6 +14,8 @@ #include <gmodule.h> +#define QEMU_PLUGIN_MIN_VERSION 0 + /* global state */ struct qemu_plugin_state { QTAILQ_HEAD(, qemu_plugin_ctx) ctxs; diff --git a/qom/object.c b/qom/object.c index 6fa9c619fa..d51b57fba1 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1106,9 +1106,8 @@ object_property_add(Object *obj, const char *name, const char *type, } if (object_property_find(obj, name, NULL) != NULL) { - error_setg(errp, "attempt to add duplicate property '%s'" - " to object (type '%s')", name, - object_get_typename(obj)); + error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')", + name, object_get_typename(obj)); return NULL; } @@ -1139,9 +1138,8 @@ object_class_property_add(ObjectClass *klass, ObjectProperty *prop; if (object_class_property_find(klass, name, NULL) != NULL) { - error_setg(errp, "attempt to add duplicate property '%s'" - " to object (type '%s')", name, - object_class_get_name(klass)); + error_setg(errp, "attempt to add duplicate property '%s' to class (type '%s')", + name, object_class_get_name(klass)); return NULL; } diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index 761f535357..bdc7d5326a 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -962,17 +962,7 @@ static void dec_load(DisasContext *dc) switch (size) { case 1: { - /* 00 -> 11 - 01 -> 10 - 10 -> 10 - 11 -> 00 */ - TCGv low = tcg_temp_new(); - - tcg_gen_andi_tl(low, addr, 3); - tcg_gen_sub_tl(low, tcg_const_tl(3), low); - tcg_gen_andi_tl(addr, addr, ~3); - tcg_gen_or_tl(addr, addr, low); - tcg_temp_free(low); + tcg_gen_xori_tl(addr, addr, 3); break; } @@ -1006,9 +996,16 @@ static void dec_load(DisasContext *dc) tcg_gen_qemu_ld_i32(v, addr, mem_index, mop); if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) { + TCGv_i32 t0 = tcg_const_i32(0); + TCGv_i32 treg = tcg_const_i32(dc->rd); + TCGv_i32 tsize = tcg_const_i32(size - 1); + tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc); - gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd), - tcg_const_i32(0), tcg_const_i32(size - 1)); + gen_helper_memalign(cpu_env, addr, treg, t0, tsize); + + tcg_temp_free_i32(t0); + tcg_temp_free_i32(treg); + tcg_temp_free_i32(tsize); } if (ex) { @@ -1095,17 +1092,7 @@ static void dec_store(DisasContext *dc) switch (size) { case 1: { - /* 00 -> 11 - 01 -> 10 - 10 -> 10 - 11 -> 00 */ - TCGv low = tcg_temp_new(); - - tcg_gen_andi_tl(low, addr, 3); - tcg_gen_sub_tl(low, tcg_const_tl(3), low); - tcg_gen_andi_tl(addr, addr, ~3); - tcg_gen_or_tl(addr, addr, low); - tcg_temp_free(low); + tcg_gen_xori_tl(addr, addr, 3); break; } @@ -1124,6 +1111,10 @@ static void dec_store(DisasContext *dc) /* Verify alignment if needed. */ if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) { + TCGv_i32 t1 = tcg_const_i32(1); + TCGv_i32 treg = tcg_const_i32(dc->rd); + TCGv_i32 tsize = tcg_const_i32(size - 1); + tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc); /* FIXME: if the alignment is wrong, we should restore the value * in memory. One possible way to achieve this is to probe @@ -1131,8 +1122,11 @@ static void dec_store(DisasContext *dc) * the alignment checks in between the probe and the mem * access. */ - gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd), - tcg_const_i32(1), tcg_const_i32(size - 1)); + gen_helper_memalign(cpu_env, addr, treg, t1, tsize); + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(treg); + tcg_temp_free_i32(tsize); } if (ex) { @@ -1183,6 +1177,17 @@ static void eval_cond_jmp(DisasContext *dc, TCGv_i64 pc_true, TCGv_i64 pc_false) tcg_temp_free_i64(tmp_zero); } +static void dec_setup_dslot(DisasContext *dc) +{ + TCGv_i32 tmp = tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)); + + dc->delayed_branch = 2; + dc->tb_flags |= D_FLAG; + + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUMBState, bimm)); + tcg_temp_free_i32(tmp); +} + static void dec_bcc(DisasContext *dc) { unsigned int cc; @@ -1194,10 +1199,7 @@ static void dec_bcc(DisasContext *dc) dc->delayed_branch = 1; if (dslot) { - dc->delayed_branch = 2; - dc->tb_flags |= D_FLAG; - tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)), - cpu_env, offsetof(CPUMBState, bimm)); + dec_setup_dslot(dc); } if (dec_alu_op_b_is_small_imm(dc)) { @@ -1256,10 +1258,7 @@ static void dec_br(DisasContext *dc) dc->delayed_branch = 1; if (dslot) { - dc->delayed_branch = 2; - dc->tb_flags |= D_FLAG; - tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)), - cpu_env, offsetof(CPUMBState, bimm)); + dec_setup_dslot(dc); } if (link && dc->rd) tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc); @@ -1361,10 +1360,7 @@ static void dec_rts(DisasContext *dc) return; } - dc->delayed_branch = 2; - dc->tb_flags |= D_FLAG; - tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)), - cpu_env, offsetof(CPUMBState, bimm)); + dec_setup_dslot(dc); if (i_bit) { LOG_DIS("rtid ir=%x\n", dc->ir); @@ -1685,7 +1681,10 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) dc->tb_flags &= ~D_FLAG; /* If it is a direct jump, try direct chaining. */ if (dc->jmp == JMP_INDIRECT) { - eval_cond_jmp(dc, env_btarget, tcg_const_i64(dc->pc)); + TCGv_i64 tmp_pc = tcg_const_i64(dc->pc); + eval_cond_jmp(dc, env_btarget, tmp_pc); + tcg_temp_free_i64(tmp_pc); + dc->is_jmp = DISAS_JUMP; } else if (dc->jmp == JMP_DIRECT) { t_sync_flags(dc); diff --git a/tests/Makefile.include b/tests/Makefile.include index 534ee48743..8566f5f119 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -177,7 +177,9 @@ check-qtest-i386-$(CONFIG_SGA) += tests/boot-serial-test$(EXESUF) check-qtest-i386-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF) check-qtest-i386-y += tests/rtc-test$(EXESUF) check-qtest-i386-$(CONFIG_ISA_IPMI_KCS) += tests/ipmi-kcs-test$(EXESUF) +ifdef CONFIG_LINUX check-qtest-i386-$(CONFIG_ISA_IPMI_BT) += tests/ipmi-bt-test$(EXESUF) +endif check-qtest-i386-y += tests/i440fx-test$(EXESUF) check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) check-qtest-i386-y += tests/device-plug-test$(EXESUF) diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c index 058cef5ac1..30e514bbfb 100644 --- a/tests/cpu-plug-test.c +++ b/tests/cpu-plug-test.c @@ -99,6 +99,7 @@ static void test_plug_with_device_add(gconstpointer data) cpu = qobject_to(QDict, e); if (qdict_haskey(cpu, "qom-path")) { + qobject_unref(e); continue; } @@ -107,6 +108,7 @@ static void test_plug_with_device_add(gconstpointer data) qtest_qmp_device_add_qdict(qts, td->device_model, props); hotplugged++; + qobject_unref(e); } /* make sure that there were hotplugged CPUs */ diff --git a/tests/libqtest.c b/tests/libqtest.c index 3706bccd8d..91e9cb220c 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -1274,6 +1274,7 @@ void qtest_qmp_device_add(QTestState *qts, const char *driver, const char *id, qdict_put_str(args, "id", id); qtest_qmp_device_add_qdict(qts, driver, args); + qobject_unref(args); } static void device_deleted_cb(void *opaque, const char *name, QDict *data) diff --git a/tests/migration-test.c b/tests/migration-test.c index 59f291c654..ac780dffda 100644 --- a/tests/migration-test.c +++ b/tests/migration-test.c @@ -899,8 +899,13 @@ static void wait_for_migration_fail(QTestState *from, bool allow_active) do { status = migrate_query_status(from); - g_assert(!strcmp(status, "setup") || !strcmp(status, "failed") || - (allow_active && !strcmp(status, "active"))); + bool result = !strcmp(status, "setup") || !strcmp(status, "failed") || + (allow_active && !strcmp(status, "active")); + if (!result) { + fprintf(stderr, "%s: unexpected status status=%s allow_active=%d\n", + __func__, status, allow_active); + } + g_assert(result); failed = !strcmp(status, "failed"); g_free(status); } while (!failed); diff --git a/tests/plugin/bb.c b/tests/plugin/bb.c index 45e1de5bd6..f30bea08dc 100644 --- a/tests/plugin/bb.c +++ b/tests/plugin/bb.c @@ -14,6 +14,8 @@ #include <qemu-plugin.h> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + static uint64_t bb_count; static uint64_t insn_count; static bool do_inline; diff --git a/tests/plugin/empty.c b/tests/plugin/empty.c index 3f60f69027..8fa6bacd93 100644 --- a/tests/plugin/empty.c +++ b/tests/plugin/empty.c @@ -13,6 +13,8 @@ #include <qemu-plugin.h> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + /* * Empty TB translation callback. * This allows us to measure the overhead of injecting and then diff --git a/tests/plugin/hotblocks.c b/tests/plugin/hotblocks.c index 1bd183849a..3942a2ca54 100644 --- a/tests/plugin/hotblocks.c +++ b/tests/plugin/hotblocks.c @@ -15,6 +15,8 @@ #include <qemu-plugin.h> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + static bool do_inline; /* Plugins need to take care of their own locking */ diff --git a/tests/plugin/hotpages.c b/tests/plugin/hotpages.c index 77df07a3cc..ecd6c18732 100644 --- a/tests/plugin/hotpages.c +++ b/tests/plugin/hotpages.c @@ -18,6 +18,8 @@ #include <qemu-plugin.h> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) static uint64_t page_size = 4096; diff --git a/tests/plugin/howvec.c b/tests/plugin/howvec.c index 58fa675e34..4ca555e123 100644 --- a/tests/plugin/howvec.c +++ b/tests/plugin/howvec.c @@ -20,6 +20,8 @@ #include <qemu-plugin.h> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) typedef enum { diff --git a/tests/plugin/insn.c b/tests/plugin/insn.c index e5fd07fb64..0a8f5a0000 100644 --- a/tests/plugin/insn.c +++ b/tests/plugin/insn.c @@ -14,6 +14,8 @@ #include <qemu-plugin.h> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + static uint64_t insn_count; static bool do_inline; diff --git a/tests/plugin/mem.c b/tests/plugin/mem.c index d967388989..878abf09d1 100644 --- a/tests/plugin/mem.c +++ b/tests/plugin/mem.c @@ -14,6 +14,8 @@ #include <qemu-plugin.h> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + static uint64_t mem_count; static uint64_t io_count; static bool do_inline; diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 2929de23aa..91a9226026 100755 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -95,19 +95,25 @@ class BaseVM(object): logging.info("KVM not available, not using -enable-kvm") self._data_args = [] - def _download_with_cache(self, url, sha256sum=None): + def _download_with_cache(self, url, sha256sum=None, sha512sum=None): def check_sha256sum(fname): if not sha256sum: return True checksum = subprocess.check_output(["sha256sum", fname]).split()[0] return sha256sum == checksum.decode("utf-8") + def check_sha512sum(fname): + if not sha512sum: + return True + checksum = subprocess.check_output(["sha512sum", fname]).split()[0] + return sha512sum == checksum.decode("utf-8") + cache_dir = os.path.expanduser("~/.cache/qemu-vm/download") if not os.path.exists(cache_dir): os.makedirs(cache_dir) fname = os.path.join(cache_dir, hashlib.sha1(url.encode("utf-8")).hexdigest()) - if os.path.exists(fname) and check_sha256sum(fname): + if os.path.exists(fname) and check_sha256sum(fname) and check_sha512sum(fname): return fname logging.debug("Downloading %s to %s...", url, fname) subprocess.check_call(["wget", "-c", url, "-O", fname + ".download"], @@ -242,6 +248,25 @@ class BaseVM(object): return False return True + def console_consume(self): + vm = self._guest + output = "" + vm.console_socket.setblocking(0) + while True: + try: + chars = vm.console_socket.recv(1) + except: + break + output += chars.decode("latin1") + if "\r" in output or "\n" in output: + lines = re.split("[\r\n]", output) + output = lines.pop() + if self.debug: + self.console_log("\n".join(lines)) + if self.debug: + self.console_log(output) + vm.console_socket.setblocking(1) + def console_send(self, command): vm = self._guest if self.debug: diff --git a/tests/vm/netbsd b/tests/vm/netbsd index 18aa56ae82..611e6cc5b5 100755 --- a/tests/vm/netbsd +++ b/tests/vm/netbsd @@ -2,10 +2,11 @@ # # NetBSD VM image # -# Copyright 2017 Red Hat Inc. +# Copyright 2017-2019 Red Hat Inc. # # Authors: # Fam Zheng <famz@redhat.com> +# Gerd Hoffmann <kraxel@redhat.com> # # This code is licensed under the GPL version 2 or later. See # the COPYING file in the top-level directory. @@ -13,20 +14,54 @@ import os import sys +import time import subprocess import basevm class NetBSDVM(basevm.BaseVM): name = "netbsd" arch = "x86_64" + + link = "https://cdn.netbsd.org/pub/NetBSD/NetBSD-8.1/images/NetBSD-8.1-amd64.iso" + csum = "718f275b7e0879599bdac95630c5e3f2184700032fdb6cdebf3bdd63687898c48ff3f08f57b89f4437a86cdd8ea07c01a39d432dbb37e1e4b008f4985f98da3f" + size = "20G" + pkgs = [ + # tools + "git-base", + "pkgconf", + "xz", + "python37", + + # gnu tools + "bash", + "gmake", + "gsed", + "flex", "bison", + + # libs: crypto + "gnutls", + + # libs: images + "jpeg", + "png", + + # libs: ui + "SDL2", + "gtk3+", + "libxkbcommon", + ] + BUILD_SCRIPT = """ set -e; - rm -rf /var/tmp/qemu-test.* - cd $(mktemp -d /var/tmp/qemu-test.XXXXXX); + rm -rf /home/qemu/qemu-test.* + cd $(mktemp -d /home/qemu/qemu-test.XXXXXX); + mkdir src build; cd src; tar -xf /dev/rld1a; - ./configure --python=python2.7 {configure_opts}; + cd ../build + ../src/configure --python=python3.7 --disable-opengl {configure_opts}; gmake --output-sync -j{jobs} {target} {verbose}; """ + poweroff = "/sbin/poweroff" # Workaround for NetBSD + IPv6 + slirp issues. # NetBSD seems to ignore the ICMPv6 Destination Unreachable @@ -36,14 +71,147 @@ class NetBSDVM(basevm.BaseVM): ipv6 = False def build_image(self, img): - cimg = self._download_with_cache("http://download.patchew.org/netbsd-7.1-amd64.img.xz", - sha256sum='b633d565b0eac3d02015cd0c81440bd8a7a8df8512615ac1ee05d318be015732') - img_tmp_xz = img + ".tmp.xz" + cimg = self._download_with_cache(self.link, sha512sum=self.csum) img_tmp = img + ".tmp" - sys.stderr.write("Extracting the image...\n") - subprocess.check_call(["ln", "-f", cimg, img_tmp_xz]) - subprocess.check_call(["xz", "--keep", "-dvf", img_tmp_xz]) + iso = img + ".install.iso" + + self.print_step("Preparing iso and disk image") + subprocess.check_call(["ln", "-f", cimg, iso]) + subprocess.check_call(["qemu-img", "create", "-f", "qcow2", + img_tmp, self.size]) + + self.print_step("Booting installer") + self.boot(img_tmp, extra_args = [ + "-bios", "pc-bios/bios-256k.bin", + "-machine", "graphics=off", + "-cdrom", iso + ]) + self.console_init() + self.console_wait("Primary Bootstrap") + + # serial console boot menu output doesn't work for some + # reason, so we have to fly blind ... + for char in list("5consdev com0\n"): + time.sleep(0.2) + self.console_send(char) + self.console_consume() + self.console_wait_send("> ", "boot\n") + + self.console_wait_send("Terminal type", "xterm\n") + self.console_wait_send("a: Installation messages", "a\n") + self.console_wait_send("b: US-English", "b\n") + self.console_wait_send("a: Install NetBSD", "a\n") + self.console_wait("Shall we continue?") + self.console_wait_send("b: Yes", "b\n") + + self.console_wait_send("a: ld0", "a\n") + self.console_wait_send("a: This is the correct", "a\n") + self.console_wait_send("b: Use the entire disk", "b\n") + self.console_wait("NetBSD bootcode") + self.console_wait_send("a: Yes", "a\n") + self.console_wait_send("b: Use existing part", "b\n") + self.console_wait_send("x: Partition sizes ok", "x\n") + self.console_wait_send("for your NetBSD disk", "\n") + self.console_wait("Shall we continue?") + self.console_wait_send("b: Yes", "b\n") + + self.console_wait_send("b: Use serial port com0", "b\n") + self.console_wait_send("f: Set serial baud rate", "f\n") + self.console_wait_send("a: 9600", "a\n") + self.console_wait_send("x: Exit", "x\n") + + self.console_wait_send("a: Full installation", "a\n") + self.console_wait_send("a: CD-ROM", "a\n") + + self.print_step("Installation started now, this will take a while") + self.console_wait_send("Hit enter to continue", "\n") + + self.console_wait_send("d: Change root password", "d\n") + self.console_wait_send("a: Yes", "a\n") + self.console_wait("New password:") + self.console_send("%s\n" % self.ROOT_PASS) + self.console_wait("New password:") + self.console_send("%s\n" % self.ROOT_PASS) + self.console_wait("Retype new password:") + self.console_send("%s\n" % self.ROOT_PASS) + + self.console_wait_send("o: Add a user", "o\n") + self.console_wait("username") + self.console_send("%s\n" % self.GUEST_USER) + self.console_wait("to group wheel") + self.console_wait_send("a: Yes", "a\n") + self.console_wait_send("a: /bin/sh", "a\n") + self.console_wait("New password:") + self.console_send("%s\n" % self.GUEST_PASS) + self.console_wait("New password:") + self.console_send("%s\n" % self.GUEST_PASS) + self.console_wait("Retype new password:") + self.console_send("%s\n" % self.GUEST_PASS) + + self.console_wait_send("a: Configure network", "a\n") + self.console_wait_send("a: vioif0", "a\n") + self.console_wait_send("Network media type", "\n") + self.console_wait("autoconfiguration") + self.console_wait_send("a: Yes", "a\n") + self.console_wait_send("DNS domain", "localnet\n") + self.console_wait("Are they OK?") + self.console_wait_send("a: Yes", "a\n") + self.console_wait("installed in /etc") + self.console_wait_send("a: Yes", "a\n") + + self.console_wait_send("e: Enable install", "e\n") + proxy = os.environ.get("http_proxy") + if not proxy is None: + self.console_wait_send("f: Proxy", "f\n") + self.console_wait("Proxy") + self.console_send("%s\n" % proxy) + self.console_wait_send("x: Install pkgin", "x\n") + self.console_init(1200) + self.console_wait_send("Hit enter to continue", "\n") + self.console_init() + + self.console_wait_send("g: Enable sshd", "g\n") + self.console_wait_send("x: Finished conf", "x\n") + self.console_wait_send("Hit enter to continue", "\n") + + self.print_step("Installation finished, rebooting") + self.console_wait_send("d: Reboot the computer", "d\n") + + # setup qemu user + prompt = "localhost$" + self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_wait_send(prompt, "exit\n") + + # setup root user + prompt = "localhost#" + self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_sshd_config(prompt) + + # setup virtio-blk #1 (tarfile) + self.console_wait(prompt) + self.console_send("echo 'chmod 666 /dev/rld1a' >> /etc/rc.local\n") + + # turn off mprotect (conflicts with tcg) + self.console_wait(prompt) + self.console_send("echo security.pax.mprotect.enabled=0 >> /etc/sysctl.conf\n") + + self.print_step("Configuration finished, rebooting") + self.console_wait_send(prompt, "reboot\n") + self.console_wait("login:") + self.wait_ssh() + + self.print_step("Installing packages") + self.ssh_root_check("pkgin update\n") + self.ssh_root_check("pkgin -y install %s\n" % " ".join(self.pkgs)) + + # shutdown + self.ssh_root(self.poweroff) + self.console_wait("entering state S5") + self.wait() + os.rename(img_tmp, img) + os.remove(iso) + self.print_step("All done") if __name__ == "__main__": sys.exit(basevm.main(NetBSDVM)) |