From 7f78d604f533ab78b1006c692b174af2640d5933 Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Tue, 3 Jun 2025 14:06:47 +0100 Subject: [PATCH 1/2] temporary workaround for secret-hidden kvm-clock Modify the kernel to do all kvm-clock related guest memory accesses through userspace addreses, and drop various workarounds from firecracker related to disabled kvm-clock. Signed-off-by: Patrick Roy --- .../hiding_ci/linux_patches/11-kvmclock.patch | 147 ++++++++++++++++++ src/vmm/src/builder.rs | 2 +- .../x86_64/cpuid/intel/normalize.rs | 2 +- 3 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 resources/hiding_ci/linux_patches/11-kvmclock.patch diff --git a/resources/hiding_ci/linux_patches/11-kvmclock.patch b/resources/hiding_ci/linux_patches/11-kvmclock.patch new file mode 100644 index 00000000000..19d1ae1aac0 --- /dev/null +++ b/resources/hiding_ci/linux_patches/11-kvmclock.patch @@ -0,0 +1,147 @@ +From f6c3a183801123395e05959b7a6508bf420eb726 Mon Sep 17 00:00:00 2001 +From: Patrick Roy +Date: Tue, 3 Jun 2025 13:57:15 +0100 +Subject: [PATCH] de-gpc-ify kvm-clock + +Signed-off-by: Patrick Roy +--- + arch/x86/include/asm/kvm_host.h | 2 +- + arch/x86/kvm/x86.c | 47 ++++++++++----------------------- + 2 files changed, 15 insertions(+), 34 deletions(-) + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index ce9ad4cd93c5..6b2e9c2ee599 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -915,7 +915,7 @@ struct kvm_vcpu_arch { + s8 pvclock_tsc_shift; + u32 pvclock_tsc_mul; + unsigned int hw_tsc_khz; +- struct gfn_to_pfn_cache pv_time; ++ gpa_t system_time; + /* set guest stopped flag in pvclock flags field */ + bool pvclock_set_guest_stopped_request; + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 2a02f2457c42..5aad662ec0e1 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -2333,12 +2333,9 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time, + + /* we verify if the enable bit is set... */ + if (system_time & 1) +- kvm_gpc_activate(&vcpu->arch.pv_time, system_time & ~1ULL, +- sizeof(struct pvclock_vcpu_time_info)); ++ vcpu->arch.system_time = system_time & ~1ULL; + else +- kvm_gpc_deactivate(&vcpu->arch.pv_time); +- +- return; ++ vcpu->arch.system_time = INVALID_GPA; + } + + static uint32_t div_frac(uint32_t dividend, uint32_t divisor) +@@ -3132,26 +3129,14 @@ u64 get_kvmclock_ns(struct kvm *kvm) + + static void kvm_setup_guest_pvclock(struct pvclock_vcpu_time_info *ref_hv_clock, + struct kvm_vcpu *vcpu, +- struct gfn_to_pfn_cache *gpc, +- unsigned int offset) ++ gpa_t gpa) + { +- struct pvclock_vcpu_time_info *guest_hv_clock; ++ struct pvclock_vcpu_time_info guest_hv_clock; + struct pvclock_vcpu_time_info hv_clock; +- unsigned long flags; + + memcpy(&hv_clock, ref_hv_clock, sizeof(hv_clock)); + +- read_lock_irqsave(&gpc->lock, flags); +- while (!kvm_gpc_check(gpc, offset + sizeof(*guest_hv_clock))) { +- read_unlock_irqrestore(&gpc->lock, flags); +- +- if (kvm_gpc_refresh(gpc, offset + sizeof(*guest_hv_clock))) +- return; +- +- read_lock_irqsave(&gpc->lock, flags); +- } +- +- guest_hv_clock = (void *)(gpc->khva + offset); ++ kvm_read_guest(vcpu->kvm, gpa, &guest_hv_clock, sizeof(struct pvclock_vcpu_time_info)); + + /* + * This VCPU is paused, but it's legal for a guest to read another +@@ -3160,20 +3145,18 @@ static void kvm_setup_guest_pvclock(struct pvclock_vcpu_time_info *ref_hv_clock, + * it is consistent. + */ + +- guest_hv_clock->version = hv_clock.version = (guest_hv_clock->version + 1) | 1; ++ guest_hv_clock.version = hv_clock.version = (guest_hv_clock.version + 1) | 1; + smp_wmb(); + + /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */ +- hv_clock.flags |= (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED); ++ hv_clock.flags |= (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED); + +- memcpy(guest_hv_clock, &hv_clock, sizeof(*guest_hv_clock)); ++ kvm_write_guest(vcpu->kvm, gpa, &hv_clock, sizeof(struct pvclock_vcpu_time_info)); + + smp_wmb(); + +- guest_hv_clock->version = ++hv_clock.version; +- +- kvm_gpc_mark_dirty_in_slot(gpc); +- read_unlock_irqrestore(&gpc->lock, flags); ++ ++hv_clock.version; ++ kvm_write_guest(vcpu->kvm, gpa + offsetof(struct pvclock_vcpu_time_info, version), &hv_clock.version, sizeof(hv_clock.version)); + + trace_kvm_pvclock_update(vcpu->vcpu_id, &hv_clock); + } +@@ -3264,7 +3247,7 @@ int kvm_guest_time_update(struct kvm_vcpu *v) + if (use_master_clock) + hv_clock.flags |= PVCLOCK_TSC_STABLE_BIT; + +- if (vcpu->pv_time.active) { ++ if (vcpu->system_time != INVALID_GPA) { + /* + * GUEST_STOPPED is only supported by kvmclock, and KVM's + * historic behavior is to only process the request if kvmclock +@@ -3274,7 +3257,7 @@ int kvm_guest_time_update(struct kvm_vcpu *v) + hv_clock.flags |= PVCLOCK_GUEST_STOPPED; + vcpu->pvclock_set_guest_stopped_request = false; + } +- kvm_setup_guest_pvclock(&hv_clock, v, &vcpu->pv_time, 0); ++ kvm_setup_guest_pvclock(&hv_clock, v, vcpu->system_time); + + hv_clock.flags &= ~PVCLOCK_GUEST_STOPPED; + } +@@ -3590,7 +3573,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data) + + static void kvmclock_reset(struct kvm_vcpu *vcpu) + { +- kvm_gpc_deactivate(&vcpu->arch.pv_time); ++ vcpu->arch.system_time = INVALID_GPA; + vcpu->arch.time = 0; + } + +@@ -5688,7 +5671,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, + */ + static int kvm_set_guest_paused(struct kvm_vcpu *vcpu) + { +- if (!vcpu->arch.pv_time.active) ++ if (vcpu->arch.system_time == INVALID_GPA) + return -EINVAL; + vcpu->arch.pvclock_set_guest_stopped_request = true; + kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); +@@ -12278,8 +12261,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) + vcpu->arch.regs_avail = ~0; + vcpu->arch.regs_dirty = ~0; + +- kvm_gpc_init(&vcpu->arch.pv_time, vcpu->kvm); +- + if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu)) + kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE); + else +-- +2.49.0 + diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index fbeedefa348..6f62e5c6fe2 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -235,7 +235,7 @@ pub fn build_microvm_for_boot( #[cfg(target_arch = "x86_64")] if secret_free { - boot_cmdline.insert_str("no-kvmclock")?; + //boot_cmdline.insert_str("no-kvmclock")?; } let (mut vmm, mut vcpus) = create_vmm_and_vcpus( diff --git a/src/vmm/src/cpu_config/x86_64/cpuid/intel/normalize.rs b/src/vmm/src/cpu_config/x86_64/cpuid/intel/normalize.rs index c742ca98741..c0d9ed6ff28 100644 --- a/src/vmm/src/cpu_config/x86_64/cpuid/intel/normalize.rs +++ b/src/vmm/src/cpu_config/x86_64/cpuid/intel/normalize.rs @@ -71,7 +71,7 @@ impl super::IntelCpuid { self.update_performance_monitoring_entry()?; self.update_extended_topology_v2_entry(); self.update_brand_string_entry()?; - self.update_frequency_information(); + //self.update_frequency_information(); Ok(()) } From 650f2566555c81cb2193e16f774ad116e826e6dd Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Tue, 3 Jun 2025 14:08:58 +0100 Subject: [PATCH 2/2] fix: clear private flag after freeing gmem folio Not clearing the private flag causes it to stick around after freeing, potentially confusing subsequent users of the folio that assign meaning to the private flag. Signed-off-by: Patrick Roy --- ...d-Add-flag-to-remove-from-direct-map.patch | 46 +++++-- ...0012-fixup-for-direct-map-removal-v4.patch | 51 -------- .../hiding_ci/linux_patches/11-kvmclock.patch | 118 ++++++++++-------- 3 files changed, 100 insertions(+), 115 deletions(-) delete mode 100644 resources/hiding_ci/linux_patches/10-direct-map-removal/0012-fixup-for-direct-map-removal-v4.patch diff --git a/resources/hiding_ci/linux_patches/10-direct-map-removal/0011-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch b/resources/hiding_ci/linux_patches/10-direct-map-removal/0011-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch index dcce661a60e..4175e0fe10d 100644 --- a/resources/hiding_ci/linux_patches/10-direct-map-removal/0011-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch +++ b/resources/hiding_ci/linux_patches/10-direct-map-removal/0011-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch @@ -1,7 +1,7 @@ -From b1fc478976c93fd42b14e06d2de57e121be03142 Mon Sep 17 00:00:00 2001 +From a06590a8007e35c86caf7344f76e69d4501bc43a Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Fri, 7 Feb 2025 14:33:01 +0000 -Subject: [PATCH 11/26] KVM: guest_memfd: Add flag to remove from direct map +Subject: [PATCH] KVM: guest_memfd: Add flag to remove from direct map Add KVM_GMEM_NO_DIRECT_MAP flag for KVM_CREATE_GUEST_MEMFD() ioctl. When set, guest_memfd folios will be removed from the direct map after @@ -56,9 +56,9 @@ spectre-gadget. Signed-off-by: Patrick Roy --- include/uapi/linux/kvm.h | 3 +++ - virt/kvm/guest_memfd.c | 28 +++++++++++++++++++++++++++- + virt/kvm/guest_memfd.c | 38 +++++++++++++++++++++++++++++++++----- virt/kvm/kvm_main.c | 5 +++++ - 3 files changed, 35 insertions(+), 1 deletion(-) + 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 117937a895da..fb02a93546d8 100644 @@ -82,7 +82,7 @@ index 117937a895da..fb02a93546d8 100644 struct kvm_pre_fault_memory { diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index fbf89e643add..a2b96bc51391 100644 +index fbf89e643add..5545a35ce900 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -4,6 +4,7 @@ @@ -117,18 +117,42 @@ index fbf89e643add..a2b96bc51391 100644 folio_mark_uptodate(folio); } -@@ -478,6 +494,10 @@ static void kvm_gmem_free_folio(struct folio *folio) +@@ -471,24 +487,30 @@ static int kvm_gmem_error_folio(struct address_space *mapping, struct folio *fol + return MF_DELAYED; + } + +-#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE + static void kvm_gmem_free_folio(struct folio *folio) + { ++#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE + struct page *page = folio_page(folio, 0); kvm_pfn_t pfn = page_to_pfn(page); int order = folio_order(folio); ++#endif -+ if (folio_test_private(folio)) ++ if (folio_test_private(folio)) { + WARN_ON_ONCE(set_direct_map_valid_noflush(folio_page(folio, 0), + folio_nr_pages(folio), true)); ++ folio_clear_private(folio); ++ } + ++#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE kvm_arch_gmem_invalidate(pfn, pfn + (1ul << order)); - } +-} #endif -@@ -551,6 +571,9 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) ++} + + static const struct address_space_operations kvm_gmem_aops = { + .dirty_folio = noop_dirty_folio, + .migrate_folio = kvm_gmem_migrate_folio, + .error_remove_folio = kvm_gmem_error_folio, +-#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE + .free_folio = kvm_gmem_free_folio, +-#endif + }; + + static int kvm_gmem_getattr(struct mnt_idmap *idmap, const struct path *path, +@@ -551,6 +573,9 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) /* Unmovable mappings are supposed to be marked unevictable as well. */ WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping)); @@ -138,7 +162,7 @@ index fbf89e643add..a2b96bc51391 100644 kvm_get_kvm(kvm); gmem->kvm = kvm; xa_init(&gmem->bindings); -@@ -570,7 +593,10 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args) +@@ -570,7 +595,10 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args) { loff_t size = args->size; u64 flags = args->flags; @@ -174,5 +198,5 @@ index 3e40acb9f5c0..32ca1c921ab0 100644 return !kvm || kvm_arch_has_private_mem(kvm); #endif -- -2.47.1 +2.49.0 diff --git a/resources/hiding_ci/linux_patches/10-direct-map-removal/0012-fixup-for-direct-map-removal-v4.patch b/resources/hiding_ci/linux_patches/10-direct-map-removal/0012-fixup-for-direct-map-removal-v4.patch deleted file mode 100644 index c54565134f1..00000000000 --- a/resources/hiding_ci/linux_patches/10-direct-map-removal/0012-fixup-for-direct-map-removal-v4.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ab44b2d5bfb7ef9b7bbb156d493f49a4bbebf014 Mon Sep 17 00:00:00 2001 -From: Nikita Kalyazin -Date: Thu, 10 Apr 2025 14:18:39 +0000 -Subject: [PATCH 12/26] fixup for direct map removal v4 - -Do not make kvm_gmem_free_folio dependent on -CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE . ---- - virt/kvm/guest_memfd.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index a2b96bc51391..291d647a5c80 100644 ---- a/virt/kvm/guest_memfd.c -+++ b/virt/kvm/guest_memfd.c -@@ -487,28 +487,28 @@ static int kvm_gmem_error_folio(struct address_space *mapping, struct folio *fol - return MF_DELAYED; - } - --#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE - static void kvm_gmem_free_folio(struct folio *folio) - { -+#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE - struct page *page = folio_page(folio, 0); - kvm_pfn_t pfn = page_to_pfn(page); - int order = folio_order(folio); -+#endif - - if (folio_test_private(folio)) - WARN_ON_ONCE(set_direct_map_valid_noflush(folio_page(folio, 0), - folio_nr_pages(folio), true)); - -+#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE - kvm_arch_gmem_invalidate(pfn, pfn + (1ul << order)); --} - #endif -+} - - static const struct address_space_operations kvm_gmem_aops = { - .dirty_folio = noop_dirty_folio, - .migrate_folio = kvm_gmem_migrate_folio, - .error_remove_folio = kvm_gmem_error_folio, --#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE - .free_folio = kvm_gmem_free_folio, --#endif - }; - - static int kvm_gmem_getattr(struct mnt_idmap *idmap, const struct path *path, --- -2.47.1 - diff --git a/resources/hiding_ci/linux_patches/11-kvmclock.patch b/resources/hiding_ci/linux_patches/11-kvmclock.patch index 19d1ae1aac0..e941d88795c 100644 --- a/resources/hiding_ci/linux_patches/11-kvmclock.patch +++ b/resources/hiding_ci/linux_patches/11-kvmclock.patch @@ -1,21 +1,21 @@ -From f6c3a183801123395e05959b7a6508bf420eb726 Mon Sep 17 00:00:00 2001 +From 48bd0eb952cf1455b124fa06c348b801ef2254ad Mon Sep 17 00:00:00 2001 From: Patrick Roy -Date: Tue, 3 Jun 2025 13:57:15 +0100 +Date: Tue, 3 Jun 2025 15:32:13 +0100 Subject: [PATCH] de-gpc-ify kvm-clock Signed-off-by: Patrick Roy --- arch/x86/include/asm/kvm_host.h | 2 +- - arch/x86/kvm/x86.c | 47 ++++++++++----------------------- - 2 files changed, 15 insertions(+), 34 deletions(-) + arch/x86/kvm/x86.c | 53 +++++++++++---------------------- + 2 files changed, 19 insertions(+), 36 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index ce9ad4cd93c5..6b2e9c2ee599 100644 +index b874e54a5ee4..7cdef9002af8 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h -@@ -915,7 +915,7 @@ struct kvm_vcpu_arch { - s8 pvclock_tsc_shift; - u32 pvclock_tsc_mul; +@@ -911,7 +911,7 @@ struct kvm_vcpu_arch { + gpa_t time; + struct pvclock_vcpu_time_info hv_clock; unsigned int hw_tsc_khz; - struct gfn_to_pfn_cache pv_time; + gpa_t system_time; @@ -23,10 +23,10 @@ index ce9ad4cd93c5..6b2e9c2ee599 100644 bool pvclock_set_guest_stopped_request; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 2a02f2457c42..5aad662ec0e1 100644 +index 4b64ab350bcd..b8fbe9b4331b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c -@@ -2333,12 +2333,9 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time, +@@ -2326,12 +2326,9 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time, /* we verify if the enable bit is set... */ if (system_time & 1) @@ -41,20 +41,19 @@ index 2a02f2457c42..5aad662ec0e1 100644 } static uint32_t div_frac(uint32_t dividend, uint32_t divisor) -@@ -3132,26 +3129,14 @@ u64 get_kvmclock_ns(struct kvm *kvm) +@@ -3117,25 +3114,13 @@ u64 get_kvmclock_ns(struct kvm *kvm) + } - static void kvm_setup_guest_pvclock(struct pvclock_vcpu_time_info *ref_hv_clock, - struct kvm_vcpu *vcpu, + static void kvm_setup_guest_pvclock(struct kvm_vcpu *v, - struct gfn_to_pfn_cache *gpc, -- unsigned int offset) -+ gpa_t gpa) +- unsigned int offset, ++ gpa_t gpa, + bool force_tsc_unstable) { + struct kvm_vcpu_arch *vcpu = &v->arch; - struct pvclock_vcpu_time_info *guest_hv_clock; -+ struct pvclock_vcpu_time_info guest_hv_clock; - struct pvclock_vcpu_time_info hv_clock; - unsigned long flags; - - memcpy(&hv_clock, ref_hv_clock, sizeof(hv_clock)); ++ struct pvclock_vcpu_time_info guest_hv_clock; - read_lock_irqsave(&gpc->lock, flags); - while (!kvm_gpc_check(gpc, offset + sizeof(*guest_hv_clock))) { @@ -67,55 +66,59 @@ index 2a02f2457c42..5aad662ec0e1 100644 - } - - guest_hv_clock = (void *)(gpc->khva + offset); -+ kvm_read_guest(vcpu->kvm, gpa, &guest_hv_clock, sizeof(struct pvclock_vcpu_time_info)); ++ kvm_read_guest(v->kvm, gpa, &guest_hv_clock, sizeof(struct pvclock_vcpu_time_info)); /* * This VCPU is paused, but it's legal for a guest to read another -@@ -3160,20 +3145,18 @@ static void kvm_setup_guest_pvclock(struct pvclock_vcpu_time_info *ref_hv_clock, +@@ -3144,28 +3129,28 @@ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v, * it is consistent. */ -- guest_hv_clock->version = hv_clock.version = (guest_hv_clock->version + 1) | 1; -+ guest_hv_clock.version = hv_clock.version = (guest_hv_clock.version + 1) | 1; +- guest_hv_clock->version = vcpu->hv_clock.version = (guest_hv_clock->version + 1) | 1; ++ guest_hv_clock.version = vcpu->hv_clock.version = (guest_hv_clock.version + 1) | 1; ++ kvm_write_guest(v->kvm, gpa, &guest_hv_clock, sizeof(struct pvclock_vcpu_time_info)); ++ smp_wmb(); /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */ -- hv_clock.flags |= (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED); -+ hv_clock.flags |= (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED); +- vcpu->hv_clock.flags |= (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED); ++ vcpu->hv_clock.flags |= (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED); + + if (vcpu->pvclock_set_guest_stopped_request) { + vcpu->hv_clock.flags |= PVCLOCK_GUEST_STOPPED; + vcpu->pvclock_set_guest_stopped_request = false; + } + +- memcpy(guest_hv_clock, &vcpu->hv_clock, sizeof(*guest_hv_clock)); ++ kvm_write_guest(v->kvm, gpa, &vcpu->hv_clock, sizeof(struct pvclock_vcpu_time_info)); -- memcpy(guest_hv_clock, &hv_clock, sizeof(*guest_hv_clock)); -+ kvm_write_guest(vcpu->kvm, gpa, &hv_clock, sizeof(struct pvclock_vcpu_time_info)); + if (force_tsc_unstable) +- guest_hv_clock->flags &= ~PVCLOCK_TSC_STABLE_BIT; ++ guest_hv_clock.flags &= ~PVCLOCK_TSC_STABLE_BIT; smp_wmb(); -- guest_hv_clock->version = ++hv_clock.version; +- guest_hv_clock->version = ++vcpu->hv_clock.version; - - kvm_gpc_mark_dirty_in_slot(gpc); - read_unlock_irqrestore(&gpc->lock, flags); -+ ++hv_clock.version; -+ kvm_write_guest(vcpu->kvm, gpa + offsetof(struct pvclock_vcpu_time_info, version), &hv_clock.version, sizeof(hv_clock.version)); ++ ++vcpu->hv_clock.version; ++ kvm_write_guest(v->kvm, gpa, &vcpu->hv_clock, sizeof(struct pvclock_vcpu_time_info)); - trace_kvm_pvclock_update(vcpu->vcpu_id, &hv_clock); + trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock); } -@@ -3264,7 +3247,7 @@ int kvm_guest_time_update(struct kvm_vcpu *v) - if (use_master_clock) - hv_clock.flags |= PVCLOCK_TSC_STABLE_BIT; - -- if (vcpu->pv_time.active) { -+ if (vcpu->system_time != INVALID_GPA) { - /* - * GUEST_STOPPED is only supported by kvmclock, and KVM's - * historic behavior is to only process the request if kvmclock -@@ -3274,7 +3257,7 @@ int kvm_guest_time_update(struct kvm_vcpu *v) - hv_clock.flags |= PVCLOCK_GUEST_STOPPED; - vcpu->pvclock_set_guest_stopped_request = false; - } -- kvm_setup_guest_pvclock(&hv_clock, v, &vcpu->pv_time, 0); -+ kvm_setup_guest_pvclock(&hv_clock, v, vcpu->system_time); - - hv_clock.flags &= ~PVCLOCK_GUEST_STOPPED; - } -@@ -3590,7 +3573,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data) +@@ -3267,8 +3252,8 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) + + vcpu->hv_clock.flags = pvclock_flags; + +- if (vcpu->pv_time.active) +- kvm_setup_guest_pvclock(v, &vcpu->pv_time, 0, false); ++ if (vcpu->system_time != INVALID_GPA) ++ kvm_setup_guest_pvclock(v, vcpu->system_time, false); + #ifdef CONFIG_KVM_XEN + if (vcpu->xen.vcpu_info_cache.active) + kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_info_cache, +@@ -3570,7 +3555,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data) static void kvmclock_reset(struct kvm_vcpu *vcpu) { @@ -124,7 +127,7 @@ index 2a02f2457c42..5aad662ec0e1 100644 vcpu->arch.time = 0; } -@@ -5688,7 +5671,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, +@@ -5656,7 +5641,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, */ static int kvm_set_guest_paused(struct kvm_vcpu *vcpu) { @@ -133,14 +136,23 @@ index 2a02f2457c42..5aad662ec0e1 100644 return -EINVAL; vcpu->arch.pvclock_set_guest_stopped_request = true; kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); -@@ -12278,8 +12261,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +@@ -6909,7 +6894,7 @@ static int kvm_arch_suspend_notifier(struct kvm *kvm) + + mutex_lock(&kvm->lock); + kvm_for_each_vcpu(i, vcpu, kvm) { +- if (!vcpu->arch.pv_time.active) ++ if (vcpu->arch.system_time == INVALID_GPA) + continue; + + ret = kvm_set_guest_paused(vcpu); +@@ -12251,8 +12236,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) vcpu->arch.regs_avail = ~0; vcpu->arch.regs_dirty = ~0; - kvm_gpc_init(&vcpu->arch.pv_time, vcpu->kvm); - if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu)) - kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE); + vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; else -- 2.49.0