summary refs log tree commit diff stats
path: root/hw/timer/hpet.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-01-16 15:45:15 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-16 15:45:15 +0000
commitc1d5b9add7b04661bedef9a3379a8b82547b53db (patch)
tree7c064b14e4a3645aedbd7d7f0009b9ee71ad9952 /hw/timer/hpet.c
parentaae39d24a387a273deab3eb930dbf730aa379e22 (diff)
parentb5976c2e46e86b36b01d8ac380a182e22209a7cd (diff)
downloadfocaccia-qemu-c1d5b9add7b04661bedef9a3379a8b82547b53db.tar.gz
focaccia-qemu-c1d5b9add7b04661bedef9a3379a8b82547b53db.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* QemuMutex tracing improvements (Alex)
* ram_addr_t optimization (David)
* SCSI fixes (Fam, Stefan, me)
* do {} while (0) fixes (Eric)
* KVM fix for PMU (Jan)
* memory leak fixes from ASAN (Marc-André)
* migration fix for HPET, icount, loadvm (Maria, Pavel)
* hflags fixes (me, Tao)
* block/iscsi uninitialized variable (Peter L.)
* full support for GMainContexts in character devices (Peter Xu)
* more boot-serial-test (Thomas)
* Memory leak fix (Zhecheng)

# gpg: Signature made Tue 16 Jan 2018 14:15:45 GMT
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (51 commits)
  scripts/analyse-locks-simpletrace.py: script to analyse lock times
  util/qemu-thread-*: add qemu_lock, locked and unlock trace events
  cpu: flush TB cache when loading VMState
  block/iscsi: fix initialization of iTask in iscsi_co_get_block_status
  find_ram_offset: Align ram_addr_t allocation on long boundaries
  find_ram_offset: Add comments and tracing
  cpu_physical_memory_sync_dirty_bitmap: Another alignment fix
  checkpatch: Enforce proper do/while (0) style
  maint: Fix macros with broken 'do/while(0); ' usage
  tests: Avoid 'do/while(false); ' in vhost-user-bridge
  chardev: Clean up previous patch indentation
  chardev: Use goto/label instead of do/break/while(0)
  mips: Tweak location of ';' in macros
  net: Drop unusual use of do { } while (0);
  irq: fix memory leak
  cpus: unify qemu_*_wait_io_event
  icount: fixed saving/restoring of icount warp timers
  scripts/qemu-gdb/timers.py: new helper to dump timer state
  scripts/qemu-gdb: add simple tcg lock status helper
  target-i386: update hflags on Hypervisor.framework
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/timer/hpet.c')
-rw-r--r--hw/timer/hpet.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 577371bc6d..d97436bc7b 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -70,6 +70,7 @@ typedef struct HPETState {
 
     MemoryRegion iomem;
     uint64_t hpet_offset;
+    bool hpet_offset_saved;
     qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
     uint32_t flags;
     uint8_t rtc_irq_level;
@@ -221,7 +222,9 @@ static int hpet_pre_save(void *opaque)
     HPETState *s = opaque;
 
     /* save current counter value */
-    s->hpet_counter = hpet_get_ticks(s);
+    if (hpet_enabled(s)) {
+        s->hpet_counter = hpet_get_ticks(s);
+    }
 
     return 0;
 }
@@ -252,7 +255,10 @@ static int hpet_post_load(void *opaque, int version_id)
     HPETState *s = opaque;
 
     /* Recalculate the offset between the main counter and guest time */
-    s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    if (!s->hpet_offset_saved) {
+        s->hpet_offset = ticks_to_ns(s->hpet_counter)
+                        - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    }
 
     /* Push number of timers into capability returned via HPET_ID */
     s->capability &= ~HPET_ID_NUM_TIM_MASK;
@@ -267,6 +273,13 @@ static int hpet_post_load(void *opaque, int version_id)
     return 0;
 }
 
+static bool hpet_offset_needed(void *opaque)
+{
+    HPETState *s = opaque;
+
+    return hpet_enabled(s) && s->hpet_offset_saved;
+}
+
 static bool hpet_rtc_irq_level_needed(void *opaque)
 {
     HPETState *s = opaque;
@@ -285,6 +298,17 @@ static const VMStateDescription vmstate_hpet_rtc_irq_level = {
     }
 };
 
+static const VMStateDescription vmstate_hpet_offset = {
+    .name = "hpet/offset",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = hpet_offset_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64(hpet_offset, HPETState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_hpet_timer = {
     .name = "hpet_timer",
     .version_id = 1,
@@ -320,6 +344,7 @@ static const VMStateDescription vmstate_hpet = {
     },
     .subsections = (const VMStateDescription*[]) {
         &vmstate_hpet_rtc_irq_level,
+        &vmstate_hpet_offset,
         NULL
     }
 };
@@ -762,6 +787,7 @@ static Property hpet_device_properties[] = {
     DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
     DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
     DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
+    DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true),
     DEFINE_PROP_END_OF_LIST(),
 };