/*
 * This is an Arm64 SPCI port of the x86 code accompanying "Using the KVM API"
 * (https://lwn.net/Articles/658511/).
 *
 * Original x86 code in the file kvmtest.c and https://lwn.net/Articles/658512/.
 *
 * Copyright (C) 2020 Google LLC
 * Author: Andrew Scull <ascull@google.com>
 */

/* Sample code for /dev/kvm API
 *
 * Copyright (c) 2015 Intel Corporation
 * Author: Josh Triplett <josh@joshtriplett.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#include <err.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/kvm.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

#define KVM_CAP_ARM_SPCI			182
#define KVM_VM_TYPE_ARM_SPCI_ATTACH		0x8000UL
#define KVM_VM_TYPE_ARM_SPCI_ATTACH_ID_SHIFT	8
#define KVM_VM_TYPE_ARM_SPCI_ATTACH_ID_MASK			\
	(0x7fUL << KVM_VM_TYPE_ARM_SPCI_ATTACH_ID_SHIFT)
#define KVM_VM_TYPE_ARM_SPCI_ATTACH_ID(x)			\
	(((x) << KVM_VM_TYPE_ARM_SPCI_ATTACH_ID_SHIFT)		\
	& KVM_VM_TYPE_ARM_SPCI_ATTACH_ID_MASK)

static struct {
	int partition_id;
	bool aarch32;
} opts = {
	.partition_id = -1,
	.aarch32 = false,
};

enum options {
	OPT_HELP,
	OPT_PARTITION_ID,
	OPT_AARCH32,
};

const char short_opts[] = "";
const struct option long_opts[] = {
	{"help",		no_argument,		NULL,	OPT_HELP},
	{"partition_id",	required_argument,	NULL,	OPT_PARTITION_ID},
	{"aarch32",		no_argument,		NULL,	OPT_AARCH32,
	{NULL,			0,			NULL,	0},
};

void usage(void)
{
	puts("Arguments:\n"
	     "\t--help\t\t\tDisplay this information\n"
	     "\t--partition_id id\tID of partition to attach to\n");
}

int handle_opts(int argc, char **argv)
{
	int opt;
	while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
		switch (opt) {
			case OPT_PARTITION_ID:
				opts.partition_id = strtol(optarg, NULL, 10);
				break;
			case OPT_AARCH32:
				opts.aarch32 = true;
				break;
			case OPT_HELP:
			default:
				goto err;
		}
	}

	if (opts.partition_id < 0)
		goto err;

	if (opts.aarch32)
		errx(1, "AArch32 not yet supported");

	return 0;

err:
	usage();
	return -1;
}

int main(int argc, char **argv)
{
	int kvm, vmfd, vcpufd, ret;

	size_t mmap_size;
	struct kvm_run *run = NULL;
	unsigned long vm_type;
	struct kvm_vcpu_init vcpu_init;

	ret = handle_opts(argc, argv);
	if (ret < 0)
		err(1, "Bad arguments");

	kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC);
	if (kvm < 0)
		err(1, "/dev/kvm");

	/* Ensure this is the stable version of the KVM API (defined as 12) */
	ret = ioctl(kvm, KVM_GET_API_VERSION, NULL);
	if (ret < 0)
		err(1, "KVM_GET_API_VERSION");
	if (ret != 12)
		errx(1, "KVM_GET_API_VERSION %d, expected 12", ret);

	ret = ioctl(kvm, KVM_CHECK_EXTENSION, KVM_CAP_ARM_SPCI);
	if (ret == -1)
		err(1, "KVM_CHECK_EXTENSION KVM_CAP_ARM_SPCI");
	if (!ret)
		errx(1, "KVM_CAP_ARM_SPCI unavailable");

	vm_type = KVM_VM_TYPE_ARM_SPCI_ATTACH
		| KVM_VM_TYPE_ARM_SPCI_ATTACH_ID(opts.partition_id);
	vmfd = ioctl(kvm, KVM_CREATE_VM, vm_type);
	if (vmfd < 0)
		err(1, "KVM_CREATE_VM");

	/* Create one CPU to run in the VM. */
	vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0);
	if (vcpufd < 0)
		err(1, "KVM_CREATE_VCPU");

	/* Map the shared kvm_run structure and following data. */
	ret = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL);
	if (ret < 0)
		err(1, "KVM_GET_VCPU_MMAP_SIZE");
	mmap_size = ret;
	if (mmap_size < sizeof(*run))
		errx(1, "KVM_GET_VCPU_MMAP_SIZE unexpectedly small");
	run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0);
	if (!run)
		err(1, "mmap vcpu");

	/* Query KVM for preferred CPU target type that can be emulated. */
	ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init);
	if (ret < 0)
		err(1, "KVM_PREFERRED_TARGET");

	/* Initialize VCPU with the preferred type obtained above. */
	ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init);
	if (ret < 0)
		err(1, "KVM_ARM_VCPU_INIT");

	/*
	 * Enable debug so that brk instruction would exit KVM_RUN with
	 * KVM_EXIT_DEBUG.
	 */
	struct kvm_guest_debug debug = {
		.control = KVM_GUESTDBG_ENABLE,
	};
	ret = ioctl(vcpufd, KVM_SET_GUEST_DEBUG, &debug);
	if (ret < 0)
		err(1, "KVM_SET_GUEST_DEBUG");

	/* Repeatedly run code and handle VM exits. */
	for (;;) {
		ret = ioctl(vcpufd, KVM_RUN, NULL);
		if (ret < 0)
			err(1, "KVM_RUN");
		switch (run->exit_reason) {
		case KVM_EXIT_DEBUG:
			puts("KVM_EXIT_DEBUG");
			return 0;
		case KVM_EXIT_MMIO:
			uint64_t payload = *(uint64_t*)(run->mmio.data); /* sorry */
			puts("KVM_EXIT_MMIO... that shouldn't happen :/");
			printf("  addr = 0x%llx, len = %u, is_write = %u, data = 0x%08llx\n",
			       run->mmio.phys_addr, run->mmio.len,
			       run->mmio.is_write, payload);
			errx(1, "Bailing out");
			break;
		}
		case KVM_EXIT_FAIL_ENTRY:
			errx(1, "KVM_EXIT_FAIL_ENTRY: hardware_entry_failure_reason = 0x%llx",
				 (unsigned long long)run->fail_entry.hardware_entry_failure_reason);
		case KVM_EXIT_INTERNAL_ERROR:
			errx(1, "KVM_EXIT_INTERNAL_ERROR: suberror = 0x%x",
				run->internal.suberror);
		default:
			errx(1, "exit_reason = 0x%x", run->exit_reason);
		}
	}
}
