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
This commit is contained in:
parent
1e9c9ab595
commit
a7db532e3a
@ -2804,10 +2804,12 @@ VMM_STAT_FUNC(VMM_MEM_WIRED, "Wired memory", vm_get_wiredcnt);
|
|||||||
static int
|
static int
|
||||||
vm_snapshot_vcpus(struct vm *vm, struct vm_snapshot_meta *meta)
|
vm_snapshot_vcpus(struct vm *vm, struct vm_snapshot_meta *meta)
|
||||||
{
|
{
|
||||||
|
uint64_t tsc, now;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
struct vcpu *vcpu;
|
struct vcpu *vcpu;
|
||||||
|
|
||||||
|
now = rdtsc();
|
||||||
for (i = 0; i < VM_MAXCPU; i++) {
|
for (i = 0; i < VM_MAXCPU; i++) {
|
||||||
vcpu = &vm->vcpu[i];
|
vcpu = &vm->vcpu[i];
|
||||||
|
|
||||||
@ -2819,13 +2821,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->guest_xcr0, meta, ret, done);
|
||||||
SNAPSHOT_VAR_OR_LEAVE(vcpu->exitinfo, meta, ret, done);
|
SNAPSHOT_VAR_OR_LEAVE(vcpu->exitinfo, meta, ret, done);
|
||||||
SNAPSHOT_VAR_OR_LEAVE(vcpu->nextrip, 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
|
* It will be turned turned back into an actual offset when the
|
||||||
* TSC restore function is called
|
* 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:
|
done:
|
||||||
@ -2836,33 +2840,10 @@ static int
|
|||||||
vm_snapshot_vm(struct vm *vm, struct vm_snapshot_meta *meta)
|
vm_snapshot_vm(struct vm *vm, struct vm_snapshot_meta *meta)
|
||||||
{
|
{
|
||||||
int ret;
|
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);
|
ret = vm_snapshot_vcpus(vm, meta);
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
printf("%s: failed to copy vm data to user buffer", __func__);
|
|
||||||
goto done;
|
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:
|
done:
|
||||||
return (ret);
|
return (ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user