Andreas's fixes to --enable-modules, two 2.1 regression fixes, and a
new qtest. Michael sent a pull request of his own, so I dropped the vhost changes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJTySF6AAoJEBvWZb6bTYbyA2UQAJRezh6xrYLZ2PYTTkYXSpsB a9egMAHcOQTKJG4bm6PyUTsLtAm6lS/RJkqVzTBszj2/e2ieDZyp2CAmtQ720rmf OC7Zy5+y39tadKxVLZknsB/jDWlpTlYAc+xyIgtFV6Eh8b98QKHMzks9vdJDCgdO ZEe8pTP5UZpNd0qco0pliX7OFHlOaCT+aNoI0ECkBEh2hBUQ0HkF4N6ZCei6wADq PYcZ//djeZb9n9hQs9ikwQnLEriv01d9qXDDqcVPPK6SJ0YkcbHwF/lItxz9Tb8K lFRAFrvkY7wF0E6dMpsUy4rpYcCGBgv9wu6trLsHZyXPX1jy7ezyfa6t/9hE8Kaz l7D1ROQeDW+oIaAlvQM3huG5A1FEBy5SNyjllXcD4JK8AWyD816gl5hgMVsuX7RT oSOXt5kDliGu9cTZaqzm7+Ij0gfAoncGPSqHxcN4Q4cAwe7+fAuLkQP0hmJVf4Tr IFBWvfyler0ziCK91rmxNYt4p2tV7w259YqyJfNMqC1c48dWWve2qzhkhES7K/A7 V276d+6fwXKqW76JdWQLEvrLz8QI2SKu4Kihwh/UGJACuL9rwfZfhKy5+PqrhY/V cESREbpJQnAH2RyoA7D/ut4+VyJNWRZSH7g569srNgGStfnefmrusJCb5bPAF9O+ RyW92wsHzEv5Nezci+4i =4qtI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging Andreas's fixes to --enable-modules, two 2.1 regression fixes, and a new qtest. Michael sent a pull request of his own, so I dropped the vhost changes. # gpg: Signature made Fri 18 Jul 2014 14:30:34 BST using RSA key ID 9B4D86F2 # gpg: Can't check signature: public key not found * remotes/bonzini/tags/for-upstream: Revert "kvmclock: Ensure time in migration never goes backward" Revert "kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation" module: Don't complain when a module is absent module: Simplify module_load() qtest: new test for wdt_ib700 target-i386: Allow execute from user mode when SMEP is enabled. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
50a2c45da9
|
@ -14,10 +14,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/host-utils.h"
|
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "sysemu/cpus.h"
|
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "hw/kvm/clock.h"
|
#include "hw/kvm/clock.h"
|
||||||
|
|
||||||
|
@ -36,48 +34,6 @@ typedef struct KVMClockState {
|
||||||
bool clock_valid;
|
bool clock_valid;
|
||||||
} KVMClockState;
|
} 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));
|
|
||||||
|
|
||||||
assert(time.tsc_timestamp <= migration_tsc);
|
|
||||||
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,
|
static void kvmclock_vm_state_change(void *opaque, int running,
|
||||||
RunState state)
|
RunState state)
|
||||||
|
@ -89,15 +45,9 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||||
|
|
||||||
if (running) {
|
if (running) {
|
||||||
struct kvm_clock_data data;
|
struct kvm_clock_data data;
|
||||||
uint64_t time_at_migration = kvmclock_current_nsec(s);
|
|
||||||
|
|
||||||
s->clock_valid = false;
|
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.clock = s->clock;
|
||||||
data.flags = 0;
|
data.flags = 0;
|
||||||
ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
|
ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
|
||||||
|
@ -125,8 +75,6 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||||
if (s->clock_valid) {
|
if (s->clock_valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_synchronize_all_states();
|
|
||||||
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
|
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
|
fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
|
||||||
|
|
|
@ -750,7 +750,8 @@ do_check_protect_pse36:
|
||||||
/* the page can be put in the TLB */
|
/* the page can be put in the TLB */
|
||||||
prot = PAGE_READ;
|
prot = PAGE_READ;
|
||||||
if (!(ptep & PG_NX_MASK) &&
|
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;
|
prot |= PAGE_EXEC;
|
||||||
}
|
}
|
||||||
if (pte & PG_DIRTY_MASK) {
|
if (pte & PG_DIRTY_MASK) {
|
||||||
|
|
|
@ -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/fw_cfg-test$(EXESUF)
|
||||||
check-qtest-i386-y += tests/blockdev-test$(EXESUF)
|
check-qtest-i386-y += tests/blockdev-test$(EXESUF)
|
||||||
check-qtest-i386-y += tests/qdev-monitor-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)
|
check-qtest-i386-y += $(check-qtest-pci-y)
|
||||||
gcov-files-i386-y += $(gcov-files-pci-y)
|
gcov-files-i386-y += $(gcov-files-pci-y)
|
||||||
check-qtest-i386-y += tests/vmxnet3-test$(EXESUF)
|
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/eepro100-test$(EXESUF): tests/eepro100-test.o
|
||||||
tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
|
tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
|
||||||
tests/ne2000-test$(EXESUF): tests/ne2000-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-balloon-test$(EXESUF): tests/virtio-balloon-test.o
|
||||||
tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o
|
tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o
|
||||||
tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
|
tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
|
||||||
|
|
134
tests/wdt_ib700-test.c
Normal file
134
tests/wdt_ib700-test.c
Normal file
|
@ -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 <glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -202,18 +202,13 @@ static void module_load(module_init_type type)
|
||||||
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
||||||
fname = g_strdup_printf("%s/%s%s", dirs[i], *mp, HOST_DSOSUF);
|
fname = g_strdup_printf("%s/%s%s", dirs[i], *mp, HOST_DSOSUF);
|
||||||
ret = module_load_file(fname);
|
ret = module_load_file(fname);
|
||||||
|
g_free(fname);
|
||||||
|
fname = NULL;
|
||||||
/* Try loading until loaded a module file */
|
/* Try loading until loaded a module file */
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
break;
|
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++) {
|
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
||||||
|
|
Loading…
Reference in a new issue