/*
 * Support for decoding of KVM_* ioctl commands.
 *
 * Copyright (c) 2017 Masatake YAMATO <yamato@redhat.com>
 * Copyright (c) 2017 Red Hat, Inc.
 * Copyright (c) 2017-2018 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"

#ifdef HAVE_LINUX_KVM_H
# include <linux/kvm.h>
# include "print_fields.h"
# include "arch_kvm.c"
# include "xmalloc.h"
# include "mmap_cache.h"

struct vcpu_info {
	struct vcpu_info *next;
	int fd;
	int cpuid;
	long mmap_addr;
	unsigned long mmap_len;
	bool resolved;
};

static bool dump_kvm_run_structure;

static struct vcpu_info *
vcpu_find(struct tcb *const tcp, int fd)
{
	for (struct vcpu_info *vcpu_info = tcp->vcpu_info_list;
	     vcpu_info;
	     vcpu_info = vcpu_info->next)
		if (vcpu_info->fd == fd)
			return vcpu_info;

	return NULL;
}

static struct vcpu_info *
vcpu_alloc(struct tcb *const tcp, int fd, int cpuid)
{
	struct vcpu_info *vcpu_info = xcalloc(1, sizeof(*vcpu_info));

	vcpu_info->fd = fd;
	vcpu_info->cpuid = cpuid;

	vcpu_info->next = tcp->vcpu_info_list;
	tcp->vcpu_info_list = vcpu_info;

	return vcpu_info;
}

void
kvm_vcpu_info_free(struct tcb *tcp)
{
	struct vcpu_info *head, *next;

	for (head = tcp->vcpu_info_list; head; head = next) {
		next = head->next;
		free(head);
	}

	tcp->vcpu_info_list = NULL;
}

static void
vcpu_register(struct tcb *const tcp, int fd, int cpuid)
{
	if (fd < 0)
		return;

	struct vcpu_info *vcpu_info = vcpu_find(tcp, fd);

	if (!vcpu_info)
		vcpu_info = vcpu_alloc(tcp, fd, cpuid);
	else if (vcpu_info->cpuid != cpuid)
	{
		vcpu_info->cpuid = cpuid;
		vcpu_info->resolved = false;
	}
}

static bool
is_map_for_file(struct mmap_cache_entry_t *map_info, void *data)
{
	/* major version for anon inode may be given in get_anon_bdev()
	 * in linux kernel.
	 *
	 * 	*p = MKDEV(0, dev & MINORMASK);
	 *-----------------^
	 */
	return map_info->binary_filename &&
		map_info->major == 0 &&
		strcmp(map_info->binary_filename, data) == 0;
}

static unsigned long
map_len(struct mmap_cache_entry_t *map_info)
{
	return map_info->start_addr < map_info->end_addr
		? map_info->end_addr - map_info->start_addr
		: 0;
}

#define VCPU_DENTRY_PREFIX "anon_inode:kvm-vcpu:"

static struct vcpu_info*
vcpu_get_info(struct tcb *const tcp, int fd)
{
	struct vcpu_info *vcpu_info = vcpu_find(tcp, fd);
	struct mmap_cache_entry_t *map_info;
	const char *cpuid_str;

	enum mmap_cache_rebuild_result mc_stat =
		mmap_cache_rebuild_if_invalid(tcp, __func__);
	if (mc_stat == MMAP_CACHE_REBUILD_NOCACHE)
		return NULL;

	if (vcpu_info && vcpu_info->resolved) {
		if (mc_stat == MMAP_CACHE_REBUILD_READY)
			return vcpu_info;
		else {
			map_info = mmap_cache_search(tcp, vcpu_info->mmap_addr);
			if (map_info) {
				cpuid_str =
					STR_STRIP_PREFIX(map_info->binary_filename,
							 VCPU_DENTRY_PREFIX);
				if (cpuid_str != map_info->binary_filename) {
					int cpuid = string_to_uint(cpuid_str);
					if (cpuid < 0)
						return NULL;
					if (vcpu_info->cpuid == cpuid)
						return vcpu_info;
				}
			}

			/* The vcpu vma may be mremap'ed. */
			vcpu_info->resolved = false;
		}
	}

	/* Slow path: !vcpu_info || !vcpu_info->resolved */
	char path[PATH_MAX + 1];
	cpuid_str = path;
	if (getfdpath(tcp, fd, path, sizeof(path)) >= 0)
		cpuid_str = STR_STRIP_PREFIX(path, VCPU_DENTRY_PREFIX);
	if (cpuid_str == path)
		map_info = NULL;
	else
		map_info = mmap_cache_search_custom(tcp, is_map_for_file, path);

	if (map_info) {
		int cpuid = string_to_uint(cpuid_str);
		if (cpuid < 0)
			return NULL;
		if (!vcpu_info)
			vcpu_info = vcpu_alloc(tcp, fd, cpuid);
		else if (vcpu_info->cpuid != cpuid)
			vcpu_info->cpuid = cpuid;
		vcpu_info->mmap_addr = map_info->start_addr;
		vcpu_info->mmap_len  = map_len(map_info);
		vcpu_info->resolved  = true;
		return vcpu_info;
	}

	return NULL;
}

static int
kvm_ioctl_create_vcpu(struct tcb *const tcp, const kernel_ulong_t arg)
{
	uint32_t cpuid = arg;

	if (entering(tcp)) {
		tprintf(", %u", cpuid);
		if (dump_kvm_run_structure)
			return 0;
	} else if (!syserror(tcp)) {
		vcpu_register(tcp, tcp->u_rval, cpuid);
	}

	return RVAL_IOCTL_DECODED | RVAL_FD;
}

# ifdef HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION
#  include "xlat/kvm_mem_flags.h"
static int
kvm_ioctl_set_user_memory_region(struct tcb *const tcp, const kernel_ulong_t arg)
{
	struct kvm_userspace_memory_region u_memory_region;

	tprints(", ");
	if (umove_or_printaddr(tcp, arg, &u_memory_region))
		return RVAL_IOCTL_DECODED;

	PRINT_FIELD_U("{", u_memory_region, slot);
	PRINT_FIELD_FLAGS(", ", u_memory_region, flags, kvm_mem_flags,
			  "KVM_MEM_???");
	PRINT_FIELD_X(", ", u_memory_region, guest_phys_addr);
	PRINT_FIELD_U(", ", u_memory_region, memory_size);
	PRINT_FIELD_X(", ", u_memory_region, userspace_addr);
	tprints("}");

	return RVAL_IOCTL_DECODED;
}
# endif /* HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION */

# ifdef HAVE_STRUCT_KVM_REGS
static int
kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code,
		      const kernel_ulong_t arg)
{
	struct kvm_regs regs;

	if (code == KVM_GET_REGS && entering(tcp))
		return 0;

	tprints(", ");
	if (!umove_or_printaddr(tcp, arg, &regs))
		arch_print_kvm_regs(tcp, arg, &regs);

	return RVAL_IOCTL_DECODED;
}
# endif /* HAVE_STRUCT_KVM_REGS */

# ifdef HAVE_STRUCT_KVM_CPUID2
#  include "xlat/kvm_cpuid_flags.h"
static bool
print_kvm_cpuid_entry(struct tcb *const tcp,
		      void* elem_buf, size_t elem_size, void* data)
{
	const struct kvm_cpuid_entry2 *entry = elem_buf;
	PRINT_FIELD_X("{", *entry, function);
	PRINT_FIELD_X(", ", *entry, index);
	PRINT_FIELD_FLAGS(", ", *entry, flags, kvm_cpuid_flags,
			  "KVM_CPUID_FLAG_???");
	PRINT_FIELD_X(", ", *entry, eax);
	PRINT_FIELD_X(", ", *entry, ebx);
	PRINT_FIELD_X(", ", *entry, ecx);
	PRINT_FIELD_X(", ", *entry, edx);
	tprints("}");

	return true;
}

static int
kvm_ioctl_decode_cpuid2(struct tcb *const tcp, const unsigned int code,
			const kernel_ulong_t arg)
{
	struct kvm_cpuid2 cpuid;

	if (entering(tcp) && (code == KVM_GET_SUPPORTED_CPUID
#  ifdef KVM_GET_EMULATED_CPUID
			      || code == KVM_GET_EMULATED_CPUID
#  endif
			     ))
		return 0;

	tprints(", ");
	if (!umove_or_printaddr(tcp, arg, &cpuid)) {
		PRINT_FIELD_U("{", cpuid, nent);

		tprints(", entries=");
		if (abbrev(tcp)) {
			tprints("[");
			if (cpuid.nent)
				tprints("...");
			tprints("]");

		} else {
			struct kvm_cpuid_entry2 entry;
			print_array(tcp, arg + sizeof(cpuid), cpuid.nent,
				    &entry, sizeof(entry), tfetch_mem,
				    print_kvm_cpuid_entry, NULL);
		}
		tprints("}");
	}

	return RVAL_IOCTL_DECODED;
}
# endif /* HAVE_STRUCT_KVM_CPUID2 */

# ifdef HAVE_STRUCT_KVM_SREGS
static int
kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code,
		       const kernel_ulong_t arg)
{
	struct kvm_sregs sregs;

	if (code == KVM_GET_SREGS && entering(tcp))
		return 0;

	tprints(", ");
	if (!umove_or_printaddr(tcp, arg, &sregs))
		arch_print_kvm_sregs(tcp, arg, &sregs);

	return RVAL_IOCTL_DECODED;
}
# endif /* HAVE_STRUCT_KVM_SREGS */

# include "xlat/kvm_cap.h"
static int
kvm_ioctl_decode_check_extension(struct tcb *const tcp, const unsigned int code,
				 const kernel_ulong_t arg)
{
	tprints(", ");
	printxval_index(kvm_cap, arg, "KVM_CAP_???");
	return RVAL_IOCTL_DECODED;
}

# include "xlat/kvm_exit_reason.h"
static void
kvm_ioctl_run_attach_auxstr(struct tcb *const tcp,
			    struct vcpu_info *info)

{
	static struct kvm_run vcpu_run_struct;

	if (info->mmap_len < sizeof(vcpu_run_struct))
		return;

	if (umove(tcp, info->mmap_addr, &vcpu_run_struct) < 0)
		return;

	tcp->auxstr = xlat_idx(kvm_exit_reason, ARRAY_SIZE(kvm_exit_reason) - 1,
			       vcpu_run_struct.exit_reason);
	if (!tcp->auxstr)
		tcp->auxstr = "KVM_EXIT_???";
}

static int
kvm_ioctl_decode_run(struct tcb *const tcp)
{

	if (entering(tcp))
		return 0;

	int r = RVAL_DECODED;

	if (syserror(tcp))
		return r;

	if (dump_kvm_run_structure) {
		tcp->auxstr = NULL;
		int fd = tcp->u_arg[0];
		struct vcpu_info *info = vcpu_get_info(tcp, fd);

		if (info) {
			kvm_ioctl_run_attach_auxstr(tcp, info);
			if (tcp->auxstr)
				r |= RVAL_STR;
		}
	}

	return r;
}

int
kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
{
	switch (code) {
	case KVM_CREATE_VCPU:
		return kvm_ioctl_create_vcpu(tcp, arg);

# ifdef HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION
	case KVM_SET_USER_MEMORY_REGION:
		return kvm_ioctl_set_user_memory_region(tcp, arg);
# endif

# ifdef HAVE_STRUCT_KVM_REGS
	case KVM_SET_REGS:
	case KVM_GET_REGS:
		return kvm_ioctl_decode_regs(tcp, code, arg);
# endif

# ifdef HAVE_STRUCT_KVM_SREGS
	case KVM_SET_SREGS:
	case KVM_GET_SREGS:
		return kvm_ioctl_decode_sregs(tcp, code, arg);
# endif

# ifdef HAVE_STRUCT_KVM_CPUID2
       case KVM_SET_CPUID2:
       case KVM_GET_SUPPORTED_CPUID:
#  ifdef KVM_GET_EMULATED_CPUID
       case KVM_GET_EMULATED_CPUID:
#  endif
               return kvm_ioctl_decode_cpuid2(tcp, code, arg);
# endif

	case KVM_CHECK_EXTENSION:
		return kvm_ioctl_decode_check_extension(tcp, code, arg);

	case KVM_CREATE_VM:
		return RVAL_DECODED | RVAL_FD;

	case KVM_RUN:
		return kvm_ioctl_decode_run(tcp);

	case KVM_GET_VCPU_MMAP_SIZE:
	case KVM_GET_API_VERSION:
	default:
		return RVAL_DECODED;
	}
}

void
kvm_run_structure_decoder_init(void)
{
	dump_kvm_run_structure = true;
	mmap_cache_enable();
}

#endif /* HAVE_LINUX_KVM_H */
