tools/testing/selftests/kvm/memslot_perf_test.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/memslot_perf_test.c
Extension
.c
Size
30113 bytes
Lines
1153
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 vm_data {
	struct kvm_vm *vm;
	struct kvm_vcpu *vcpu;
	pthread_t vcpu_thread;
	u32 nslots;
	u64 npages;
	u64 pages_per_slot;
	void **hva_slots;
	bool mmio_ok;
	u64 mmio_gpa_min;
	u64 mmio_gpa_max;
};

struct sync_area {
	u32    guest_page_size;
	atomic_bool start_flag;
	atomic_bool exit_flag;
	atomic_bool sync_flag;
	void *move_area_ptr;
};

/*
 * Technically, we need also for the atomic bool to be address-free, which
 * is recommended, but not strictly required, by C11 for lockless
 * implementations.
 * However, in practice both GCC and Clang fulfill this requirement on
 * all KVM-supported platforms.
 */
static_assert(ATOMIC_BOOL_LOCK_FREE == 2, "atomic bool is not lockless");

static int wait_timeout = 10;
static sem_t vcpu_ready;

static bool map_unmap_verify;
#ifdef __x86_64__
static bool disable_slot_zap_quirk;
#endif

static bool verbose;
#define pr_info_v(...)				\
	do {					\
		if (verbose)			\
			pr_info(__VA_ARGS__);	\
	} while (0)

static void check_mmio_access(struct vm_data *data, struct kvm_run *run)
{
	TEST_ASSERT(data->mmio_ok, "Unexpected mmio exit");
	TEST_ASSERT(run->mmio.is_write, "Unexpected mmio read");
	TEST_ASSERT(run->mmio.len == 8,
		    "Unexpected exit mmio size = %u", run->mmio.len);
	TEST_ASSERT(run->mmio.phys_addr >= data->mmio_gpa_min &&
		    run->mmio.phys_addr <= data->mmio_gpa_max,
		    "Unexpected exit mmio address = 0x%llx",
		    run->mmio.phys_addr);
}

static void *vcpu_worker(void *__data)
{
	struct vm_data *data = __data;
	struct kvm_vcpu *vcpu = data->vcpu;
	struct kvm_run *run = vcpu->run;
	struct ucall uc;

	while (1) {
		vcpu_run(vcpu);

		switch (get_ucall(vcpu, &uc)) {
		case UCALL_SYNC:
			TEST_ASSERT(uc.args[1] == 0,
				"Unexpected sync ucall, got %lx",
				(ulong)uc.args[1]);
			sem_post(&vcpu_ready);
			continue;
		case UCALL_NONE:
			if (run->exit_reason == KVM_EXIT_MMIO)
				check_mmio_access(data, run);
			else
				goto done;
			break;
		case UCALL_ABORT:
			REPORT_GUEST_ASSERT(uc);
			break;
		case UCALL_DONE:
			goto done;
		default:
			TEST_FAIL("Unknown ucall %lu", uc.cmd);
		}
	}

Annotation

Implementation Notes