Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20824f30 authored by Joerg Roedel's avatar Joerg Roedel Committed by Avi Kivity
Browse files

KVM: SVM: Handle tsc in svm_get_msr/svm_set_msr correctly



When running nested we need to touch the l1 guests
tsc_offset. Otherwise changes will be lost or a wrong value
be read.

Cc: stable@kernel.org
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 77b1ab17
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -2059,10 +2059,14 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)

	switch (ecx) {
	case MSR_IA32_TSC: {
		u64 tsc;
		u64 tsc_offset;

		rdtscll(tsc);
		*data = svm->vmcb->control.tsc_offset + tsc;
		if (is_nested(svm))
			tsc_offset = svm->nested.hsave->control.tsc_offset;
		else
			tsc_offset = svm->vmcb->control.tsc_offset;

		*data = tsc_offset + native_read_tsc();
		break;
	}
	case MSR_K6_STAR:
@@ -2148,10 +2152,17 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)

	switch (ecx) {
	case MSR_IA32_TSC: {
		u64 tsc;
		u64 tsc_offset = data - native_read_tsc();
		u64 g_tsc_offset = 0;

		if (is_nested(svm)) {
			g_tsc_offset = svm->vmcb->control.tsc_offset -
				       svm->nested.hsave->control.tsc_offset;
			svm->nested.hsave->control.tsc_offset = tsc_offset;
		}

		svm->vmcb->control.tsc_offset = tsc_offset + g_tsc_offset;

		rdtscll(tsc);
		svm->vmcb->control.tsc_offset = data - tsc;
		break;
	}
	case MSR_K6_STAR: