Commit 81ab11a7 authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents da1c4ec8 541be927
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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;
}
+2 −2
Original line number Diff line number Diff line
@@ -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;
}

+53 −0
Original line number Diff line number Diff line
@@ -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));
Loading