arch/loongarch/kernel/vdso.c

Source file repositories/reference/linux-study-clean/arch/loongarch/kernel/vdso.c

File Facts

System
Linux kernel
Corpus path
arch/loongarch/kernel/vdso.c
Extension
.c
Size
2886 bytes
Lines
128
Domain
Architecture Layer
Bucket
arch/loongarch
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration 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

subsys_initcall(init_vdso);

static unsigned long vdso_base(void)
{
	unsigned long base = STACK_TOP;

	if (current->flags & PF_RANDOMIZE) {
		base += get_random_u32_below(VDSO_RANDOMIZE_SIZE);
		base = PAGE_ALIGN(base);
	}

	return base;
}

int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
	int ret;
	unsigned long size, data_addr, vdso_addr;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma;
	struct loongarch_vdso_info *info = current->thread.vdso;

	if (mmap_write_lock_killable(mm))
		return -EINTR;

	/*
	 * Determine total area size. This includes the VDSO data itself
	 * and the data pages.
	 */
	size = VVAR_SIZE + info->size;

	data_addr = get_unmapped_area(NULL, vdso_base(), size, 0, 0);
	if (IS_ERR_VALUE(data_addr)) {
		ret = data_addr;
		goto out;
	}

	vma = vdso_install_vvar_mapping(mm, data_addr);
	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
		goto out;
	}

	vdso_addr = data_addr + VVAR_SIZE;
	vma = _install_special_mapping(mm, vdso_addr, info->size,
				       VM_READ | VM_EXEC |
				       VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC |
				       VM_SEALED_SYSMAP,
				       &info->code_mapping);
	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
		goto out;
	}

	mm->context.vdso = (void *)vdso_addr;
	ret = 0;

out:
	mmap_write_unlock(mm);
	return ret;
}

Annotation

Implementation Notes