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

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

File Facts

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

if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_STATE) {
			rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
			__TEST_REQUIRE(!rc, "%s not available, skipping tests", s->name);
		}
	}

	/* We should assert if disabling failed here while enabling succeeded before */
	vcpu_set_reg(vcpu, feature, 0);
}

void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
{
	unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
	struct vcpu_reg_sublist *s;
	u64 feature;
	int rc;

	for (int i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++)
		__vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(i), &isa_ext_state[i]);

	/*
	 * Disable all extensions which were enabled by default
	 * if they were available in the risc-v host.
	 */
	for (int i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) {
		rc = __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(i), 0);
		if (rc && isa_ext_state[i])
			isa_ext_cant_disable[i] = true;
	}

	for (int i = 0; i < KVM_RISCV_SBI_EXT_MAX; i++) {
		rc = __vcpu_set_reg(vcpu, RISCV_SBI_EXT_REG(i), 0);
		TEST_ASSERT(!rc || (rc == -1 && errno == ENOENT), "Unexpected error");
	}

	for_each_sublist(c, s) {
		if (!s->feature)
			continue;

		if (s->feature == KVM_RISCV_ISA_EXT_V) {
			feature = RISCV_ISA_EXT_REG(s->feature);
			rc = override_vector_reg_size(vcpu, s, feature);
			if (rc)
				goto skip;
		}

		switch (s->feature_type) {
		case VCPU_FEATURE_ISA_EXT:
			feature = RISCV_ISA_EXT_REG(s->feature);
			break;
		case VCPU_FEATURE_SBI_EXT:
			feature = RISCV_SBI_EXT_REG(s->feature);
			if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
				check_fwft_feature(vcpu, s, feature);
			sbi_ext_enabled[s->feature] = true;
			break;
		default:
			TEST_FAIL("Unknown feature type");
		}

		/* Try to enable the desired extension */
		__vcpu_set_reg(vcpu, feature, 1);

skip:
		/* Double check whether the desired extension was enabled */
		__TEST_REQUIRE(__vcpu_has_ext(vcpu, feature),
			       "%s not available, skipping tests", s->name);
	}
}

static const char *config_id_to_str(const char *prefix, __u64 id)
{
	/* reg_off is the offset into struct kvm_riscv_config */
	__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CONFIG);

	assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CONFIG);

	switch (reg_off) {
	case KVM_REG_RISCV_CONFIG_REG(isa):
		return "KVM_REG_RISCV_CONFIG_REG(isa)";
	case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
		return "KVM_REG_RISCV_CONFIG_REG(zicbom_block_size)";
	case KVM_REG_RISCV_CONFIG_REG(zicboz_block_size):
		return "KVM_REG_RISCV_CONFIG_REG(zicboz_block_size)";
	case KVM_REG_RISCV_CONFIG_REG(zicbop_block_size):
		return "KVM_REG_RISCV_CONFIG_REG(zicbop_block_size)";
	case KVM_REG_RISCV_CONFIG_REG(mvendorid):
		return "KVM_REG_RISCV_CONFIG_REG(mvendorid)";
	case KVM_REG_RISCV_CONFIG_REG(marchid):
		return "KVM_REG_RISCV_CONFIG_REG(marchid)";

Annotation

Implementation Notes