]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: x86/xen: setup pvclock updates
authorJoao Martins <joao.m.martins@oracle.com>
Fri, 1 Feb 2019 18:01:45 +0000 (13:01 -0500)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Sat, 12 Dec 2020 19:34:15 +0000 (19:34 +0000)
Parameterise kvm_setup_pvclock_page() a little bit so that it can be
invoked for different gfn_to_hva_cache structures, and with different
offsets. Then we can invoke it for the normal KVM pvclock and also for
the Xen one in the vcpu_info.

Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
arch/x86/kvm/x86.c
arch/x86/kvm/xen.c

index 64016443159c0316f2f0ca8b8742444beac59aa7..cbdc05bb53bdedde3473dfc249f434998470f636 100644 (file)
@@ -2582,13 +2582,15 @@ u64 get_kvmclock_ns(struct kvm *kvm)
        return ret;
 }
 
-static void kvm_setup_pvclock_page(struct kvm_vcpu *v)
+static void kvm_setup_pvclock_page(struct kvm_vcpu *v,
+                                  struct gfn_to_hva_cache *cache,
+                                  unsigned int offset)
 {
        struct kvm_vcpu_arch *vcpu = &v->arch;
        struct pvclock_vcpu_time_info guest_hv_clock;
 
-       if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time,
-               &guest_hv_clock, sizeof(guest_hv_clock))))
+       if (unlikely(kvm_read_guest_offset_cached(v->kvm, cache,
+               &guest_hv_clock, offset, sizeof(guest_hv_clock))))
                return;
 
        /* This VCPU is paused, but it's legal for a guest to read another
@@ -2611,9 +2613,9 @@ static void kvm_setup_pvclock_page(struct kvm_vcpu *v)
                ++guest_hv_clock.version;  /* first time write, random junk */
 
        vcpu->hv_clock.version = guest_hv_clock.version + 1;
-       kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
-                               &vcpu->hv_clock,
-                               sizeof(vcpu->hv_clock.version));
+       kvm_write_guest_offset_cached(v->kvm, cache,
+                                     &vcpu->hv_clock, offset,
+                                     sizeof(vcpu->hv_clock.version));
 
        smp_wmb();
 
@@ -2627,16 +2629,16 @@ static void kvm_setup_pvclock_page(struct kvm_vcpu *v)
 
        trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock);
 
-       kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
-                               &vcpu->hv_clock,
-                               sizeof(vcpu->hv_clock));
+       kvm_write_guest_offset_cached(v->kvm, cache,
+                                     &vcpu->hv_clock, offset,
+                                     sizeof(vcpu->hv_clock));
 
        smp_wmb();
 
        vcpu->hv_clock.version++;
-       kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
-                               &vcpu->hv_clock,
-                               sizeof(vcpu->hv_clock.version));
+       kvm_write_guest_offset_cached(v->kvm, cache,
+                                    &vcpu->hv_clock, offset,
+                                    sizeof(vcpu->hv_clock.version));
 }
 
 static int kvm_guest_time_update(struct kvm_vcpu *v)
@@ -2723,7 +2725,10 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
        vcpu->hv_clock.flags = pvclock_flags;
 
        if (vcpu->pv_time_enabled)
-               kvm_setup_pvclock_page(v);
+               kvm_setup_pvclock_page(v, &vcpu->pv_time, 0);
+       if (vcpu->xen.vcpu_info_set)
+               kvm_setup_pvclock_page(v, &vcpu->xen.vcpu_info_cache,
+                                      offsetof(struct compat_vcpu_info, time));
        if (v == kvm_get_vcpu(v->kvm, 0))
                kvm_hv_setup_tsc_page(v->kvm, &vcpu->hv_clock);
        return 0;
index 4bc72e0b9928d1f43e12f9fc95f8ea213b72851c..d2055b60fdc1414f267a66571c45189d552eaec6 100644 (file)
@@ -82,6 +82,9 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
                /* No compat necessary here. */
                BUILD_BUG_ON(sizeof(struct vcpu_info) !=
                             sizeof(struct compat_vcpu_info));
+               BUILD_BUG_ON(offsetof(struct vcpu_info, time) !=
+                            offsetof(struct compat_vcpu_info, time));
+
                r = kvm_gfn_to_hva_cache_init(kvm, &v->arch.xen.vcpu_info_cache,
                                              data->u.vcpu_attr.gpa,
                                              sizeof(struct vcpu_info));
@@ -89,6 +92,7 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
                        return r;
 
                v->arch.xen.vcpu_info_set = true;
+               kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
                break;
 
        default: