Skip to content

Commit 3115d2d

Browse files
committed
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.
2 parents 8c9244a + 6d72283 commit 3115d2d

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8550,6 +8550,7 @@ PVHVM guests. Valid flags are::
85508550
#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
85518551
#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
85528552
#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
8553+
#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
85538554

85548555
The KVM_XEN_HVM_CONFIG_HYPERCALL_MSR flag indicates that the KVM_XEN_HVM_CONFIG
85558556
ioctl 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
85938594
specifically enabled (by the guest making the hypercall, causing the VMM
85948595
to enable the KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG attribute).
85958596

8597+
The KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE flag indicates that KVM supports
8598+
clearing the PVCLOCK_TSC_STABLE_BIT flag in Xen pvclock sources. This will be
8599+
done when the KVM_CAP_XEN_HVM ioctl sets the
8600+
KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE flag.
8601+
85968602
8.31 KVM_CAP_PPC_MULTITCE
85978603
-------------------------
85988604

arch/x86/kvm/x86.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3110,7 +3110,8 @@ u64 get_kvmclock_ns(struct kvm *kvm)
31103110

31113111
static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,
31123112
struct gfn_to_pfn_cache *gpc,
3113-
unsigned int offset)
3113+
unsigned int offset,
3114+
bool force_tsc_unstable)
31143115
{
31153116
struct kvm_vcpu_arch *vcpu = &v->arch;
31163117
struct pvclock_vcpu_time_info *guest_hv_clock;
@@ -3147,6 +3148,10 @@ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,
31473148
}
31483149

31493150
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+
31503155
smp_wmb();
31513156

31523157
guest_hv_clock->version = ++vcpu->hv_clock.version;
@@ -3167,6 +3172,16 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
31673172
u64 tsc_timestamp, host_tsc;
31683173
u8 pvclock_flags;
31693174
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
31703185

31713186
kernel_ns = 0;
31723187
host_tsc = 0;
@@ -3245,13 +3260,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
32453260
vcpu->hv_clock.flags = pvclock_flags;
32463261

32473262
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);
32493264
#ifdef CONFIG_KVM_XEN
32503265
if (vcpu->xen.vcpu_info_cache.active)
32513266
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);
32533269
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);
32553272
#endif
32563273
kvm_hv_setup_tsc_page(v->kvm, &vcpu->hv_clock);
32573274
return 0;
@@ -4660,7 +4677,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
46604677
KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL |
46614678
KVM_XEN_HVM_CONFIG_SHARED_INFO |
46624679
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;
46644682
if (sched_info_on())
46654683
r |= KVM_XEN_HVM_CONFIG_RUNSTATE |
46664684
KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG;

arch/x86/kvm/xen.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,9 @@ int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc)
11621162
{
11631163
/* Only some feature flags need to be *enabled* by userspace */
11641164
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;
11661168

11671169
if (xhc->flags & ~permitted_flags)
11681170
return -EINVAL;
@@ -1183,9 +1185,14 @@ int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc)
11831185
else if (!xhc->msr && kvm->arch.xen_hvm_config.msr)
11841186
static_branch_slow_dec_deferred(&kvm_xen_enabled);
11851187

1188+
old_flags = kvm->arch.xen_hvm_config.flags;
11861189
memcpy(&kvm->arch.xen_hvm_config, xhc, sizeof(*xhc));
11871190

11881191
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+
11891196
return 0;
11901197
}
11911198

include/uapi/linux/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,7 @@ struct kvm_x86_mce {
12451245
#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
12461246
#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
12471247
#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
1248+
#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
12481249

12491250
struct kvm_xen_hvm_config {
12501251
__u32 flags;

0 commit comments

Comments
 (0)