diff --git a/configure b/configure index 862f6d27e364..a2c0f2a02a43 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 -#include int main(void) { return 0; } diff --git a/cpus.c b/cpus.c index 2a0e133d39ae..0c33458bb18e 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 a668249049ea..ebcacdc872b7 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 dd370ed7e56d..a414029beaec 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 07b9c0e58139..1ac60d6cdd86 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 59373aaade36..472af811cdff 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 2cca7a44f45b..2dc362b88f1c 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 4f790810bfea..3f162a9e083c 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 d2000af9c330..77ee24087598 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 8b9e66d42dfb..4afcd0551bb2 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -44,10 +44,6 @@ #include #endif -#ifdef CONFIG_VALGRIND_H -#include -#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 1ab241a5b7f2..b271f79ba2aa 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 2406c727a5d3..e7bf9de80fa1 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 71b505f56c0c..2968749578c9 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 1b2900d5d2f0..1d4eee3974fe 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 19fe9adc3f3c..ff99cfb0078f 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 fb890654b134..0dd49f000580 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 9153f983f486..011d1059f814 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"