/*
 * Set up the VMAs to tell the VM about the vDSO.
 * Copyright 2007 Andi Kleen, SUSE Labs.
 * Subject to the GPL, v.2
 */

/*
 * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
 */

#include <linux/mm.h>
#include <linux/err.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/random.h>
#include <linux/elf.h>
#include <asm/cacheflush.h>
#include <asm/spitfire.h>
#include <asm/vdso.h>
#include <asm/vvar.h>
#include <asm/page.h>

unsigned int __read_mostly vdso_enabled = 1;

static struct vm_special_mapping vvar_mapping = {
	.name = "[vvar]"
};

#ifdef	CONFIG_SPARC64
static struct vm_special_mapping vdso_mapping64 = {
	.name = "[vdso]"
};
#endif

#ifdef CONFIG_COMPAT
static struct vm_special_mapping vdso_mapping32 = {
	.name = "[vdso]"
};
#endif

struct vvar_data *vvar_data;

struct vdso_elfinfo32 {
	Elf32_Ehdr	*hdr;
	Elf32_Sym	*dynsym;
	unsigned long	dynsymsize;
	const char	*dynstr;
	unsigned long	text;
};

struct vdso_elfinfo64 {
	Elf64_Ehdr	*hdr;
	Elf64_Sym	*dynsym;
	unsigned long	dynsymsize;
	const char	*dynstr;
	unsigned long	text;
};

struct vdso_elfinfo {
	union {
		struct vdso_elfinfo32 elf32;
		struct vdso_elfinfo64 elf64;
	} u;
};

static void *one_section64(struct vdso_elfinfo64 *e, const char *name,
			   unsigned long *size)
{
	const char *snames;
	Elf64_Shdr *shdrs;
	unsigned int i;

	shdrs = (void *)e->hdr + e->hdr->e_shoff;
	snames = (void *)e->hdr + shdrs[e->hdr->e_shstrndx].sh_offset;
	for (i = 1; i < e->hdr->e_shnum; i++) {
		if (!strcmp(snames+shdrs[i].sh_name, name)) {
			if (size)
				*size = shdrs[i].sh_size;
			return (void *)e->hdr + shdrs[i].sh_offset;
		}
	}
	return NULL;
}

static int find_sections64(const struct vdso_image *image, struct vdso_elfinfo *_e)
{
	struct vdso_elfinfo64 *e = &_e->u.elf64;

	e->hdr = image->data;
	e->dynsym = one_section64(e, ".dynsym", &e->dynsymsize);
	e->dynstr = one_section64(e, ".dynstr", NULL);

	if (!e->dynsym || !e->dynstr) {
		pr_err("VDSO64: Missing symbol sections.\n");
		return -ENODEV;
	}
	return 0;
}

static Elf64_Sym *find_sym64(const struct vdso_elfinfo64 *e, const char *name)
{
	unsigned int i;

	for (i = 0; i < (e->dynsymsize / sizeof(Elf64_Sym)); i++) {
		Elf64_Sym *s = &e->dynsym[i];
		if (s->st_name == 0)
			continue;
		if (!strcmp(e->dynstr + s->st_name, name))
			return s;
	}
	return NULL;
}

static int patchsym64(struct vdso_elfinfo *_e, const char *orig,
		      const char *new)
{
	struct vdso_elfinfo64 *e = &_e->u.elf64;
	Elf64_Sym *osym = find_sym64(e, orig);
	Elf64_Sym *nsym = find_sym64(e, new);

	if (!nsym || !osym) {
		pr_err("VDSO64: Missing symbols.\n");
		return -ENODEV;
	}
	osym->st_value = nsym->st_value;
	osym->st_size = nsym->st_size;
	osym->st_info = nsym->st_info;
	osym->st_other = nsym->st_other;
	osym->st_shndx = nsym->st_shndx;

	return 0;
}

static void *one_section32(struct vdso_elfinfo32 *e, const char *name,
			   unsigned long *size)
{
	const char *snames;
	Elf32_Shdr *shdrs;
	unsigned int i;

	shdrs = (void *)e->hdr + e->hdr->e_shoff;
	snames = (void *)e->hdr + shdrs[e->hdr->e_shstrndx].sh_offset;
	for (i = 1; i < e->hdr->e_shnum; i++) {
		if (!strcmp(snames+shdrs[i].sh_name, name)) {
			if (size)
				*size = shdrs[i].sh_size;
			return (void *)e->hdr + shdrs[i].sh_offset;
		}
	}
	return NULL;
}

static int find_sections32(const struct vdso_image *image, struct vdso_elfinfo *_e)
{
	struct vdso_elfinfo32 *e = &_e->u.elf32;

	e->hdr = image->data;
	e->dynsym = one_section32(e, ".dynsym", &e->dynsymsize);
	e->dynstr = one_section32(e, ".dynstr", NULL);

	if (!e->dynsym || !e->dynstr) {
		pr_err("VDSO32: Missing symbol sections.\n");
		return -ENODEV;
	}
	return 0;
}

static Elf32_Sym *find_sym32(const struct vdso_elfinfo32 *e, const char *name)
{
	unsigned int i;

	for (i = 0; i < (e->dynsymsize / sizeof(Elf32_Sym)); i++) {
		Elf32_Sym *s = &e->dynsym[i];
		if (s->st_name == 0)
			continue;
		if (!strcmp(e->dynstr + s->st_name, name))
			return s;
	}
	return NULL;
}

static int patchsym32(struct vdso_elfinfo *_e, const char *orig,
		      const char *new)
{
	struct vdso_elfinfo32 *e = &_e->u.elf32;
	Elf32_Sym *osym = find_sym32(e, orig);
	Elf32_Sym *nsym = find_sym32(e, new);

	if (!nsym || !osym) {
		pr_err("VDSO32: Missing symbols.\n");
		return -ENODEV;
	}
	osym->st_value = nsym->st_value;
	osym->st_size = nsym->st_size;
	osym->st_info = nsym->st_info;
	osym->st_other = nsym->st_other;
	osym->st_shndx = nsym->st_shndx;

	return 0;
}

static int find_sections(const struct vdso_image *image, struct vdso_elfinfo *e,
			 bool elf64)
{
	if (elf64)
		return find_sections64(image, e);
	else
		return find_sections32(image, e);
}

static int patch_one_symbol(struct vdso_elfinfo *e, const char *orig,
			    const char *new_target, bool elf64)
{
	if (elf64)
		return patchsym64(e, orig, new_target);
	else
		return patchsym32(e, orig, new_target);
}

static int stick_patch(const struct vdso_image *image, struct vdso_elfinfo *e, bool elf64)
{
	int err;

	err = find_sections(image, e, elf64);
	if (err)
		return err;

	err = patch_one_symbol(e,
			       "__vdso_gettimeofday",
			       "__vdso_gettimeofday_stick", elf64);
	if (err)
		return err;

	return patch_one_symbol(e,
				"__vdso_clock_gettime",
				"__vdso_clock_gettime_stick", elf64);
	return 0;
}

/*
 * Allocate pages for the vdso and vvar, and copy in the vdso text from the
 * kernel image.
 */
int __init init_vdso_image(const struct vdso_image *image,
			   struct vm_special_mapping *vdso_mapping, bool elf64)
{
	int cnpages = (image->size) / PAGE_SIZE;
	struct page *dp, **dpp = NULL;
	struct page *cp, **cpp = NULL;
	struct vdso_elfinfo ei;
	int i, dnpages = 0;

	if (tlb_type != spitfire) {
		int err = stick_patch(image, &ei, elf64);
		if (err)
			return err;
	}

	/*
	 * First, the vdso text.  This is initialied data, an integral number of
	 * pages long.
	 */
	if (WARN_ON(image->size % PAGE_SIZE != 0))
		goto oom;

	cpp = kcalloc(cnpages, sizeof(struct page *), GFP_KERNEL);
	vdso_mapping->pages = cpp;

	if (!cpp)
		goto oom;

	for (i = 0; i < cnpages; i++) {
		cp = alloc_page(GFP_KERNEL);
		if (!cp)
			goto oom;
		cpp[i] = cp;
		copy_page(page_address(cp), image->data + i * PAGE_SIZE);
	}

	/*
	 * Now the vvar page.  This is uninitialized data.
	 */

	if (vvar_data == NULL) {
		dnpages = (sizeof(struct vvar_data) / PAGE_SIZE) + 1;
		if (WARN_ON(dnpages != 1))
			goto oom;
		dpp = kcalloc(dnpages, sizeof(struct page *), GFP_KERNEL);
		vvar_mapping.pages = dpp;

		if (!dpp)
			goto oom;

		dp = alloc_page(GFP_KERNEL);
		if (!dp)
			goto oom;

		dpp[0] = dp;
		vvar_data = page_address(dp);
		memset(vvar_data, 0, PAGE_SIZE);

		vvar_data->seq = 0;
	}

	return 0;
 oom:
	if (cpp != NULL) {
		for (i = 0; i < cnpages; i++) {
			if (cpp[i] != NULL)
				__free_page(cpp[i]);
		}
		kfree(cpp);
		vdso_mapping->pages = NULL;
	}

	if (dpp != NULL) {
		for (i = 0; i < dnpages; i++) {
			if (dpp[i] != NULL)
				__free_page(dpp[i]);
		}
		kfree(dpp);
		vvar_mapping.pages = NULL;
	}

	pr_warn("Cannot allocate vdso\n");
	vdso_enabled = 0;
	return -ENOMEM;
}

static int __init init_vdso(void)
{
	int err = 0;
#ifdef CONFIG_SPARC64
	err = init_vdso_image(&vdso_image_64_builtin, &vdso_mapping64, true);
	if (err)
		return err;
#endif

#ifdef CONFIG_COMPAT
	err = init_vdso_image(&vdso_image_32_builtin, &vdso_mapping32, false);
#endif
	return err;

}
subsys_initcall(init_vdso);

struct linux_binprm;

/* Shuffle the vdso up a bit, randomly. */
static unsigned long vdso_addr(unsigned long start, unsigned int len)
{
	unsigned int offset;

	/* This loses some more bits than a modulo, but is cheaper */
	offset = get_random_int() & (PTRS_PER_PTE - 1);
	return start + (offset << PAGE_SHIFT);
}

static int map_vdso(const struct vdso_image *image,
		struct vm_special_mapping *vdso_mapping)
{
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma;
	unsigned long text_start, addr = 0;
	int ret = 0;

	down_write(&mm->mmap_sem);

	/*
	 * First, get an unmapped region: then randomize it, and make sure that
	 * region is free.
	 */
	if (current->flags & PF_RANDOMIZE) {
		addr = get_unmapped_area(NULL, 0,
					 image->size - image->sym_vvar_start,
					 0, 0);
		if (IS_ERR_VALUE(addr)) {
			ret = addr;
			goto up_fail;
		}
		addr = vdso_addr(addr, image->size - image->sym_vvar_start);
	}
	addr = get_unmapped_area(NULL, addr,
				 image->size - image->sym_vvar_start, 0, 0);
	if (IS_ERR_VALUE(addr)) {
		ret = addr;
		goto up_fail;
	}

	text_start = addr - image->sym_vvar_start;
	current->mm->context.vdso = (void __user *)text_start;

	/*
	 * MAYWRITE to allow gdb to COW and set breakpoints
	 */
	vma = _install_special_mapping(mm,
				       text_start,
				       image->size,
				       VM_READ|VM_EXEC|
				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
				       vdso_mapping);

	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
		goto up_fail;
	}

	vma = _install_special_mapping(mm,
				       addr,
				       -image->sym_vvar_start,
				       VM_READ|VM_MAYREAD,
				       &vvar_mapping);

	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
		do_munmap(mm, text_start, image->size, NULL);
	}

up_fail:
	if (ret)
		current->mm->context.vdso = NULL;

	up_write(&mm->mmap_sem);
	return ret;
}

int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{

	if (!vdso_enabled)
		return 0;

#if defined CONFIG_COMPAT
	if (!(is_32bit_task()))
		return map_vdso(&vdso_image_64_builtin, &vdso_mapping64);
	else
		return map_vdso(&vdso_image_32_builtin, &vdso_mapping32);
#else
	return map_vdso(&vdso_image_64_builtin, &vdso_mapping64);
#endif

}

static __init int vdso_setup(char *s)
{
	int err;
	unsigned long val;

	err = kstrtoul(s, 10, &val);
	if (err)
		return err;
	vdso_enabled = val;
	return 0;
}
__setup("vdso=", vdso_setup);
