summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure3
-rw-r--r--cpus.c9
-rw-r--r--hw/char/serial.c6
-rw-r--r--hw/dma/i8257.c4
-rw-r--r--hw/i386/kvm/clock.c53
-rw-r--r--hw/i386/kvm/i8254.c3
-rw-r--r--hw/i386/kvmvapic.c11
-rw-r--r--include/sysemu/cpus.h1
-rw-r--r--include/sysemu/kvm.h8
-rw-r--r--kvm-all.c12
-rw-r--r--po/Makefile6
-rw-r--r--target-i386/cpu.c2
-rw-r--r--target-i386/cpu.h2
-rw-r--r--target-i386/fpu_helper.c21
-rw-r--r--target-i386/gdbstub.c2
-rw-r--r--target-i386/machine.c2
-rw-r--r--trace-events3
17 files changed, 117 insertions, 31 deletions
diff --git a/configure b/configure
index 862f6d27e3..a2c0f2a02a 100755
--- a/configure
+++ b/configure
@@ -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;
}
diff --git a/cpus.c b/cpus.c
index 2a0e133d39..0c33458bb1 100644
--- a/cpus.c
+++ b/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;
diff --git a/hw/char/serial.c b/hw/char/serial.c
index a668249049..ebcacdc872 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -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;
}
diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
index dd370ed7e5..a414029bea 100644
--- a/hw/dma/i8257.c
+++ b/hw/dma/i8257.c
@@ -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;
}
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 07b9c0e581..1ac60d6cdd 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -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));
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 59373aaade..472af811cd 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -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;
}
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 2cca7a44f4..2dc362b88f 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -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;
}
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 4f790810bf..3f162a9e08 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -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);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index d2000af9c3..77ee240875 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -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);
diff --git a/kvm-all.c b/kvm-all.c
index 8b9e66d42d..4afcd0551b 100644
--- a/kvm-all.c
+++ b/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);
diff --git a/po/Makefile b/po/Makefile
index 1ab241a5b7..b271f79ba2 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -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 \
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 2406c727a5..e7bf9de80f 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -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;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 71b505f56c..2968749578 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -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,
diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 1b2900d5d2..1d4eee3974 100644
--- a/target-i386/fpu_helper.c
+++ b/target-i386/fpu_helper.c
@@ -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);
diff --git a/target-i386/gdbstub.c b/target-i386/gdbstub.c
index 19fe9adc3f..ff99cfb007 100644
--- a/target-i386/gdbstub.c
+++ b/target-i386/gdbstub.c
@@ -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);
diff --git a/target-i386/machine.c b/target-i386/machine.c
index fb890654b1..0dd49f0005 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -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);
diff --git a/trace-events b/trace-events
index 9153f983f4..011d1059f8 100644
--- a/trace-events
+++ b/trace-events
@@ -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"