tools/testing/selftests/kvm/get-reg-list.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/get-reg-list.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/get-reg-list.c
Extension
.c
Size
10170 bytes
Lines
406
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

for_each_reg(i) {
			__u64 id = reg_list->reg[i];
			if ((print_list && !filter_reg(id)) ||
			    (print_filtered && filter_reg(id)))
				print_reg(config_name(c), id);
		}
		putchar('\n');
		return;
	}

	for_each_sublist(c, s)
		blessed_n += s->regs_n;
	blessed_reg = calloc(blessed_n, sizeof(__u64));

	n = 0;
	for_each_sublist(c, s) {
		for (i = 0; i < s->regs_n; ++i)
			blessed_reg[n++] = s->regs[i];
	}

	/*
	 * We only test that we can get the register and then write back the
	 * same value. Some registers may allow other values to be written
	 * back, but others only allow some bits to be changed, and at least
	 * for ID registers set will fail if the value does not exactly match
	 * what was returned by get. If registers that allow other values to
	 * be written need to have the other values tested, then we should
	 * create a new set of tests for those in a new independent test
	 * executable.
	 *
	 * Only do the get/set tests on present, blessed list registers,
	 * since we don't know the capabilities of any new registers.
	 */
	for_each_present_blessed_reg(i) {
		u8 addr[2048 / 8];
		struct kvm_one_reg reg = {
			.id = reg_list->reg[i],
			.addr = (__u64)&addr,
		};
		bool reject_reg = false, skip_reg = false;
		int ret;

		ret = __vcpu_get_reg(vcpu, reg_list->reg[i], &addr);
		if (ret) {
			printf("%s: Failed to get ", config_name(c));
			print_reg(config_name(c), reg.id);
			putchar('\n');
			++failed_get;
		}

		for_each_sublist(c, s) {
			/* rejects_set registers are rejected for set operation */
			if (s->rejects_set && find_reg(s->rejects_set, s->rejects_set_n, reg.id)) {
				reject_reg = true;
				ret = __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, &reg);
				if (ret != -1 || !check_reject_set(errno)) {
					printf("%s: Failed to reject (ret=%d, errno=%d) ", config_name(c), ret, errno);
					print_reg(config_name(c), reg.id);
					putchar('\n');
					++failed_reject;
				}
				break;
			}

			/* skips_set registers are skipped for set operation */
			if (s->skips_set && find_reg(s->skips_set, s->skips_set_n, reg.id)) {
				skip_reg = true;
				++skipped_set;
				break;
			}
		}

		if (!reject_reg && !skip_reg) {
			ret = __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, &reg);
			if (ret) {
				printf("%s: Failed to set ", config_name(c));
				print_reg(config_name(c), reg.id);
				putchar('\n');
				++failed_set;
			}
		}
	}

	for_each_new_reg(i)
		++new_regs;

	for_each_missing_reg(i)
		++missing_regs;

	if (new_regs || missing_regs) {

Annotation

Implementation Notes