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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/lib/riscv/processor.c
Extension
.c
Size
15672 bytes
Lines
573
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 handlers {
	exception_handler_fn exception_handlers[NR_VECTORS][NR_EXCEPTIONS];
};

void route_exception(struct pt_regs *regs)
{
	struct handlers *handlers = (struct handlers *)exception_handlers;
	int vector = 0, ec;

	ec = regs->cause & ~CAUSE_IRQ_FLAG;
	if (ec >= NR_EXCEPTIONS)
		goto unexpected_exception;

	/* Use the same handler for all the interrupts */
	if (regs->cause & CAUSE_IRQ_FLAG) {
		vector = 1;
		ec = 0;
	}

	if (handlers && handlers->exception_handlers[vector][ec])
		return handlers->exception_handlers[vector][ec](regs);

unexpected_exception:
	return kvm_exit_unexpected_exception(vector, ec);
}

void vcpu_init_vector_tables(struct kvm_vcpu *vcpu)
{
	extern char exception_vectors;

	vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(stvec), (unsigned long)&exception_vectors);
}

void vm_init_vector_tables(struct kvm_vm *vm)
{
	vm->handlers = __vm_alloc(vm, sizeof(struct handlers), vm->page_size,
				  MEM_REGION_DATA);

	*(gva_t *)addr_gva2hva(vm, (gva_t)(&exception_handlers)) = vm->handlers;
}

void vm_install_exception_handler(struct kvm_vm *vm, int vector, exception_handler_fn handler)
{
	struct handlers *handlers = addr_gva2hva(vm, vm->handlers);

	assert(vector < NR_EXCEPTIONS);
	handlers->exception_handlers[0][vector] = handler;
}

void vm_install_interrupt_handler(struct kvm_vm *vm, exception_handler_fn handler)
{
	struct handlers *handlers = addr_gva2hva(vm, vm->handlers);

	handlers->exception_handlers[1][0] = handler;
}

u32 guest_get_vcpuid(void)
{
	return csr_read(CSR_SSCRATCH);
}

struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
			unsigned long arg1, unsigned long arg2,
			unsigned long arg3, unsigned long arg4,
			unsigned long arg5)
{
	register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
	register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
	register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
	register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
	register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
	register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
	register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
	register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
	struct sbiret ret;

	asm volatile (
		"ecall"
		: "+r" (a0), "+r" (a1)
		: "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
		: "memory");
	ret.error = a0;
	ret.value = a1;

	return ret;
}

bool guest_sbi_probe_extension(int extid, long *out_val)
{
	struct sbiret ret;

Annotation

Implementation Notes