Commit 8d7fbf01 authored by Makarand Sonare's avatar Makarand Sonare Committed by Paolo Bonzini
Browse files

KVM: selftests: VMX preemption timer migration test



When a nested VM with a VMX-preemption timer is migrated, verify that the
nested VM and its parent VM observe the VMX-preemption timer exit close to
the original expiration deadline.

Signed-off-by: default avatarMakarand Sonare <makarandsonare@google.com>
Reviewed-by: default avatarJim Mattson <jmattson@google.com>
Message-Id: <20200526215107.205814-3-makarandsonare@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 850448f3
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -2091,20 +2091,16 @@ static u64 vmx_calc_preemption_timer_value(struct kvm_vcpu *vcpu)
{
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
	u64 timer_value = 0;

	u64 l1_scaled_tsc = kvm_read_l1_tsc(vcpu, rdtsc()) >>
			    VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE;

	if (!vmx->nested.has_preemption_timer_deadline) {
		timer_value = vmcs12->vmx_preemption_timer_value;
		vmx->nested.preemption_timer_deadline = timer_value +
							l1_scaled_tsc;
		vmx->nested.preemption_timer_deadline =
			vmcs12->vmx_preemption_timer_value + l1_scaled_tsc;
		vmx->nested.has_preemption_timer_deadline = true;
	} else if (l1_scaled_tsc < vmx->nested.preemption_timer_deadline)
		timer_value = vmx->nested.preemption_timer_deadline -
			      l1_scaled_tsc;
	return timer_value;
	}
	return vmx->nested.preemption_timer_deadline - l1_scaled_tsc;
}

static void vmx_start_preemption_timer(struct kvm_vcpu *vcpu,
+1 −0
Original line number Diff line number Diff line
@@ -400,6 +400,7 @@ struct kvm_sync_regs {
struct kvm_vmx_nested_state_data {
	__u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
	__u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
	__u64 preemption_timer_deadline;
};

struct kvm_vmx_nested_state_hdr {
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
/x86_64/set_sregs_test
/x86_64/smm_test
/x86_64/state_test
/x86_64/vmx_preemption_timer_test
/x86_64/svm_vmcall_test
/x86_64/sync_regs_test
/x86_64/vmx_close_while_nested_test
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
TEST_GEN_PROGS_x86_64 += x86_64/smm_test
TEST_GEN_PROGS_x86_64 += x86_64/state_test
TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
+2 −0
Original line number Diff line number Diff line
@@ -314,6 +314,8 @@ void ucall_uninit(struct kvm_vm *vm);
void ucall(uint64_t cmd, int nargs, ...);
uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);

#define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4)	\
				ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4)
#define GUEST_SYNC(stage)	ucall(UCALL_SYNC, 2, "hello", stage)
#define GUEST_DONE()		ucall(UCALL_DONE, 0)
#define __GUEST_ASSERT(_condition, _nargs, _args...) do {	\
Loading