Commit 629b5348 authored by Joao Martins's avatar Joao Martins Committed by David Woodhouse

KVM: x86/xen: update wallclock region

Wallclock on Xen is written in the shared_info page.

To that purpose, export kvm_write_wall_clock() and pass on the GPA of
its location to populate the shared_info wall clock data.
Signed-off-by: default avatarJoao Martins <joao.m.martins@oracle.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
parent 42387042
...@@ -1949,15 +1949,14 @@ static s64 get_kvmclock_base_ns(void) ...@@ -1949,15 +1949,14 @@ static s64 get_kvmclock_base_ns(void)
} }
#endif #endif
static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock, int sec_hi_ofs)
{ {
int version; int version;
int r; int r;
struct pvclock_wall_clock wc; struct pvclock_wall_clock wc;
u32 wc_sec_hi;
u64 wall_nsec; u64 wall_nsec;
kvm->arch.wall_clock = wall_clock;
if (!wall_clock) if (!wall_clock)
return; return;
...@@ -1986,6 +1985,12 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) ...@@ -1986,6 +1985,12 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc)); kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc));
if (sec_hi_ofs) {
wc_sec_hi = wall_nsec >> 32;
kvm_write_guest(kvm, wall_clock + sec_hi_ofs,
&wc_sec_hi, sizeof(wc_sec_hi));
}
version++; version++;
kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
} }
...@@ -3131,13 +3136,15 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) ...@@ -3131,13 +3136,15 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2))
return 1; return 1;
kvm_write_wall_clock(vcpu->kvm, data); vcpu->kvm->arch.wall_clock = data;
kvm_write_wall_clock(vcpu->kvm, data, 0);
break; break;
case MSR_KVM_WALL_CLOCK: case MSR_KVM_WALL_CLOCK:
if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE)) if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE))
return 1; return 1;
kvm_write_wall_clock(vcpu->kvm, data); vcpu->kvm->arch.wall_clock = data;
kvm_write_wall_clock(vcpu->kvm, data, 0);
break; break;
case MSR_KVM_SYSTEM_TIME_NEW: case MSR_KVM_SYSTEM_TIME_NEW:
if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2))
......
...@@ -247,6 +247,7 @@ static inline bool kvm_vcpu_latch_init(struct kvm_vcpu *vcpu) ...@@ -247,6 +247,7 @@ static inline bool kvm_vcpu_latch_init(struct kvm_vcpu *vcpu)
return is_smm(vcpu) || static_call(kvm_x86_apic_init_signal_blocked)(vcpu); return is_smm(vcpu) || static_call(kvm_x86_apic_init_signal_blocked)(vcpu);
} }
void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock, int sec_hi_ofs);
void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr);
......
...@@ -21,15 +21,42 @@ DEFINE_STATIC_KEY_DEFERRED_FALSE(kvm_xen_enabled, HZ); ...@@ -21,15 +21,42 @@ DEFINE_STATIC_KEY_DEFERRED_FALSE(kvm_xen_enabled, HZ);
static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn) static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn)
{ {
gpa_t gpa = gfn_to_gpa(gfn);
int wc_ofs, sec_hi_ofs;
int ret; int ret;
int idx = srcu_read_lock(&kvm->srcu); int idx = srcu_read_lock(&kvm->srcu);
ret = kvm_gfn_to_hva_cache_init(kvm, &kvm->arch.xen.shinfo_cache, ret = kvm_gfn_to_hva_cache_init(kvm, &kvm->arch.xen.shinfo_cache,
gfn_to_gpa(gfn), PAGE_SIZE); gpa, PAGE_SIZE);
if (!ret) { if (ret)
kvm->arch.xen.shinfo_set = true; goto out;
kvm->arch.xen.shinfo_set = true;
/* Paranoia checks on the 32-bit struct layout */
BUILD_BUG_ON(offsetof(struct compat_shared_info, wc) != 0x900);
BUILD_BUG_ON(offsetof(struct compat_shared_info, arch.wc_sec_hi) != 0x924);
BUILD_BUG_ON(offsetof(struct pvclock_vcpu_time_info, version) != 0);
/* 32-bit location by default */
wc_ofs = offsetof(struct compat_shared_info, wc);
sec_hi_ofs = offsetof(struct compat_shared_info, arch.wc_sec_hi);
#ifdef CONFIG_X86_64
/* Paranoia checks on the 64-bit struct layout */
BUILD_BUG_ON(offsetof(struct shared_info, wc) != 0xc00);
BUILD_BUG_ON(offsetof(struct shared_info, wc_sec_hi) != 0xc0c);
if (kvm->arch.xen.long_mode) {
wc_ofs = offsetof(struct shared_info, wc);
sec_hi_ofs = offsetof(struct shared_info, wc_sec_hi);
} }
#endif
kvm_write_wall_clock(kvm, gpa + wc_ofs, sec_hi_ofs - wc_ofs);
kvm_make_all_cpus_request(kvm, KVM_REQ_MASTERCLOCK_UPDATE);
out:
srcu_read_unlock(&kvm->srcu, idx); srcu_read_unlock(&kvm->srcu, idx);
return ret; return ret;
} }
......
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