History

Merge tag 'kvm-x86-xen-6.8' of https://github.com/kvm-x86/linux into HEAD

KVM Xen change for 6.8: To workaround Xen guests that don't expect Xen PV clocks to be marked as being based on a stable TSC, add a Xen config knob to allow userspace to opt out of KVM setting the "TSC stable" bit in Xen PV clocks. Note, the "TSC stable" bit was added to the PVCLOCK ABI by KVM without an ack from Xen, i.e. KVM isn't entirely blameless for the buggy guest behavior.

Paolo Bonzini committed 2 years ago

Commit 3115d2d2 parents 8c9244a 6d722834 files · +38 −6Browse files

Unified · Split

4 files
  1. Documentation/virt/kvm/api.rst +6 −0
  2. arch/x86/kvm/x86.c +23 −5
  3. arch/x86/kvm/xen.c +8 −1
  4. include/uapi/linux/kvm.h +1 −0
Documentation/virt/kvm/api.rst+6−0
@@ -8550,6 +8550,7 @@ PVHVM guests. Valid flags are:: · 8549 unmodified lines
8550 #define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)8550 #define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
8551 #define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)8551 #define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
8552 #define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)8552 #define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
8553 #define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
8553 8554
8554The KVM_XEN_HVM_CONFIG_HYPERCALL_MSR flag indicates that the KVM_XEN_HVM_CONFIG8555The KVM_XEN_HVM_CONFIG_HYPERCALL_MSR flag indicates that the KVM_XEN_HVM_CONFIG
8555ioctl is available, for the guest to set its hypercall page.8556ioctl is available, for the guest to set its hypercall page.
@@ -8593,6 +8594,11 @@ behave more correctly, not using the XEN_RUNSTATE_UPDATE flag until/unless · 37 unmodified lines
8593specifically enabled (by the guest making the hypercall, causing the VMM8594specifically enabled (by the guest making the hypercall, causing the VMM
8594to enable the KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG attribute).8595to enable the KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG attribute).
8595 8596
8597The KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE flag indicates that KVM supports
8598clearing the PVCLOCK_TSC_STABLE_BIT flag in Xen pvclock sources. This will be
8599done when the KVM_CAP_XEN_HVM ioctl sets the
8600KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE flag.
8601
85968.31 KVM_CAP_PPC_MULTITCE86028.31 KVM_CAP_PPC_MULTITCE
8597-------------------------8603-------------------------
8598 8604
arch/x86/kvm/x86.c+23−5
@@ -3110,7 +3110,8 @@ u64 get_kvmclock_ns(struct kvm *kvm) · 3109 unmodified lines
3110 3110
3111static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,3111static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,
3112 struct gfn_to_pfn_cache *gpc,3112 struct gfn_to_pfn_cache *gpc,
3113 unsigned int offset)3113 unsigned int offset,
3114 bool force_tsc_unstable)
3114{3115{
3115 struct kvm_vcpu_arch *vcpu = &v->arch;3116 struct kvm_vcpu_arch *vcpu = &v->arch;
3116 struct pvclock_vcpu_time_info *guest_hv_clock;3117 struct pvclock_vcpu_time_info *guest_hv_clock;
@@ -3147,6 +3148,10 @@ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v, · 30 unmodified lines
3147 }3148 }
3148 3149
3149 memcpy(guest_hv_clock, &vcpu->hv_clock, sizeof(*guest_hv_clock));3150 memcpy(guest_hv_clock, &vcpu->hv_clock, sizeof(*guest_hv_clock));
3151
3152 if (force_tsc_unstable)
3153 guest_hv_clock->flags &= ~PVCLOCK_TSC_STABLE_BIT;
3154
3150 smp_wmb();3155 smp_wmb();
3151 3156
3152 guest_hv_clock->version = ++vcpu->hv_clock.version;3157 guest_hv_clock->version = ++vcpu->hv_clock.version;
@@ -3167,6 +3172,16 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 14 unmodified lines
3167 u64 tsc_timestamp, host_tsc;3172 u64 tsc_timestamp, host_tsc;
3168 u8 pvclock_flags;3173 u8 pvclock_flags;
3169 bool use_master_clock;3174 bool use_master_clock;
3175#ifdef CONFIG_KVM_XEN
3176 /*
3177 * For Xen guests we may need to override PVCLOCK_TSC_STABLE_BIT as unless
3178 * explicitly told to use TSC as its clocksource Xen will not set this bit.
3179 * This default behaviour led to bugs in some guest kernels which cause
3180 * problems if they observe PVCLOCK_TSC_STABLE_BIT in the pvclock flags.
3181 */
3182 bool xen_pvclock_tsc_unstable =
3183 ka->xen_hvm_config.flags & KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE;
3184#endif
3170 3185
3171 kernel_ns = 0;3186 kernel_ns = 0;
3172 host_tsc = 0;3187 host_tsc = 0;
@@ -3245,13 +3260,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 72 unmodified lines
3245 vcpu->hv_clock.flags = pvclock_flags;3260 vcpu->hv_clock.flags = pvclock_flags;
3246 3261
3247 if (vcpu->pv_time.active)3262 if (vcpu->pv_time.active)
3248 kvm_setup_guest_pvclock(v, &vcpu->pv_time, 0);3263 kvm_setup_guest_pvclock(v, &vcpu->pv_time, 0, false);
3249#ifdef CONFIG_KVM_XEN3264#ifdef CONFIG_KVM_XEN
3250 if (vcpu->xen.vcpu_info_cache.active)3265 if (vcpu->xen.vcpu_info_cache.active)
3251 kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_info_cache,3266 kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_info_cache,
3252 offsetof(struct compat_vcpu_info, time));3267 offsetof(struct compat_vcpu_info, time),
3268 xen_pvclock_tsc_unstable);
3253 if (vcpu->xen.vcpu_time_info_cache.active)3269 if (vcpu->xen.vcpu_time_info_cache.active)
3254 kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_time_info_cache, 0);3270 kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_time_info_cache, 0,
3271 xen_pvclock_tsc_unstable);
3255#endif3272#endif
3256 kvm_hv_setup_tsc_page(v->kvm, &vcpu->hv_clock);3273 kvm_hv_setup_tsc_page(v->kvm, &vcpu->hv_clock);
3257 return 0;3274 return 0;
@@ -4660,7 +4677,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 1402 unmodified lines
4660 KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL |4677 KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL |
4661 KVM_XEN_HVM_CONFIG_SHARED_INFO |4678 KVM_XEN_HVM_CONFIG_SHARED_INFO |
4662 KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL |4679 KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL |
4663 KVM_XEN_HVM_CONFIG_EVTCHN_SEND;4680 KVM_XEN_HVM_CONFIG_EVTCHN_SEND |
4681 KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE;
4664 if (sched_info_on())4682 if (sched_info_on())
4665 r |= KVM_XEN_HVM_CONFIG_RUNSTATE |4683 r |= KVM_XEN_HVM_CONFIG_RUNSTATE |
4666 KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG;4684 KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG;
arch/x86/kvm/xen.c+8−1
@@ -1162,7 +1162,9 @@ int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc) · 1161 unmodified lines
1162{1162{
1163 /* Only some feature flags need to be *enabled* by userspace */1163 /* Only some feature flags need to be *enabled* by userspace */
1164 u32 permitted_flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL |1164 u32 permitted_flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL |
1165 KVM_XEN_HVM_CONFIG_EVTCHN_SEND;1165 KVM_XEN_HVM_CONFIG_EVTCHN_SEND |
1166 KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE;
1167 u32 old_flags;
1166 1168
1167 if (xhc->flags & ~permitted_flags)1169 if (xhc->flags & ~permitted_flags)
1168 return -EINVAL;1170 return -EINVAL;
@@ -1183,9 +1185,14 @@ int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc) · 14 unmodified lines
1183 else if (!xhc->msr && kvm->arch.xen_hvm_config.msr)1185 else if (!xhc->msr && kvm->arch.xen_hvm_config.msr)
1184 static_branch_slow_dec_deferred(&kvm_xen_enabled);1186 static_branch_slow_dec_deferred(&kvm_xen_enabled);
1185 1187
1188 old_flags = kvm->arch.xen_hvm_config.flags;
1186 memcpy(&kvm->arch.xen_hvm_config, xhc, sizeof(*xhc));1189 memcpy(&kvm->arch.xen_hvm_config, xhc, sizeof(*xhc));
1187 1190
1188 mutex_unlock(&kvm->arch.xen.xen_lock);1191 mutex_unlock(&kvm->arch.xen.xen_lock);
1192
1193 if ((old_flags ^ xhc->flags) & KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE)
1194 kvm_make_all_cpus_request(kvm, KVM_REQ_CLOCK_UPDATE);
1195
1189 return 0;1196 return 0;
1190}1197}
1191 1198
include/uapi/linux/kvm.h+1−0
@@ -1245,6 +1245,7 @@ struct kvm_x86_mce { · 1244 unmodified lines
1245#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)1245#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
1246#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)1246#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
1247#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)1247#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
1248#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
1248 1249
1249struct kvm_xen_hvm_config {1250struct kvm_xen_hvm_config {
1250 __u32 flags;1251 __u32 flags;