tools/testing/selftests/kvm/x86/apic_bus_clock_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/apic_bus_clock_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/x86/apic_bus_clock_test.c
Extension
.c
Size
4809 bytes
Lines
199
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (get_ucall(vcpu, &uc)) {
		case UCALL_DONE:
			done = true;
			break;
		case UCALL_ABORT:
			REPORT_GUEST_ASSERT(uc);
			break;
		default:
			TEST_FAIL("Unknown ucall %lu", uc.cmd);
			break;
		}
	}
}

static void run_apic_bus_clock_test(u64 apic_hz, u64 delay_ms,
				    bool x2apic)
{
	struct kvm_vcpu *vcpu;
	struct kvm_vm *vm;
	int ret;

	is_x2apic = x2apic;

	vm = vm_create(1);

	sync_global_to_guest(vm, is_x2apic);

	vm_enable_cap(vm, KVM_CAP_X86_APIC_BUS_CYCLES_NS,
		      NSEC_PER_SEC / apic_hz);

	TEST_ASSERT_EQ(kvm_check_cap(KVM_CAP_X86_APIC_BUS_CYCLES_NS), 1);
	TEST_ASSERT_EQ(vm_check_cap(vm, KVM_CAP_X86_APIC_BUS_CYCLES_NS),
		       NSEC_PER_SEC / apic_hz);

	vcpu = vm_vcpu_add(vm, 0, apic_guest_code);
	vcpu_args_set(vcpu, 2, apic_hz, delay_ms);

	ret = __vm_enable_cap(vm, KVM_CAP_X86_APIC_BUS_CYCLES_NS,
			      NSEC_PER_SEC / apic_hz);
	TEST_ASSERT(ret < 0 && errno == EINVAL,
		    "Setting of APIC bus frequency after vCPU is created should fail.");

	if (!is_x2apic)
		virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA);

	test_apic_bus_clock(vcpu);
	kvm_vm_free(vm);
}

static void help(char *name)
{
	puts("");
	printf("usage: %s [-h] [-d delay] [-f APIC bus freq]\n", name);
	puts("");
	printf("-d: Delay (in msec) guest uses to measure APIC bus frequency.\n");
	printf("-f: The APIC bus frequency (in MHz) to be configured for the guest.\n");
	puts("");
}

int main(int argc, char *argv[])
{
	/*
	 * Arbitrarilty default to 25MHz for the APIC bus frequency, which is
	 * different enough from the default 1GHz to be interesting.
	 */
	u64 apic_hz = 25 * 1000 * 1000;
	u64 delay_ms = 100;
	int opt;

	TEST_REQUIRE(kvm_has_cap(KVM_CAP_X86_APIC_BUS_CYCLES_NS));

	while ((opt = getopt(argc, argv, "d:f:h")) != -1) {
		switch (opt) {
		case 'f':
			apic_hz = atoi_positive("APIC bus frequency", optarg) * 1000 * 1000;
			break;
		case 'd':
			delay_ms = atoi_positive("Delay in milliseconds", optarg);
			break;
		case 'h':
		default:
			help(argv[0]);
			exit(KSFT_SKIP);
		}
	}

	run_apic_bus_clock_test(apic_hz, delay_ms, false);
	run_apic_bus_clock_test(apic_hz, delay_ms, true);
}

Annotation

Implementation Notes