127 lines · 2.6 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * Copyright (C) 2021, Google LLC. * * Tests for adjusting the system counter from userspace */#include <asm/kvm_para.h>#include <stdint.h>#include <string.h>#include <sys/stat.h>#include <time.h> #include "test_util.h"#include "kvm_util.h"#include "processor.h" #ifdef __x86_64__ struct test_case {	u64 tsc_offset;}; static struct test_case test_cases[] = {	{ 0 },	{ 180 * NSEC_PER_SEC },	{ -180 * NSEC_PER_SEC },}; static void check_preconditions(struct kvm_vcpu *vcpu){	__TEST_REQUIRE(!__vcpu_has_device_attr(vcpu, KVM_VCPU_TSC_CTRL,					       KVM_VCPU_TSC_OFFSET),		       "KVM_VCPU_TSC_OFFSET not supported; skipping test");} static void setup_system_counter(struct kvm_vcpu *vcpu, struct test_case *test){	vcpu_device_attr_set(vcpu, KVM_VCPU_TSC_CTRL, KVM_VCPU_TSC_OFFSET,			     &test->tsc_offset);} static u64 guest_read_system_counter(struct test_case *test){	return rdtsc();} static u64 host_read_guest_system_counter(struct test_case *test){	return rdtsc() + test->tsc_offset;} #else /* __x86_64__ */ #error test not implemented for this architecture! #endif #define GUEST_SYNC_CLOCK(__stage, __val)			\		GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0) static void guest_main(void){	int i; 	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {		struct test_case *test = &test_cases[i]; 		GUEST_SYNC_CLOCK(i, guest_read_system_counter(test));	}} static void handle_sync(struct ucall *uc, u64 start, u64 end){	u64 obs = uc->args[2]; 	TEST_ASSERT(start <= obs && obs <= end,		    "unexpected system counter value: %"PRIu64" expected range: [%"PRIu64", %"PRIu64"]",		    obs, start, end); 	pr_info("system counter value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n",		obs, start, end);} static void handle_abort(struct ucall *uc){	REPORT_GUEST_ASSERT(*uc);} static void enter_guest(struct kvm_vcpu *vcpu){	u64 start, end;	struct ucall uc;	int i; 	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {		struct test_case *test = &test_cases[i]; 		setup_system_counter(vcpu, test);		start = host_read_guest_system_counter(test);		vcpu_run(vcpu);		end = host_read_guest_system_counter(test); 		switch (get_ucall(vcpu, &uc)) {		case UCALL_SYNC:			handle_sync(&uc, start, end);			break;		case UCALL_ABORT:			handle_abort(&uc);			return;		default:			TEST_ASSERT(0, "unhandled ucall %ld",				    get_ucall(vcpu, &uc));		}	}} int main(void){	struct kvm_vcpu *vcpu;	struct kvm_vm *vm; 	vm = vm_create_with_one_vcpu(&vcpu, guest_main);	check_preconditions(vcpu); 	enter_guest(vcpu);	kvm_vm_free(vm);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t