tools/testing/selftests/kvm/lib/loongarch/processor.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/lib/loongarch/processor.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/lib/loongarch/processor.c
Extension
.c
Size
10294 bytes
Lines
403
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 (virt_pte_none(ptep, level)) {
			if (alloc) {
				child = vm_alloc_page_table(vm);
				virt_set_pgtable(vm, child, invalid_pgtable[level - 1]);
				WRITE_ONCE(*ptep, child);
			} else
				goto unmapped_gva;

		} else
			child = pte_addr(vm, *ptep);
		level--;
	}

	ptep = addr_gpa2hva(vm, child) + virt_pte_index(vm, gva, level) * 8;
	return ptep;

unmapped_gva:
	TEST_FAIL("No mapping for vm virtual address, gva: 0x%lx", gva);
	exit(EXIT_FAILURE);
}

gpa_t addr_arch_gva2gpa(struct kvm_vm *vm, gva_t gva)
{
	u64 *ptep;

	ptep = virt_populate_pte(vm, gva, 0);
	TEST_ASSERT(*ptep != 0, "Virtual address gva: 0x%lx not mapped\n", gva);

	return pte_addr(vm, *ptep) + (gva & (vm->page_size - 1));
}

void virt_arch_pg_map(struct kvm_vm *vm, gva_t gva, gpa_t gpa)
{
	u32 prot_bits;
	u64 *ptep;

	TEST_ASSERT((gva % vm->page_size) == 0,
			"Virtual address not on page boundary,\n"
			"gva: 0x%lx vm->page_size: 0x%x", gva, vm->page_size);
	TEST_ASSERT(sparsebit_is_set(vm->vpages_valid, (gva >> vm->page_shift)),
			"Invalid virtual address, gva: 0x%lx", gva);
	TEST_ASSERT((gpa % vm->page_size) == 0,
			"Physical address not on page boundary,\n"
			"gpa: 0x%lx vm->page_size: 0x%x", gpa, vm->page_size);
	TEST_ASSERT((gpa >> vm->page_shift) <= vm->max_gfn,
			"Physical address beyond maximum supported,\n"
			"gpa: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
			gpa, vm->max_gfn, vm->page_size);

	ptep = virt_populate_pte(vm, gva, 1);
	prot_bits = _PAGE_PRESENT | __READABLE | __WRITEABLE | _CACHE_CC | _PAGE_USER;
	WRITE_ONCE(*ptep, gpa | prot_bits);
}

static void pte_dump(FILE *stream, struct kvm_vm *vm, u8 indent, u64 page, int level)
{
	u64 pte, *ptep;
	static const char * const type[] = { "pte", "pmd", "pud", "pgd"};

	if (level < 0)
		return;

	for (pte = page; pte < page + ptrs_per_pte(vm) * 8; pte += 8) {
		ptep = addr_gpa2hva(vm, pte);
		if (virt_pte_none(ptep, level))
			continue;
		fprintf(stream, "%*s%s: %lx: %lx at %p\n",
				indent, "", type[level], pte, *ptep, ptep);
		pte_dump(stream, vm, indent + 1, pte_addr(vm, *ptep), level--);
	}
}

void virt_arch_dump(FILE *stream, struct kvm_vm *vm, u8 indent)
{
	int level;

	if (!vm->mmu.pgd_created)
		return;

	level = vm->mmu.pgtable_levels - 1;
	pte_dump(stream, vm, indent, vm->mmu.pgd, level);
}

void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, u8 indent)
{
}

void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
{
	struct ucall uc;

Annotation

Implementation Notes