aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeth Kon <eak@us.ibm.com>2009-07-07 11:50:37 -0400
committerAvi Kivity <avi@redhat.com>2009-07-12 16:37:41 +0300
commitf69b3e23bfbfba15ec42c511617a521e90d1e639 (patch)
treef907ad79a2290b4d45ac94a07383566359101009 /qemu-kvm-x86.c
parentAdvertise HPET in ACPI HPET table (diff)
downloadqemu-kvm-f69b3e23bfbfba15ec42c511617a521e90d1e639.tar.gz
qemu-kvm-f69b3e23bfbfba15ec42c511617a521e90d1e639.tar.bz2
qemu-kvm-f69b3e23bfbfba15ec42c511617a521e90d1e639.zip
HPET support with kvm
The big change here is handling of enabling/disabling of hpet legacy mode. When hpet enters legacy mode, the spec says that the pit stops generating interrupts. In practice, we want to stop the pit periodic timer from running because it is wasteful in a virtual environment. We also have to worry about the hpet leaving legacy mode (which, at least in linux, happens only during a shutdown or crash). At this point, according to the hpet spec, PIT interrupts need to be reenabled. For us, it means the PIT timer needs to be restarted. This patch handles this situation better than the earlier versions by coming closer to just disabling PIT interrupts. It allows the PIT state to change if the OS modifies it, even while PIT is disabled, but does not allow a pit timer to start. Then if HPET legacy mode is disabled, whatever the PIT state is at that point, the PIT timer is restarted accordingly. [avi: adjust to kernel header changes] Signed-off-by: Beth Kon <eak@us.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'qemu-kvm-x86.c')
-rw-r--r--qemu-kvm-x86.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 67aca3288..daf60b6bf 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -294,8 +294,46 @@ int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s)
return r;
}
+#ifdef KVM_CAP_PIT_STATE2
+int kvm_get_pit2(kvm_context_t kvm, struct kvm_pit_state2 *ps2)
+{
+ int r;
+ if (!kvm->pit_in_kernel)
+ return 0;
+ r = ioctl(kvm->vm_fd, KVM_GET_PIT2, ps2);
+ if (r == -1) {
+ r = -errno;
+ perror("kvm_get_pit2");
+ }
+ return r;
+}
+
+int kvm_set_pit2(kvm_context_t kvm, struct kvm_pit_state2 *ps2)
+{
+ int r;
+ if (!kvm->pit_in_kernel)
+ return 0;
+ r = ioctl(kvm->vm_fd, KVM_SET_PIT2, ps2);
+ if (r == -1) {
+ r = -errno;
+ perror("kvm_set_pit2");
+ }
+ return r;
+}
+
+#endif
#endif
+int kvm_has_pit_state2(kvm_context_t kvm)
+{
+ int r = 0;
+
+#ifdef KVM_CAP_PIT_STATE2
+ r = kvm_check_extension(kvm, KVM_CAP_PIT_STATE2);
+#endif
+ return r;
+}
+
void kvm_show_code(kvm_vcpu_context_t vcpu)
{
#define SHOW_CODE_LEN 50