From b4bda1ae57a20a7ce7cb0077946fc33d6d6fd6c5 Mon Sep 17 00:00:00 2001 From: Ricky Zhou Date: Mon, 14 Jul 2014 13:54:47 -0700 Subject: target-i386: Allow execute from user mode when SMEP is enabled. Previously, execute would be disabled for all pages with SMEP enabled, regardless of what mode the access took place in. Signed-off-by: Ricky Zhou Signed-off-by: Paolo Bonzini --- target-i386/helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 11ca8649b5..47b982b437 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -750,7 +750,8 @@ do_check_protect_pse36: /* the page can be put in the TLB */ prot = PAGE_READ; if (!(ptep & PG_NX_MASK) && - !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK))) { + (mmu_idx == MMU_USER_IDX || + !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) { prot |= PAGE_EXEC; } if (pte & PG_DIRTY_MASK) { -- cgit v1.2.1 From f52b7687825ae7b998ce790cd6028ff760b20b4c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 15 Jul 2014 14:57:06 +0200 Subject: qtest: new test for wdt_ib700 Since the "pause" watchdog action had a regression and it went unnoticed for a while, let's add a test for it. Signed-off-by: Paolo Bonzini --- tests/Makefile | 3 ++ tests/wdt_ib700-test.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 tests/wdt_ib700-test.c diff --git a/tests/Makefile b/tests/Makefile index 1fcd633871..c4422eef36 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -141,6 +141,8 @@ check-qtest-i386-y += tests/i440fx-test$(EXESUF) check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) check-qtest-i386-y += tests/blockdev-test$(EXESUF) check-qtest-i386-y += tests/qdev-monitor-test$(EXESUF) +check-qtest-i386-y += tests/wdt_ib700-test$(EXESUF) +gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c check-qtest-i386-y += $(check-qtest-pci-y) gcov-files-i386-y += $(gcov-files-pci-y) check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) @@ -311,6 +313,7 @@ tests/pcnet-test$(EXESUF): tests/pcnet-test.o tests/eepro100-test$(EXESUF): tests/eepro100-test.o tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o tests/ne2000-test$(EXESUF): tests/ne2000-test.o +tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o diff --git a/tests/wdt_ib700-test.c b/tests/wdt_ib700-test.c new file mode 100644 index 0000000000..513a533852 --- /dev/null +++ b/tests/wdt_ib700-test.c @@ -0,0 +1,134 @@ +/* + * QTest testcase for the IB700 watchdog + * + * Copyright (c) 2014 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include +#include +#include "libqtest.h" +#include "qemu/osdep.h" + +#define NS_PER_SEC 1000000000ULL + +static void qmp_check_no_event(void) +{ + QDict *resp = qmp("{'execute':'query-status'}"); + g_assert(qdict_haskey(resp, "return")); + QDECREF(resp); +} + +static QDict *qmp_get_event(const char *name) +{ + QDict *event = qmp(""); + QDict *data; + g_assert(qdict_haskey(event, "event")); + g_assert(!strcmp(qdict_get_str(event, "event"), name)); + + if (qdict_haskey(event, "data")) { + data = qdict_get_qdict(event, "data"); + QINCREF(data); + } else { + data = NULL; + } + + QDECREF(event); + return data; +} + +static QDict *ib700_program_and_wait(QTestState *s) +{ + clock_step(NS_PER_SEC * 40); + qmp_check_no_event(); + + /* 2 second limit */ + outb(0x443, 14); + + /* Ping */ + clock_step(NS_PER_SEC); + qmp_check_no_event(); + outb(0x443, 14); + + /* Disable */ + clock_step(NS_PER_SEC); + qmp_check_no_event(); + outb(0x441, 1); + clock_step(3 * NS_PER_SEC); + qmp_check_no_event(); + + /* Enable and let it fire */ + outb(0x443, 13); + clock_step(3 * NS_PER_SEC); + qmp_check_no_event(); + clock_step(2 * NS_PER_SEC); + return qmp_get_event("WATCHDOG"); +} + + +static void ib700_pause(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action pause -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "pause")); + QDECREF(d); + d = qmp_get_event("STOP"); + QDECREF(d); + qtest_end(); +} + +static void ib700_reset(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action reset -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "reset")); + QDECREF(d); + d = qmp_get_event("RESET"); + QDECREF(d); + qtest_end(); +} + +static void ib700_shutdown(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action reset -no-reboot -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "reset")); + QDECREF(d); + d = qmp_get_event("SHUTDOWN"); + QDECREF(d); + qtest_end(); +} + +static void ib700_none(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action none -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "none")); + QDECREF(d); + qtest_end(); +} + +int main(int argc, char **argv) +{ + int ret; + + g_test_init(&argc, &argv, NULL); + qtest_add_func("/wdt_ib700/pause", ib700_pause); + qtest_add_func("/wdt_ib700/reset", ib700_reset); + qtest_add_func("/wdt_ib700/shutdown", ib700_shutdown); + qtest_add_func("/wdt_ib700/none", ib700_none); + + ret = g_test_run(); + + return ret; +} -- cgit v1.2.1 From f9e13f8fd87710063f9fa0feaf7de0348b32612a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Tue, 15 Jul 2014 16:04:25 +0200 Subject: module: Simplify module_load() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The file path is not used for error reporting, so we can free it directly after use. Reviewed-by: Fam Zheng Signed-off-by: Andreas Färber Signed-off-by: Paolo Bonzini --- util/module.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/util/module.c b/util/module.c index 214effb39f..9fd30309ae 100644 --- a/util/module.c +++ b/util/module.c @@ -202,18 +202,16 @@ static void module_load(module_init_type type) for (i = 0; i < ARRAY_SIZE(dirs); i++) { fname = g_strdup_printf("%s/%s%s", dirs[i], *mp, HOST_DSOSUF); ret = module_load_file(fname); + g_free(fname); + fname = NULL; /* Try loading until loaded a module file */ if (!ret) { break; } - g_free(fname); - fname = NULL; } if (ret == -ENOENT) { fprintf(stderr, "Can't find module: %s\n", *mp); } - - g_free(fname); } for (i = 0; i < ARRAY_SIZE(dirs); i++) { -- cgit v1.2.1 From bb2eb1892d36e5c9fa1695924434313e3acbb1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Tue, 15 Jul 2014 16:04:26 +0200 Subject: module: Don't complain when a module is absent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation depends on a configure-time generated list of block modules. When any of them is absent, module_load() emits a warning. This is suboptimal because extracting code to modules was mainly done to allow separate packaging of modules with intrusive dependencies. Absence of optional packages then leads to absence of modules and an error message, which users may recognize as new and report as error. Cc: Paolo Bonzini Cc: Michael Tokarev Reviewed-by: Fam Zheng Signed-off-by: Andreas Färber Signed-off-by: Paolo Bonzini --- util/module.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/util/module.c b/util/module.c index 9fd30309ae..4bd4a94d87 100644 --- a/util/module.c +++ b/util/module.c @@ -209,9 +209,6 @@ static void module_load(module_init_type type) break; } } - if (ret == -ENOENT) { - fprintf(stderr, "Can't find module: %s\n", *mp); - } } for (i = 0; i < ARRAY_SIZE(dirs); i++) { -- cgit v1.2.1 From 108e4c3871e0d0cd185ccffef5e932961f92dd63 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 15 Jul 2014 21:45:42 +0200 Subject: Revert "kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation" This reverts commit 9b1786829aefb83f37a8f3135e3ea91c56001b56. This patch fixed a hang introduced by commit a096b3a (kvmclock: Ensure time in migration never goes backward, 2014-05-16), but it causes a regression in migration whose cause is not quite clear. Because of this, I'm choosing to revert both patches. This trades a 2.1 regression for a bug that's been there forever. Cc: agraf@suse.de Cc: mtosatti@redhat.com Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini --- hw/i386/kvm/clock.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 272a88acb5..feb5fc5109 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -17,7 +17,6 @@ #include "qemu/host-utils.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" -#include "sysemu/cpus.h" #include "hw/sysbus.h" #include "hw/kvm/clock.h" @@ -66,7 +65,6 @@ static uint64_t kvmclock_current_nsec(KVMClockState *s) cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time)); - assert(time.tsc_timestamp <= migration_tsc); delta = migration_tsc - time.tsc_timestamp; if (time.tsc_shift < 0) { delta >>= -time.tsc_shift; @@ -125,8 +123,6 @@ static void kvmclock_vm_state_change(void *opaque, int running, if (s->clock_valid) { return; } - - cpu_synchronize_all_states(); ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); if (ret < 0) { fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); -- cgit v1.2.1 From fa666c10f2f3e15685ff88abd3bc433ddce012d6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 15 Jul 2014 21:46:02 +0200 Subject: Revert "kvmclock: Ensure time in migration never goes backward" This reverts commit a096b3a6732f846ec57dc28b47ee9435aa0609bf. This patch caused a hang that was fixed by commit 9b17868 (kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation, 2014-06-03), and we just had to revert that commit. Drop this one too. Cc: agraf@suse.de Cc: mtosatti@redhat.com Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini --- hw/i386/kvm/clock.c | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index feb5fc5109..07b9c0e581 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -14,7 +14,6 @@ */ #include "qemu-common.h" -#include "qemu/host-utils.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "hw/sysbus.h" @@ -35,47 +34,6 @@ typedef struct KVMClockState { bool clock_valid; } KVMClockState; -struct pvclock_vcpu_time_info { - uint32_t version; - uint32_t pad0; - uint64_t tsc_timestamp; - uint64_t system_time; - uint32_t tsc_to_system_mul; - int8_t tsc_shift; - uint8_t flags; - uint8_t pad[2]; -} __attribute__((__packed__)); /* 32 bytes */ - -static uint64_t kvmclock_current_nsec(KVMClockState *s) -{ - CPUState *cpu = first_cpu; - CPUX86State *env = cpu->env_ptr; - hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL; - uint64_t migration_tsc = env->tsc; - struct pvclock_vcpu_time_info time; - uint64_t delta; - uint64_t nsec_lo; - uint64_t nsec_hi; - uint64_t nsec; - - if (!(env->system_time_msr & 1ULL)) { - /* KVM clock not active */ - return 0; - } - - cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time)); - - delta = migration_tsc - time.tsc_timestamp; - if (time.tsc_shift < 0) { - delta >>= -time.tsc_shift; - } else { - delta <<= time.tsc_shift; - } - - mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul); - nsec = (nsec_lo >> 32) | (nsec_hi << 32); - return nsec + time.system_time; -} static void kvmclock_vm_state_change(void *opaque, int running, RunState state) @@ -87,15 +45,9 @@ static void kvmclock_vm_state_change(void *opaque, int running, if (running) { struct kvm_clock_data data; - uint64_t time_at_migration = kvmclock_current_nsec(s); s->clock_valid = false; - /* We can't rely on the migrated clock value, just discard it */ - if (time_at_migration) { - s->clock = time_at_migration; - } - data.clock = s->clock; data.flags = 0; ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); -- cgit v1.2.1