diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/char/serial.c | 6 | ||||
| -rw-r--r-- | hw/dma/i8257.c | 4 | ||||
| -rw-r--r-- | hw/i386/kvm/clock.c | 53 | ||||
| -rw-r--r-- | hw/i386/kvm/i8254.c | 3 | ||||
| -rw-r--r-- | hw/i386/kvmvapic.c | 11 | ||||
| -rw-r--r-- | hw/usb/hcd-ohci.c | 21 |
6 files changed, 81 insertions, 17 deletions
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/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 7ea871ddf2..9a84eb6950 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -723,11 +723,13 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, trace_usb_ohci_iso_td_head( ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK, iso_td.flags, iso_td.bp, iso_td.next, iso_td.be, - iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3], - iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7], - ohci->frame_number, starting_frame, - frame_count, relative_frame_number, - OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC)); + ohci->frame_number, starting_frame, + frame_count, relative_frame_number); + trace_usb_ohci_iso_td_head_offset( + iso_td.offset[0], iso_td.offset[1], + iso_td.offset[2], iso_td.offset[3], + iso_td.offset[4], iso_td.offset[5], + iso_td.offset[6], iso_td.offset[7]); if (relative_frame_number < 0) { trace_usb_ohci_iso_td_relative_frame_number_neg(relative_frame_number); @@ -1199,13 +1201,14 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) } while ((ed.head & OHCI_DPTR_MASK) != ed.tail) { - trace_usb_ohci_ed_pkt(cur, + trace_usb_ohci_ed_pkt(cur, (ed.head & OHCI_ED_H) != 0, + (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK, + ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK); + trace_usb_ohci_ed_pkt_flags( OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN), OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0, (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0, - OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0, - (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK, - ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK); + OHCI_BM(ed.flags, ED_MPS)); active = 1; |