arch/riscv/kvm/nacl.c

Source file repositories/reference/linux-study-clean/arch/riscv/kvm/nacl.c

File Facts

System
Linux kernel
Corpus path
arch/riscv/kvm/nacl.c
Extension
.c
Size
3693 bytes
Lines
153
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (try_count) {
			nacl_sync_hfence(-1UL);
			goto again;
		} else {
			pr_warn("KVM: No free entry in NACL shared memory\n");
			return;
		}
	}

	entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG(i);
	*entp = cpu_to_lelong(control);
	entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PNUM(i);
	*entp = cpu_to_lelong(page_num);
	entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PCOUNT(i);
	*entp = cpu_to_lelong(page_count);
}

int kvm_riscv_nacl_enable(void)
{
	int rc;
	struct sbiret ret;
	struct kvm_riscv_nacl *nacl;

	if (!kvm_riscv_nacl_available())
		return 0;
	nacl = this_cpu_ptr(&kvm_riscv_nacl);

	ret = sbi_ecall(SBI_EXT_NACL, SBI_EXT_NACL_SET_SHMEM,
			nacl->shmem_phys, 0, 0, 0, 0, 0);
	rc = sbi_err_map_linux_errno(ret.error);
	if (rc)
		return rc;

	return 0;
}

void kvm_riscv_nacl_disable(void)
{
	if (!kvm_riscv_nacl_available())
		return;

	sbi_ecall(SBI_EXT_NACL, SBI_EXT_NACL_SET_SHMEM,
		  SBI_SHMEM_DISABLE, SBI_SHMEM_DISABLE, 0, 0, 0, 0);
}

void kvm_riscv_nacl_exit(void)
{
	int cpu;
	struct kvm_riscv_nacl *nacl;

	if (!kvm_riscv_nacl_available())
		return;

	/* Allocate per-CPU shared memory */
	for_each_possible_cpu(cpu) {
		nacl = per_cpu_ptr(&kvm_riscv_nacl, cpu);
		if (!nacl->shmem)
			continue;

		free_pages((unsigned long)nacl->shmem,
			   get_order(SBI_NACL_SHMEM_SIZE));
		nacl->shmem = NULL;
		nacl->shmem_phys = 0;
	}
}

static long nacl_probe_feature(long feature_id)
{
	struct sbiret ret;

	if (!kvm_riscv_nacl_available())
		return 0;

	ret = sbi_ecall(SBI_EXT_NACL, SBI_EXT_NACL_PROBE_FEATURE,
			feature_id, 0, 0, 0, 0, 0);
	return ret.value;
}

int kvm_riscv_nacl_init(void)
{
	int cpu;
	struct page *shmem_page;
	struct kvm_riscv_nacl *nacl;

	if (sbi_spec_version < sbi_mk_version(1, 0) ||
	    sbi_probe_extension(SBI_EXT_NACL) <= 0)
		return -ENODEV;

	/* Enable NACL support */
	static_branch_enable(&kvm_riscv_nacl_available);

Annotation

Implementation Notes