Usual mix of patches, the most important being Alex and Marcelo's
kvmclock fix. This was reverted last minute for 2.1, but it is now back with the problematic case fixed. Note: I will soon switch to a subkey for signing purposes. To verify future signed pull requests from me, please update my key with "gpg --recv-keys 9B4D86F2". You should see 3 new subkeys---the one for signing will be a 2048-bit RSA key, 4E6B09D7. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJUJXmEAAoJEBvWZb6bTYbyuZoP+gJScjcoHVL27YL6GqCsLzQ+ swk/6TDaboR5+t3Tt1vHOWOvtXmoZlxp+sQU50ltiKS1mwRTsMAhEeTInTNPLJ6z aKX46QdvNib2bYdUgnl8nqOiKQAZiA6rR8os2lWJ3E8n1n6qBbeWwneQK2YvRaVf RMjmDm7sjhZt5h868O7SPNDSjk8k5TgYj5MOsDugFxQr6JXGxt8xmB+Ml6v6Ne+y ufDchXtBhANIkr1aNMeOBYdX+/wuY+fltjnG11xpuAL1a63F/b3EGvPoqUHQCZSd PzHmkSZV0z3rmgVTpcAHxSw2MxUEgmXLvxWAQTahrzGUi8mH3hF7z7zNqfULZWa1 3hctUdlf9aWbIgdfEdBZqOjol58TYvgCjIa7W2upsvEf7sjctpCZnMmBi8vMM3FQ qv7S4139jN70+7zNY8CCnXPuOY63rsFTAs8XCPF7DL3HESzm7x8MEFgW7/7iJtwQ PNJVbJX8+FpDmdAy/fwkMKA8BvjmNBuIZrr9/IfFJ6uM70//brq3OXq25agToBpZ QYWW5CXYeQXurPBK1Q6XkGx61mNuc5zOveVS+8MhJKw9SiL/cIhQzrh3fgFtIP+e 63LlufFPMA2+fhBJctptIoU9+XeUwalQic92ZqepuXB/OZV6vhhV9/K2zZMUMpl9 B/Gg3cd1w5rMHg6O2kov =nP/e -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging Usual mix of patches, the most important being Alex and Marcelo's kvmclock fix. This was reverted last minute for 2.1, but it is now back with the problematic case fixed. Note: I will soon switch to a subkey for signing purposes. To verify future signed pull requests from me, please update my key with "gpg --recv-keys 9B4D86F2". You should see 3 new subkeys---the one for signing will be a 2048-bit RSA key, 4E6B09D7. # gpg: Signature made Fri 26 Sep 2014 15:34:44 BST using RSA key ID 9B4D86F2 # gpg: Good signature from "Paolo Bonzini <pbonzini@redhat.com>" # gpg: aka "Paolo Bonzini <bonzini@gnu.org>" * remotes/bonzini/tags/for-upstream: kvm/valgrind: don't mark memory as initialized po: fix conflict with %.mo rule in rules.mak kvmvapic: fix migration when VM paused and when not running Windows serial: check if backed by a physical serial port at realize time serial: reset state at startup target-i386: update fp status fix hw/dma/i8257: Silence phony error message kvmclock: Ensure time in migration never goes backward kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation Introduce cpu_clean_all_dirty pit: fix pit interrupt can't inject into vm after migration Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
81ab11a7a5
3
configure
vendored
3
configure
vendored
@ -3956,12 +3956,11 @@ else
|
||||
fi
|
||||
|
||||
########################################
|
||||
# check if we have valgrind/valgrind.h and valgrind/memcheck.h
|
||||
# check if we have valgrind/valgrind.h
|
||||
|
||||
valgrind_h=no
|
||||
cat > $TMPC << EOF
|
||||
#include <valgrind/valgrind.h>
|
||||
#include <valgrind/memcheck.h>
|
||||
int main(void) {
|
||||
return 0;
|
||||
}
|
||||
|
9
cpus.c
9
cpus.c
@ -593,6 +593,15 @@ void cpu_synchronize_all_post_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_clean_all_dirty(void)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
cpu_clean_state(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static int do_vm_stop(RunState state)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -815,6 +815,9 @@ static void serial_reset(void *opaque)
|
||||
s->thr_ipending = 0;
|
||||
s->last_break_enable = 0;
|
||||
qemu_irq_lower(s->irq);
|
||||
|
||||
serial_update_msl(s);
|
||||
s->msr &= ~UART_MSR_ANY_DELTA;
|
||||
}
|
||||
|
||||
void serial_realize_core(SerialState *s, Error **errp)
|
||||
@ -833,6 +836,7 @@ void serial_realize_core(SerialState *s, Error **errp)
|
||||
serial_event, s);
|
||||
fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
|
||||
fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH);
|
||||
serial_reset(s);
|
||||
}
|
||||
|
||||
void serial_exit_core(SerialState *s)
|
||||
@ -944,7 +948,5 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
|
||||
memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
|
||||
"serial", 8 << it_shift);
|
||||
memory_region_add_subregion(address_space, base, &s->io);
|
||||
|
||||
serial_update_msl(s);
|
||||
return s;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "hw/hw.h"
|
||||
#include "hw/isa/isa.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* #define DEBUG_DMA */
|
||||
|
||||
@ -473,8 +474,7 @@ static void dma_reset(void *opaque)
|
||||
|
||||
static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
|
||||
{
|
||||
dolog ("unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n",
|
||||
nchan, dma_pos, dma_len);
|
||||
trace_i8257_unregistered_dma(nchan, dma_pos, dma_len);
|
||||
return dma_pos;
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,10 @@
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
@ -34,6 +36,48 @@ 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)
|
||||
@ -45,9 +89,15 @@ 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);
|
||||
@ -75,6 +125,9 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
if (s->clock_valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_synchronize_all_states();
|
||||
cpu_clean_all_dirty();
|
||||
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
|
||||
|
@ -239,6 +239,7 @@ static void kvm_pit_vm_state_change(void *opaque, int running,
|
||||
|
||||
if (running) {
|
||||
kvm_pit_update_clock_offset(s);
|
||||
kvm_pit_put(PIT_COMMON(s));
|
||||
s->vm_stopped = false;
|
||||
} else {
|
||||
kvm_pit_update_clock_offset(s);
|
||||
@ -314,8 +315,6 @@ static void kvm_pit_class_init(ObjectClass *klass, void *data)
|
||||
dc->realize = kvm_pit_realizefn;
|
||||
k->set_channel_gate = kvm_pit_set_gate;
|
||||
k->get_channel_info = kvm_pit_get_channel_info;
|
||||
k->pre_save = kvm_pit_get;
|
||||
k->post_load = kvm_pit_put;
|
||||
dc->reset = kvm_pit_reset;
|
||||
dc->props = kvm_pit_properties;
|
||||
}
|
||||
|
@ -732,7 +732,11 @@ static void do_vapic_enable(void *data)
|
||||
VAPICROMState *s = data;
|
||||
X86CPU *cpu = X86_CPU(first_cpu);
|
||||
|
||||
vapic_enable(s, cpu);
|
||||
static const uint8_t enabled = 1;
|
||||
cpu_physical_memory_write(s->vapic_paddr + offsetof(VAPICState, enabled),
|
||||
&enabled, sizeof(enabled));
|
||||
apic_enable_vapic(cpu->apic_state, s->vapic_paddr);
|
||||
s->state = VAPIC_ACTIVE;
|
||||
}
|
||||
|
||||
static void kvmvapic_vm_state_change(void *opaque, int running,
|
||||
@ -777,7 +781,10 @@ static int vapic_post_load(void *opaque, int version_id)
|
||||
}
|
||||
}
|
||||
|
||||
s->vmsentry = qemu_add_vm_change_state_handler(kvmvapic_vm_state_change, s);
|
||||
if (!s->vmsentry) {
|
||||
s->vmsentry =
|
||||
qemu_add_vm_change_state_handler(kvmvapic_vm_state_change, s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ void cpu_stop_current(void);
|
||||
void cpu_synchronize_all_states(void);
|
||||
void cpu_synchronize_all_post_reset(void);
|
||||
void cpu_synchronize_all_post_init(void);
|
||||
void cpu_clean_all_dirty(void);
|
||||
|
||||
void qtest_clock_warp(int64_t dest);
|
||||
|
||||
|
@ -350,6 +350,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
|
||||
void kvm_cpu_synchronize_state(CPUState *cpu);
|
||||
void kvm_cpu_synchronize_post_reset(CPUState *cpu);
|
||||
void kvm_cpu_synchronize_post_init(CPUState *cpu);
|
||||
void kvm_cpu_clean_state(CPUState *cpu);
|
||||
|
||||
/* generic hooks - to be moved/refactored once there are more users */
|
||||
|
||||
@ -374,6 +375,13 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cpu_clean_state(CPUState *cpu)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
kvm_cpu_clean_state(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
|
||||
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
|
||||
void kvm_irqchip_release_virq(KVMState *s, int virq);
|
||||
|
12
kvm-all.c
12
kvm-all.c
@ -44,10 +44,6 @@
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
#include <valgrind/memcheck.h>
|
||||
#endif
|
||||
|
||||
/* KVM uses PAGE_SIZE in its definition of COALESCED_MMIO_MAX */
|
||||
#define PAGE_SIZE TARGET_PAGE_SIZE
|
||||
|
||||
@ -1708,6 +1704,11 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
|
||||
run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, cpu);
|
||||
}
|
||||
|
||||
void kvm_cpu_clean_state(CPUState *cpu)
|
||||
{
|
||||
cpu->kvm_vcpu_dirty = false;
|
||||
}
|
||||
|
||||
int kvm_cpu_exec(CPUState *cpu)
|
||||
{
|
||||
struct kvm_run *run = cpu->kvm_run;
|
||||
@ -1954,9 +1955,6 @@ int kvm_has_intx_set_mask(void)
|
||||
|
||||
void kvm_setup_guest_memory(void *start, size_t size)
|
||||
{
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
VALGRIND_MAKE_MEM_DEFINED(start, size);
|
||||
#endif
|
||||
if (!kvm_has_sync_mmu()) {
|
||||
int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK);
|
||||
|
||||
|
@ -9,6 +9,9 @@ all:
|
||||
|
||||
.PHONY: all build clean install update
|
||||
|
||||
%.mo: %.po
|
||||
$(call quiet-command, msgfmt -o $@ $<, " GEN $@")
|
||||
|
||||
-include ../config-host.mak
|
||||
include $(SRC_PATH)/rules.mak
|
||||
|
||||
@ -38,9 +41,6 @@ install: $(OBJS)
|
||||
$(INSTALL) -m644 $$obj $(DESTDIR)$(prefix)/share/locale/$$base/LC_MESSAGES/qemu.mo; \
|
||||
done
|
||||
|
||||
%.mo: %.po
|
||||
$(call quiet-command, msgfmt -o $@ $<, " GEN $@")
|
||||
|
||||
$(PO_PATH)/messages.po: $(SRC_PATH)/ui/gtk.c
|
||||
$(call quiet-command, ( cd $(SRC_PATH) && \
|
||||
xgettext -o - --from-code=UTF-8 --foreign-user \
|
||||
|
@ -2580,7 +2580,7 @@ static void x86_cpu_reset(CPUState *s)
|
||||
for (i = 0; i < 8; i++) {
|
||||
env->fptags[i] = 1;
|
||||
}
|
||||
env->fpuc = 0x37f;
|
||||
cpu_set_fpuc(env, 0x37f);
|
||||
|
||||
env->mxcsr = 0x1f80;
|
||||
env->xstate_bv = XSTATE_FP | XSTATE_SSE;
|
||||
|
@ -1251,6 +1251,7 @@ void QEMU_NORETURN raise_interrupt(CPUX86State *nenv, int intno, int is_int,
|
||||
/* cc_helper.c */
|
||||
extern const uint8_t parity_table[256];
|
||||
uint32_t cpu_cc_compute_all(CPUX86State *env1, int op);
|
||||
void update_fp_status(CPUX86State *env);
|
||||
|
||||
static inline uint32_t cpu_compute_eflags(CPUX86State *env)
|
||||
{
|
||||
@ -1286,6 +1287,7 @@ static inline void cpu_load_efer(CPUX86State *env, uint64_t val)
|
||||
|
||||
/* fpu_helper.c */
|
||||
void cpu_set_mxcsr(CPUX86State *env, uint32_t val);
|
||||
void cpu_set_fpuc(CPUX86State *env, uint16_t val);
|
||||
|
||||
/* svm_helper.c */
|
||||
void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
|
||||
|
@ -537,7 +537,7 @@ uint32_t helper_fnstcw(CPUX86State *env)
|
||||
return env->fpuc;
|
||||
}
|
||||
|
||||
static void update_fp_status(CPUX86State *env)
|
||||
void update_fp_status(CPUX86State *env)
|
||||
{
|
||||
int rnd_type;
|
||||
|
||||
@ -575,8 +575,7 @@ static void update_fp_status(CPUX86State *env)
|
||||
|
||||
void helper_fldcw(CPUX86State *env, uint32_t val)
|
||||
{
|
||||
env->fpuc = val;
|
||||
update_fp_status(env);
|
||||
cpu_set_fpuc(env, val);
|
||||
}
|
||||
|
||||
void helper_fclex(CPUX86State *env)
|
||||
@ -595,7 +594,7 @@ void helper_fninit(CPUX86State *env)
|
||||
{
|
||||
env->fpus = 0;
|
||||
env->fpstt = 0;
|
||||
env->fpuc = 0x37f;
|
||||
cpu_set_fpuc(env, 0x37f);
|
||||
env->fptags[0] = 1;
|
||||
env->fptags[1] = 1;
|
||||
env->fptags[2] = 1;
|
||||
@ -1013,11 +1012,11 @@ void helper_fldenv(CPUX86State *env, target_ulong ptr, int data32)
|
||||
int i, fpus, fptag;
|
||||
|
||||
if (data32) {
|
||||
env->fpuc = cpu_lduw_data(env, ptr);
|
||||
cpu_set_fpuc(env, cpu_lduw_data(env, ptr));
|
||||
fpus = cpu_lduw_data(env, ptr + 4);
|
||||
fptag = cpu_lduw_data(env, ptr + 8);
|
||||
} else {
|
||||
env->fpuc = cpu_lduw_data(env, ptr);
|
||||
cpu_set_fpuc(env, cpu_lduw_data(env, ptr));
|
||||
fpus = cpu_lduw_data(env, ptr + 2);
|
||||
fptag = cpu_lduw_data(env, ptr + 4);
|
||||
}
|
||||
@ -1046,7 +1045,7 @@ void helper_fsave(CPUX86State *env, target_ulong ptr, int data32)
|
||||
/* fninit */
|
||||
env->fpus = 0;
|
||||
env->fpstt = 0;
|
||||
env->fpuc = 0x37f;
|
||||
cpu_set_fpuc(env, 0x37f);
|
||||
env->fptags[0] = 1;
|
||||
env->fptags[1] = 1;
|
||||
env->fptags[2] = 1;
|
||||
@ -1157,7 +1156,7 @@ void helper_fxrstor(CPUX86State *env, target_ulong ptr, int data64)
|
||||
raise_exception(env, EXCP0D_GPF);
|
||||
}
|
||||
|
||||
env->fpuc = cpu_lduw_data(env, ptr);
|
||||
cpu_set_fpuc(env, cpu_lduw_data(env, ptr));
|
||||
fpus = cpu_lduw_data(env, ptr + 2);
|
||||
fptag = cpu_lduw_data(env, ptr + 4);
|
||||
env->fpstt = (fpus >> 11) & 7;
|
||||
@ -1257,6 +1256,12 @@ void cpu_set_mxcsr(CPUX86State *env, uint32_t mxcsr)
|
||||
set_flush_to_zero((mxcsr & SSE_FZ) ? 1 : 0, &env->fp_status);
|
||||
}
|
||||
|
||||
void cpu_set_fpuc(CPUX86State *env, uint16_t val)
|
||||
{
|
||||
env->fpuc = val;
|
||||
update_fp_status(env);
|
||||
}
|
||||
|
||||
void helper_ldmxcsr(CPUX86State *env, uint32_t val)
|
||||
{
|
||||
cpu_set_mxcsr(env, val);
|
||||
|
@ -203,7 +203,7 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf);
|
||||
|
||||
case IDX_FP_REGS + 8:
|
||||
env->fpuc = ldl_p(mem_buf);
|
||||
cpu_set_fpuc(env, ldl_p(mem_buf));
|
||||
return 4;
|
||||
case IDX_FP_REGS + 9:
|
||||
tmp = ldl_p(mem_buf);
|
||||
|
@ -315,13 +315,13 @@ static int cpu_post_load(void *opaque, int version_id)
|
||||
env->hflags &= ~HF_CPL_MASK;
|
||||
env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
|
||||
|
||||
/* XXX: restore FPU round state */
|
||||
env->fpstt = (env->fpus_vmstate >> 11) & 7;
|
||||
env->fpus = env->fpus_vmstate & ~0x3800;
|
||||
env->fptag_vmstate ^= 0xff;
|
||||
for(i = 0; i < 8; i++) {
|
||||
env->fptags[i] = (env->fptag_vmstate >> i) & 1;
|
||||
}
|
||||
update_fp_status(env);
|
||||
|
||||
cpu_breakpoint_remove_all(cs, BP_CPU);
|
||||
cpu_watchpoint_remove_all(cs, BP_CPU);
|
||||
|
@ -1369,3 +1369,6 @@ mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
|
||||
# target-s390x/kvm.c
|
||||
kvm_enable_cmma(int rc) "CMMA: enabling with result code %d"
|
||||
kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
|
||||
|
||||
# hw/dma/i8257.c
|
||||
i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
|
||||
|
Loading…
Reference in New Issue
Block a user