mirror of https://github.com/xemu-project/xemu.git
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/host-utils.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/kvm/clock.h"
|
||||
|
||||
|
@ -36,48 +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));
|
||||
|
||||
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,
|
||||
RunState state)
|
||||
|
@ -89,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);
|
||||
|
@ -125,8 +75,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));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
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++) {
|
||||
|
|
Loading…
Reference in New Issue