From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: aliguori@us.ibm.com
Subject: [Qemu-devel] [PATCH stable-1.1 13/26] kvm: i8254: Fix conversion of in-kernel to userspace state
Date: Fri, 22 Jun 2012 19:33:17 -0500 [thread overview]
Message-ID: <1340411610-22596-14-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1340411610-22596-1-git-send-email-mdroth@linux.vnet.ibm.com>
From: Jan Kiszka <jan.kiszka@siemens.com>
Due to a offset between the clock used to generate the in-kernel
count_load_time (CLOCK_MONOTONIC) and the clock used for processing this
in userspace (vm_clock), reading back the output of PIT channel 2 via
port 0x61 was broken. One use cases that suffered from it was the CPU
frequency calibration of SeaBIOS, which also affected IDE/AHCI timeouts.
This fixes it by calibrating the offset between both clocks on
kvm_pit_get and adjusting the kernel value before saving it in the
userspace state. As the calibration only works while the vm_clock is
running, we cache the in-kernel state across stopped phases.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
hw/kvm/i8254.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/hw/kvm/i8254.c b/hw/kvm/i8254.c
index bb5fe07..c5d3711 100644
--- a/hw/kvm/i8254.c
+++ b/hw/kvm/i8254.c
@@ -23,31 +23,63 @@
* THE SOFTWARE.
*/
#include "qemu-timer.h"
+#include "sysemu.h"
#include "hw/i8254.h"
#include "hw/i8254_internal.h"
#include "kvm.h"
#define KVM_PIT_REINJECT_BIT 0
+#define CALIBRATION_ROUNDS 3
+
typedef struct KVMPITState {
PITCommonState pit;
LostTickPolicy lost_tick_policy;
+ bool state_valid;
} KVMPITState;
-static void kvm_pit_get(PITCommonState *s)
+static int64_t abs64(int64_t v)
{
+ return v < 0 ? -v : v;
+}
+
+static void kvm_pit_get(PITCommonState *pit)
+{
+ KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit);
struct kvm_pit_state2 kpit;
struct kvm_pit_channel_state *kchan;
struct PITChannelState *sc;
+ int64_t offset, clock_offset;
+ struct timespec ts;
int i, ret;
+ if (s->state_valid) {
+ return;
+ }
+
+ /*
+ * Measure the delta between CLOCK_MONOTONIC, the base used for
+ * kvm_pit_channel_state::count_load_time, and vm_clock. Take the
+ * minimum of several samples to filter out scheduling noise.
+ */
+ clock_offset = INT64_MAX;
+ for (i = 0; i < CALIBRATION_ROUNDS; i++) {
+ offset = qemu_get_clock_ns(vm_clock);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ offset -= ts.tv_nsec;
+ offset -= (int64_t)ts.tv_sec * 1000000000;
+ if (abs64(offset) < abs64(clock_offset)) {
+ clock_offset = offset;
+ }
+ }
+
if (kvm_has_pit_state2()) {
ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit);
if (ret < 0) {
fprintf(stderr, "KVM_GET_PIT2 failed: %s\n", strerror(ret));
abort();
}
- s->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY;
+ pit->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY;
} else {
/*
* kvm_pit_state2 is superset of kvm_pit_state struct,
@@ -61,7 +93,7 @@ static void kvm_pit_get(PITCommonState *s)
}
for (i = 0; i < 3; i++) {
kchan = &kpit.channels[i];
- sc = &s->channels[i];
+ sc = &pit->channels[i];
sc->count = kchan->count;
sc->latched_count = kchan->latched_count;
sc->count_latched = kchan->count_latched;
@@ -74,10 +106,10 @@ static void kvm_pit_get(PITCommonState *s)
sc->mode = kchan->mode;
sc->bcd = kchan->bcd;
sc->gate = kchan->gate;
- sc->count_load_time = kchan->count_load_time;
+ sc->count_load_time = kchan->count_load_time + clock_offset;
}
- sc = &s->channels[0];
+ sc = &pit->channels[0];
sc->next_transition_time =
pit_get_next_transition_time(sc, sc->count_load_time);
}
@@ -173,6 +205,19 @@ static void kvm_pit_irq_control(void *opaque, int n, int enable)
kvm_pit_put(pit);
}
+static void kvm_pit_vm_state_change(void *opaque, int running,
+ RunState state)
+{
+ KVMPITState *s = opaque;
+
+ if (running) {
+ s->state_valid = false;
+ } else {
+ kvm_pit_get(&s->pit);
+ s->state_valid = true;
+ }
+}
+
static int kvm_pit_initfn(PITCommonState *pit)
{
KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit);
@@ -215,6 +260,8 @@ static int kvm_pit_initfn(PITCommonState *pit)
qdev_init_gpio_in(&pit->dev.qdev, kvm_pit_irq_control, 1);
+ qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);
+
return 0;
}
--
1.7.4.1
next prev parent reply other threads:[~2012-06-23 0:34 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-23 0:33 [Qemu-devel] [PATCH stable-1.1 00/26] Initial tree and candidates for stable-1.1 Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 01/26] virtio-blk: Fix geometry sector calculation Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 02/26] target-xtensa: flush TLB page for new MMU mapping Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 03/26] target-xtensa: update EXCVADDR in case of page table lookup Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 04/26] target-xtensa: extract TLB entry setting method Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 05/26] target-xtensa: update autorefill TLB entries conditionally Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 06/26] target-xtensa: control page table lookup explicitly Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 07/26] target-xtensa: add MMU pagewalking tests Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 08/26] exec: fix TB invalidation after breakpoint insertion/deletion Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 09/26] target-xtensa: fix CCOUNT for conditional branches Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 10/26] trace/simple.c: fix deprecated glib2 interface Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 11/26] configure: report missing libraries for virtfs Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 12/26] kvm/apic: correct short memset Michael Roth
2012-06-23 0:33 ` Michael Roth [this message]
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 14/26] qcow2: Silence false warning Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 15/26] monitor: Fix memory leak with readline completion Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 16/26] configure: Fix build for some versions of glibc (9pfs) Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 17/26] rtl8139: honor RxOverflow flag in can_receive method Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 18/26] ahci: Fix reset of MSI function Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 19/26] intel-hda: " Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 20/26] qdev: release parent properties on dc->init failure Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 21/26] pci_bridge_dev: fix error path in pci_bridge_dev_initfn() Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 22/26] qcow2: fix endianness conversion Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 23/26] Prevent disk data loss when closing qemu Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 24/26] qcow2: fix autoclear image header update Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 25/26] fdc: fix implied seek while there is no media in drive Michael Roth
2012-06-23 0:33 ` [Qemu-devel] [PATCH stable-1.1 26/26] build: install qmp-commands.txt Michael Roth
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1340411610-22596-14-git-send-email-mdroth@linux.vnet.ibm.com \
--to=mdroth@linux.vnet.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).