From 0a2672b7ead72b7c788200499a63a4d5f2faa74a Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 26 Jun 2014 10:44:22 +0100 Subject: [PATCH 01/10] mips/kvm: Init EBase to correct KSEG0 The EBase CP0 register is initialised to 0x80000000, however with KVM the guest's KSEG0 is at 0x40000000. The incorrect value doesn't get passed to KVM yet as KVM doesn't implement the EBase register, however we should set it correctly now so as not to break migration/loadvm to a future version of QEMU that does support EBase. Cc: Aurelien Jarno Cc: Paolo Bonzini Signed-off-by: James Hogan Reviewed-by: Aurelien Jarno Signed-off-by: Paolo Bonzini --- target-mips/translate.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2f91959ed7..d7b8c4dbc8 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -28,6 +28,7 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" +#include "sysemu/kvm.h" #define MIPS_DEBUG_DISAS 0 //#define MIPS_DEBUG_SIGN_EXTENSIONS @@ -16076,7 +16077,12 @@ void cpu_state_reset(CPUMIPSState *env) env->CP0_Random = env->tlb->nb_tlb - 1; env->tlb->tlb_in_use = env->tlb->nb_tlb; env->CP0_Wired = 0; - env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF); + env->CP0_EBase = (cs->cpu_index & 0x3FF); + if (kvm_enabled()) { + env->CP0_EBase |= 0x40000000; + } else { + env->CP0_EBase |= 0x80000000; + } env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); /* vectored interrupts not implemented, timer on int 7, no performance counters. */ From 0e928b12c94a4eea56028dec676422b165063ea5 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Fri, 27 Jun 2014 16:22:42 +0100 Subject: [PATCH 02/10] mips/kvm: Disable FPU on reset with KVM KVM doesn't yet support the MIPS FPU, or writing to the guest's Config1 register which contains the FPU implemented bit. Clear QEMU's version of that bit on reset and display a warning that the FPU has been disabled. The previous incorrect Config1 CP0 register value wasn't being passed to KVM yet, however we should ensure it is set correctly now to reduce the risk of breaking migration/loadvm to a future version of QEMU/Linux that does support it. Signed-off-by: James Hogan Cc: Aurelien Jarno Cc: Paolo Bonzini Signed-off-by: Paolo Bonzini --- target-mips/kvm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/target-mips/kvm.c b/target-mips/kvm.c index 844e5bbe5f..97fd51a02f 100644 --- a/target-mips/kvm.c +++ b/target-mips/kvm.c @@ -61,6 +61,13 @@ int kvm_arch_init_vcpu(CPUState *cs) void kvm_mips_reset_vcpu(MIPSCPU *cpu) { + CPUMIPSState *env = &cpu->env; + + if (env->CP0_Config1 & (1 << CP0C1_FP)) { + fprintf(stderr, "Warning: FPU not supported with KVM, disabling\n"); + env->CP0_Config1 &= ~(1 << CP0C1_FP); + } + DPRINTF("%s\n", __func__); } From fbdb1d955511c38e61e3aa3ba4fb3944b126eb28 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 26 Jun 2014 10:44:24 +0100 Subject: [PATCH 03/10] mips_malta: Remove incorrect KVM T&E references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the error message and code comments relating to KVM not supporting booting from the flash mapping when no kernel is provided. The issue is a general MIPS KVM issue and isn't specific to the Trap & Emulate version of MIPS KVM. Cc: Aurelien Jarno Cc: Paolo Bonzini Reported-by: Andreas Färber Signed-off-by: James Hogan Reviewed-by: Aurelien Jarno Signed-off-by: Paolo Bonzini --- hw/mips/mips_malta.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 2868ee5b03..3305a25fc1 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1028,7 +1028,7 @@ void mips_malta_init(MachineState *machine) fl_idx++; if (kernel_filename) { ram_low_size = MIN(ram_size, 256 << 20); - /* For KVM T&E we reserve 1MB of RAM for running bootloader */ + /* For KVM we reserve 1MB of RAM for running bootloader */ if (kvm_enabled()) { ram_low_size -= 0x100000; bootloader_run_addr = 0x40000000 + ram_low_size; @@ -1052,10 +1052,10 @@ void mips_malta_init(MachineState *machine) bootloader_run_addr, kernel_entry); } } else { - /* The flash region isn't executable from a KVM T&E guest */ + /* The flash region isn't executable from a KVM guest */ if (kvm_enabled()) { error_report("KVM enabled but no -kernel argument was specified. " - "Booting from flash is not supported with KVM T&E."); + "Booting from flash is not supported with KVM."); exit(1); } /* Load firmware from flash. */ From f7f152458e953690f1c8025f507a26d554f6ee4d Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 26 Jun 2014 10:44:25 +0100 Subject: [PATCH 04/10] mips_malta: Catch kernels linked at wrong address Add error reporting if the wrong type of kernel is provided for the current mode of acceleration. Currently a KVM kernel linked at 0x40000000 can't be used with TCG, and a normal kernel linked at 0x80000000 can't be used with KVM. Cc: Aurelien Jarno Cc: Paolo Bonzini Signed-off-by: James Hogan Reviewed-by: Aurelien Jarno Signed-off-by: Paolo Bonzini --- hw/mips/mips_malta.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 3305a25fc1..cfb60aff9f 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -792,9 +792,23 @@ static int64_t load_kernel (void) loaderparams.kernel_filename); exit(1); } + + /* Sanity check where the kernel has been linked */ if (kvm_enabled()) { + if (kernel_entry & 0x80000000ll) { + error_report("KVM guest kernels must be linked in useg. " + "Did you forget to enable CONFIG_KVM_GUEST?"); + exit(1); + } + xlate_to_kseg0 = cpu_mips_kvm_um_phys_to_kseg0; } else { + if (!(kernel_entry & 0x80000000ll)) { + error_report("KVM guest kernels aren't supported with TCG. " + "Did you unintentionally enable CONFIG_KVM_GUEST?"); + exit(1); + } + xlate_to_kseg0 = cpu_mips_phys_to_kseg0; } From 30e5210a706ca6b52cbefa8b71e40ae614ffd6e5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 27 Jun 2014 16:31:07 +0200 Subject: [PATCH 05/10] watchdog: fix deadlock with -watchdog-action pause qemu_clock_enable says: /* Disabling the clock will wait for related timerlists to stop * executing qemu_run_timers. Thus, this functions should not * be used from the callback of a timer that is based on @clock. * Doing so would cause a deadlock. */ and it indeed does: vm_stop uses qemu_clock_enable on QEMU_CLOCK_VIRTUAL and watchdogs are based on QEMU_CLOCK_VIRTUAL, and we get a deadlock. Use qemu_system_vmstop_request_prepare()/qemu_system_vmstop_request() instead; yet another alternative could be a BH. I checked other occurrences of vm_stop and they should not have this problem. RUN_STATE_IO_ERROR could in principle (it depends on the code in the drivers) but it has been fixed by commit 2bd3bce, "block: asynchronously stop the VM on I/O errors", 2014-06-05. Tested-by: Luiz Capitulino Signed-off-by: Paolo Bonzini --- hw/watchdog/watchdog.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c index 9f607d42bb..c307f9b57e 100644 --- a/hw/watchdog/watchdog.c +++ b/hw/watchdog/watchdog.c @@ -122,8 +122,12 @@ void watchdog_perform_action(void) exit(0); case WDT_PAUSE: /* same as 'stop' command in monitor */ + /* In a timer callback, when vm_stop calls qemu_clock_enable + * you would get a deadlock. Bypass the problem. + */ + qemu_system_vmstop_request_prepare(); qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_PAUSE, &error_abort); - vm_stop(RUN_STATE_WATCHDOG); + qemu_system_vmstop_request(RUN_STATE_WATCHDOG); break; case WDT_DEBUG: From 3b463a3fa8f7690ffa3ef273993dff349b3a73d3 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 2 Jul 2014 10:05:24 +0200 Subject: [PATCH 06/10] Enforce stack protector usage If --enable-stack-protector is used is used, configure script try to use --fstack-protector-strong. In case it's not supported, --fstack-protector-all is enabled. If both protectors are not supported, configure does not use any protector at all without any notification. This patch reports error when user requests stack protector to be used and both protector modes are not supported. Behavior is not changed in case user do not use any of --enable-stack-protector/--disable-stack-protector. Signed-off-by: Miroslav Rezanina [Fix non-POSIX operator in test. - Paolo] Signed-off-by: Paolo Bonzini --- configure | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 7dd43fdc70..f7685b565c 100755 --- a/configure +++ b/configure @@ -1489,8 +1489,9 @@ for flag in $gcc_flags; do fi done -if test "$stack_protector" != "no" ; then +if test "$stack_protector" != "no"; then gcc_flags="-fstack-protector-strong -fstack-protector-all" + sp_on=0 for flag in $gcc_flags; do # We need to check both a compile and a link, since some compiler # setups fail only on a .c->.o compile and some only at link time @@ -1498,9 +1499,15 @@ if test "$stack_protector" != "no" ; then compile_prog "-Werror $flag" ""; then QEMU_CFLAGS="$QEMU_CFLAGS $flag" LIBTOOLFLAGS="$LIBTOOLFLAGS -Wc,$flag" + sp_on=1 break fi done + if test "$stack_protector" = yes; then + if test $sp_on = 0; then + error_exit "Stack protector not supported" + fi + fi fi # Workaround for http://gcc.gnu.org/PR55489. Happens with -fPIE/-fPIC and From 8248c36a5db6ff7d5f07f05148be0dd0160e650c Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 4 Jul 2014 16:44:34 -0300 Subject: [PATCH 07/10] target-i386: Add "kvmclock-stable-bit" feature bit name KVM_FEATURE_CLOCKSOURCE_STABLE_BIT is enabled by default and supported by KVM. But not having a name defined makes QEMU treat it as an unknown and unmigratable feature flag (as any unknown feature may possibly require state to be migrated), and disable it by default on "-cpu host". As a side-effect, the new name also makes the flag configurable, allowing the user to disable it (which may be useful for testing or for compatibility with old kernels). Signed-off-by: Eduardo Habkost Signed-off-by: Paolo Bonzini --- target-i386/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 45c662dad4..6d008ab5ee 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -241,7 +241,7 @@ static const char *kvm_feature_name[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + "kvmclock-stable-bit", NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; From b7bf8f5657d48e4625c86cd5f1d3cc83e830d8f7 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Tue, 24 Jun 2014 22:52:29 +0200 Subject: [PATCH 08/10] oslib-posix: Fix new compiler error with -Wclobbered MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer versions of gcc report a warning (or an error with -Werror) when compiler option -Wclobbered (or -Wextra) is active: util/oslib-posix.c:372:12: error: variable ‘hpagesize’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] The rewritten code fixes this warning: variable 'hpagesize' is now set and used in a block without any call of sigsetjmp or similar functions. Signed-off-by: Stefan Weil Signed-off-by: Paolo Bonzini --- util/oslib-posix.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 1524ead755..cdbfb2e270 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -366,10 +366,9 @@ static size_t fd_getpagesize(int fd) void os_mem_prealloc(int fd, char *area, size_t memory) { - int ret, i; + int ret; struct sigaction act, oldact; sigset_t set, oldset; - size_t hpagesize = fd_getpagesize(fd); memset(&act, 0, sizeof(act)); act.sa_handler = &sigbus_handler; @@ -389,19 +388,22 @@ void os_mem_prealloc(int fd, char *area, size_t memory) if (sigsetjmp(sigjump, 1)) { fprintf(stderr, "os_mem_prealloc: failed to preallocate pages\n"); exit(1); - } + } else { + int i; + size_t hpagesize = fd_getpagesize(fd); - /* MAP_POPULATE silently ignores failures */ - memory = (memory + hpagesize - 1) & -hpagesize; - for (i = 0; i < (memory/hpagesize); i++) { - memset(area + (hpagesize*i), 0, 1); - } + /* MAP_POPULATE silently ignores failures */ + memory = (memory + hpagesize - 1) & -hpagesize; + for (i = 0; i < (memory / hpagesize); i++) { + memset(area + (hpagesize * i), 0, 1); + } - ret = sigaction(SIGBUS, &oldact, NULL); - if (ret) { - perror("os_mem_prealloc: failed to reinstall signal handler"); - exit(1); - } + ret = sigaction(SIGBUS, &oldact, NULL); + if (ret) { + perror("os_mem_prealloc: failed to reinstall signal handler"); + exit(1); + } - pthread_sigmask(SIG_SETMASK, &oldset, NULL); + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + } } From 13c0cbaec5698f3984606e52bfcfb63ddfc29f00 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 8 Jul 2014 07:42:05 +0200 Subject: [PATCH 09/10] mc146818rtc: register the clock reset notifier on the right clock Commit 884f17c (aio / timers: Convert rtc_clock to be a QEMUClockType, 2013-08-21) erroneously changed an occurrence of rtc_clock to QEMU_CLOCK_REALTIME, which broke the RTC reset notifier in mc146818rtc. Fix this. I redid the patch myself since the original reporter did not sign off on his. Cc: qemu-stable@nongnu.org Reported-by: Lb peace Signed-off-by: Paolo Bonzini --- hw/timer/mc146818rtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 9d817cab78..233fc70d67 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -895,7 +895,7 @@ static void rtc_realizefn(DeviceState *dev, Error **errp) check_update_timer(s); s->clock_reset_notifier.notify = rtc_notify_clock_reset; - qemu_clock_register_reset_notifier(QEMU_CLOCK_REALTIME, + qemu_clock_register_reset_notifier(rtc_clock, &s->clock_reset_notifier); s->suspend_notifier.notify = rtc_notify_suspend; From 0a58991a5f7efd6eb8a66643f4fd894b9c6874b7 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolaev Date: Wed, 9 Jul 2014 18:06:32 +0300 Subject: [PATCH 10/10] qtest: fix vhost-user-test compilation with old GLib Mising G_TIME_SPAN_SECOND definition breaks the RHEL6 compilation as GLib version before 2.26 does not have it. In such case just define it. Reported-by: Kevin Wolf Signed-off-by: Nikolay Nikolaev Signed-off-by: Paolo Bonzini --- tests/vhost-user-test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 2af2381a1d..406ba70941 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -22,6 +22,10 @@ #include /* GLIB version compatibility flags */ +#if !GLIB_CHECK_VERSION(2, 26, 0) +#define G_TIME_SPAN_SECOND (G_GINT64_CONSTANT(1000000)) +#endif + #if GLIB_CHECK_VERSION(2, 28, 0) #define HAVE_MONOTONIC_TIME #endif