tools/testing/selftests/kvm/steal_time.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/steal_time.c
Extension
.c
Size
14869 bytes
Lines
592
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

struct st_time {
	u32 rev;
	u32 attr;
	u64 st_time;
};

static s64 smccc(u32 func, u64 arg)
{
	struct arm_smccc_res res;

	do_smccc(func, arg, 0, 0, 0, 0, 0, 0, &res);
	return res.a0;
}

static void check_status(struct st_time *st)
{
	GUEST_ASSERT_EQ(READ_ONCE(st->rev), 0);
	GUEST_ASSERT_EQ(READ_ONCE(st->attr), 0);
}

static void guest_code(int cpu)
{
	struct st_time *st;
	s64 status;

	status = smccc(SMCCC_ARCH_FEATURES, PV_TIME_FEATURES);
	GUEST_ASSERT_EQ(status, 0);
	status = smccc(PV_TIME_FEATURES, PV_TIME_FEATURES);
	GUEST_ASSERT_EQ(status, 0);
	status = smccc(PV_TIME_FEATURES, PV_TIME_ST);
	GUEST_ASSERT_EQ(status, 0);

	status = smccc(PV_TIME_ST, 0);
	GUEST_ASSERT_NE(status, -1);
	GUEST_ASSERT_EQ(status, (ulong)st_gva[cpu]);

	st = (struct st_time *)status;
	GUEST_SYNC(0);

	check_status(st);
	WRITE_ONCE(guest_stolen_time[cpu], st->st_time);
	GUEST_SYNC(1);

	check_status(st);
	WRITE_ONCE(guest_stolen_time[cpu], st->st_time);
	GUEST_DONE();
}

static bool is_steal_time_supported(struct kvm_vcpu *vcpu)
{
	struct kvm_device_attr dev = {
		.group = KVM_ARM_VCPU_PVTIME_CTRL,
		.attr = KVM_ARM_VCPU_PVTIME_IPA,
	};

	return !__vcpu_ioctl(vcpu, KVM_HAS_DEVICE_ATTR, &dev);
}

static void steal_time_init(struct kvm_vcpu *vcpu, u32 i)
{
	struct kvm_vm *vm = vcpu->vm;
	u64 st_ipa;

	struct kvm_device_attr dev = {
		.group = KVM_ARM_VCPU_PVTIME_CTRL,
		.attr = KVM_ARM_VCPU_PVTIME_IPA,
		.addr = (u64)&st_ipa,
	};

	/* ST_GPA_BASE is identity mapped */
	st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
	sync_global_to_guest(vm, st_gva[i]);

	st_ipa = (ulong)st_gva[i];
	vcpu_ioctl(vcpu, KVM_SET_DEVICE_ATTR, &dev);
}

static void steal_time_dump(struct kvm_vm *vm, u32 vcpu_idx)
{
	struct st_time *st = addr_gva2hva(vm, (ulong)st_gva[vcpu_idx]);

	ksft_print_msg("VCPU%d:\n", vcpu_idx);
	ksft_print_msg("    rev:     %d\n", st->rev);
	ksft_print_msg("    attr:    %d\n", st->attr);
	ksft_print_msg("    st_time: %ld\n", st->st_time);
}

static void check_steal_time_uapi(void)
{
	struct kvm_vm *vm;

Annotation

Implementation Notes