git: a8ffb1a17ce3 - stable/13 - vmm: Simplify saving of absolute TSC values in snapshots.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 26 Jan 2023 22:11:35 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=a8ffb1a17ce31c0ec60ec220f79e4eaeefe99aaa

commit a8ffb1a17ce31c0ec60ec220f79e4eaeefe99aaa
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-11-18 17:57:29 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2023-01-26 21:43:22 +0000

    vmm: Simplify saving of absolute TSC values in snapshots.
    
    Read the current "now" TSC value and use it to compute absolute time
    saved value in vm_snapshot_vcpus rather than iterating over vCPUs
    multiple times in vm_snapshot_vm.
    
    Reviewed by:    corvink, markj
    Differential Revision:  https://reviews.freebsd.org/D37146
    
    (cherry picked from commit a7db532e3a6f83067b342f569b56076d011f8a1e)
---
 sys/amd64/vmm/vmm.c | 35 ++++++++---------------------------
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 90edfbe7673c..3ec34a1f3336 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -2802,10 +2802,12 @@ VMM_STAT_FUNC(VMM_MEM_WIRED, "Wired memory", vm_get_wiredcnt);
 static int
 vm_snapshot_vcpus(struct vm *vm, struct vm_snapshot_meta *meta)
 {
+	uint64_t tsc, now;
 	int ret;
 	int i;
 	struct vcpu *vcpu;
 
+	now = rdtsc();
 	for (i = 0; i < VM_MAXCPU; i++) {
 		vcpu = &vm->vcpu[i];
 
@@ -2817,13 +2819,15 @@ vm_snapshot_vcpus(struct vm *vm, struct vm_snapshot_meta *meta)
 		SNAPSHOT_VAR_OR_LEAVE(vcpu->guest_xcr0, meta, ret, done);
 		SNAPSHOT_VAR_OR_LEAVE(vcpu->exitinfo, meta, ret, done);
 		SNAPSHOT_VAR_OR_LEAVE(vcpu->nextrip, meta, ret, done);
-		/* XXX we're cheating here, since the value of tsc_offset as
-		 * saved here is actually the value of the guest's TSC value.
+
+		/*
+		 * Save the absolute TSC value by adding now to tsc_offset.
 		 *
 		 * It will be turned turned back into an actual offset when the
 		 * TSC restore function is called
 		 */
-		SNAPSHOT_VAR_OR_LEAVE(vcpu->tsc_offset, meta, ret, done);
+		tsc = now + vcpu->tsc_offset;
+		SNAPSHOT_VAR_OR_LEAVE(tsc, meta, ret, done);
 	}
 
 done:
@@ -2834,33 +2838,10 @@ static int
 vm_snapshot_vm(struct vm *vm, struct vm_snapshot_meta *meta)
 {
 	int ret;
-	int i;
-	uint64_t now;
-
-	ret = 0;
-	now = rdtsc();
-
-	if (meta->op == VM_SNAPSHOT_SAVE) {
-		/* XXX make tsc_offset take the value TSC proper as seen by the
-		 * guest
-		 */
-		for (i = 0; i < VM_MAXCPU; i++)
-			vm->vcpu[i].tsc_offset += now;
-	}
 
 	ret = vm_snapshot_vcpus(vm, meta);
-	if (ret != 0) {
-		printf("%s: failed to copy vm data to user buffer", __func__);
+	if (ret != 0)
 		goto done;
-	}
-
-	if (meta->op == VM_SNAPSHOT_SAVE) {
-		/* XXX turn tsc_offset back into an offset; actual value is only
-		 * required for restore; using it otherwise would be wrong
-		 */
-		for (i = 0; i < VM_MAXCPU; i++)
-			vm->vcpu[i].tsc_offset -= now;
-	}
 
 done:
 	return (ret);