Commit e3fd9a93 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Radim Krčmář

kvm: kvmclock: let KVM_GET_CLOCK return whether the master clock is in use

Userspace can read the exact value of kvmclock by reading the TSC
and fetching the timekeeping parameters out of guest memory.  This
however is brittle and not necessary anymore with KVM 4.11.  Provide
a mechanism that lets userspace know if the new KVM_GET_CLOCK
semantics are in effect, and---since we are at it---if the clock
is stable across all VCPUs.

Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
parent 1650b4eb
...@@ -777,6 +777,17 @@ Gets the current timestamp of kvmclock as seen by the current guest. In ...@@ -777,6 +777,17 @@ Gets the current timestamp of kvmclock as seen by the current guest. In
conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios
such as migration. such as migration.
When KVM_CAP_ADJUST_CLOCK is passed to KVM_CHECK_EXTENSION, it returns the
set of bits that KVM can return in struct kvm_clock_data's flag member.
The only flag defined now is KVM_CLOCK_TSC_STABLE. If set, the returned
value is the exact kvmclock value seen by all VCPUs at the instant
when KVM_GET_CLOCK was called. If clear, the returned value is simply
CLOCK_MONOTONIC plus a constant offset; the offset can be modified
with KVM_SET_CLOCK. KVM will try to make all VCPUs follow this clock,
but the exact value read by each VCPU could differ, because the host
TSC is not stable.
struct kvm_clock_data { struct kvm_clock_data {
__u64 clock; /* kvmclock current value */ __u64 clock; /* kvmclock current value */
__u32 flags; __u32 flags;
......
...@@ -2610,7 +2610,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) ...@@ -2610,7 +2610,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_PIT_STATE2: case KVM_CAP_PIT_STATE2:
case KVM_CAP_SET_IDENTITY_MAP_ADDR: case KVM_CAP_SET_IDENTITY_MAP_ADDR:
case KVM_CAP_XEN_HVM: case KVM_CAP_XEN_HVM:
case KVM_CAP_ADJUST_CLOCK:
case KVM_CAP_VCPU_EVENTS: case KVM_CAP_VCPU_EVENTS:
case KVM_CAP_HYPERV: case KVM_CAP_HYPERV:
case KVM_CAP_HYPERV_VAPIC: case KVM_CAP_HYPERV_VAPIC:
...@@ -2637,6 +2636,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) ...@@ -2637,6 +2636,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
#endif #endif
r = 1; r = 1;
break; break;
case KVM_CAP_ADJUST_CLOCK:
r = KVM_CLOCK_TSC_STABLE;
break;
case KVM_CAP_X86_SMM: case KVM_CAP_X86_SMM:
/* SMBASE is usually relocated above 1M on modern chipsets, /* SMBASE is usually relocated above 1M on modern chipsets,
* and SMM handlers might indeed rely on 4G segment limits, * and SMM handlers might indeed rely on 4G segment limits,
...@@ -4117,9 +4119,11 @@ long kvm_arch_vm_ioctl(struct file *filp, ...@@ -4117,9 +4119,11 @@ long kvm_arch_vm_ioctl(struct file *filp,
struct kvm_clock_data user_ns; struct kvm_clock_data user_ns;
u64 now_ns; u64 now_ns;
now_ns = get_kvmclock_ns(kvm); local_irq_disable();
now_ns = __get_kvmclock_ns(kvm);
user_ns.clock = now_ns; user_ns.clock = now_ns;
user_ns.flags = 0; user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0;
local_irq_enable();
memset(&user_ns.pad, 0, sizeof(user_ns.pad)); memset(&user_ns.pad, 0, sizeof(user_ns.pad));
r = -EFAULT; r = -EFAULT;
......
...@@ -972,12 +972,19 @@ struct kvm_irqfd { ...@@ -972,12 +972,19 @@ struct kvm_irqfd {
__u8 pad[16]; __u8 pad[16];
}; };
/* For KVM_CAP_ADJUST_CLOCK */
/* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags. */
#define KVM_CLOCK_TSC_STABLE 2
struct kvm_clock_data { struct kvm_clock_data {
__u64 clock; __u64 clock;
__u32 flags; __u32 flags;
__u32 pad[9]; __u32 pad[9];
}; };
/* For KVM_CAP_SW_TLB */
#define KVM_MMU_FSL_BOOKE_NOHV 0 #define KVM_MMU_FSL_BOOKE_NOHV 0
#define KVM_MMU_FSL_BOOKE_HV 1 #define KVM_MMU_FSL_BOOKE_HV 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment