#include "config.h"

#ifdef USE_KVM

#include <linux/ioctl.h>
#include <linux/kvm.h>
#include "compat.h"
#include "ioctls.h"
#include "utils.h"

static const struct ioctl kvm_ioctls[] = {
  IOCTL(KVM_SET_MEMORY_REGION, 0, 0),
  IOCTL(KVM_CREATE_VCPU, 0, 0),
  IOCTL(KVM_GET_DIRTY_LOG, 0, 0),
  IOCTL(KVM_SET_NR_MMU_PAGES, 0, 0),
  IOCTL(KVM_GET_NR_MMU_PAGES, 0, 0),
  IOCTL(KVM_SET_USER_MEMORY_REGION, 0, 0),
  IOCTL(KVM_SET_TSS_ADDR, 0, 0),
  IOCTL(KVM_SET_IDENTITY_MAP_ADDR, 0, 0),
  IOCTL(KVM_S390_UCAS_MAP, 0, 0),
  IOCTL(KVM_S390_UCAS_UNMAP, 0, 0),
  IOCTL(KVM_S390_VCPU_FAULT, 0, 0),
  IOCTL(KVM_CREATE_IRQCHIP, 0, 0),
  IOCTL(KVM_IRQ_LINE, 0, 0),
  IOCTL(KVM_GET_IRQCHIP, 0, 0),
  IOCTL(KVM_SET_IRQCHIP, 0, 0),
  IOCTL(KVM_CREATE_PIT, 0, 0),
  IOCTL(KVM_IRQ_LINE_STATUS, 0, 0),
  IOCTL(KVM_REGISTER_COALESCED_MMIO, 0, 0),
  IOCTL(KVM_UNREGISTER_COALESCED_MMIO, 0, 0),
  IOCTL(KVM_ASSIGN_PCI_DEVICE, 0, 0),
  IOCTL(KVM_ASSIGN_IRQ, 0, 0),
  IOCTL(KVM_ASSIGN_DEV_IRQ, 0, 0),
  IOCTL(KVM_REINJECT_CONTROL, 0, 0),
  IOCTL(KVM_DEASSIGN_PCI_DEVICE, 0, 0),
  IOCTL(KVM_ASSIGN_SET_MSIX_NR, 0, 0),
  IOCTL(KVM_ASSIGN_SET_MSIX_ENTRY, 0, 0),
  IOCTL(KVM_DEASSIGN_DEV_IRQ, 0, 0),
  IOCTL(KVM_IRQFD, 0, 0),
  IOCTL(KVM_CREATE_PIT2, 0, 0),
  IOCTL(KVM_SET_BOOT_CPU_ID, 0, 0),
  IOCTL(KVM_IOEVENTFD, 0, 0),
  IOCTL(KVM_SET_CLOCK, 0, 0),
  IOCTL(KVM_GET_CLOCK, 0, 0),
  IOCTL(KVM_PPC_GET_PVINFO, 0, 0),
  IOCTL(KVM_SET_TSC_KHZ, 0, 0),
  IOCTL(KVM_GET_TSC_KHZ, 0, 0),
  IOCTL(KVM_ASSIGN_SET_INTX_MASK, 0, 0),
  IOCTL(KVM_SIGNAL_MSI, 0, 0),
#ifdef X86
  IOCTL(KVM_SET_MEMORY_ALIAS, 0, 0),
  IOCTL(KVM_GET_PIT, 0, 0),
  IOCTL(KVM_SET_PIT, 0, 0),
  IOCTL(KVM_GET_PIT2, 0, 0),
  IOCTL(KVM_SET_PIT2, 0, 0),
  IOCTL(KVM_SET_GSI_ROUTING, 0, 0),
  IOCTL(KVM_XEN_HVM_CONFIG, 0, 0),
  IOCTL(KVM_GET_MSRS, 0, 0),
  IOCTL(KVM_SET_MSRS, 0, 0),
  IOCTL(KVM_SET_CPUID, 0, 0),
  IOCTL(KVM_GET_LAPIC, 0, 0),
  IOCTL(KVM_SET_LAPIC, 0, 0),
  IOCTL(KVM_SET_CPUID2, 0, 0),
  IOCTL(KVM_GET_CPUID2, 0, 0),
  IOCTL(KVM_X86_SET_MCE, 0, 0),
  IOCTL(KVM_GET_VCPU_EVENTS, 0, 0),
  IOCTL(KVM_SET_VCPU_EVENTS, 0, 0),
  IOCTL(KVM_GET_DEBUGREGS, 0, 0),
  IOCTL(KVM_SET_DEBUGREGS, 0, 0),
  IOCTL(KVM_GET_XSAVE, 0, 0),
  IOCTL(KVM_SET_XSAVE, 0, 0),
  IOCTL(KVM_GET_XCRS, 0, 0),
  IOCTL(KVM_SET_XCRS, 0, 0),
#endif
#if defined(__powerpc__)
  IOCTL(KVM_PPC_GET_SMMU_INFO, 0, 0),
  IOCTL(KVM_PPC_ALLOCATE_HTAB, 0, 0),
#if defined(KVM_CREATE_SPAPR_TCE)
  IOCTL(KVM_CREATE_SPAPR_TCE, 0, 0),
#endif
#if defined(KVM_ALLOCATE_RMA)
  IOCTL(KVM_ALLOCATE_RMA, 0, 0),
#endif
  IOCTL(KVM_PPC_GET_HTAB_FD, 0, 0),
#endif
#if defined(__arm__) || defined(__aarch64__)
  IOCTL(KVM_ARM_SET_DEVICE_ADDR, 0, 0),
  IOCTL(KVM_ARM_VCPU_INIT, 0, 0),
#endif
  IOCTL(KVM_RUN, 0, 0),
  IOCTL(KVM_GET_REGS, 0, 0),
  IOCTL(KVM_SET_REGS, 0, 0),
  IOCTL(KVM_GET_SREGS, 0, 0),
  IOCTL(KVM_SET_SREGS, 0, 0),
  IOCTL(KVM_TRANSLATE, 0, 0),
  IOCTL(KVM_INTERRUPT, 0, 0),
  IOCTL(KVM_DEBUG_GUEST, 0, 0),
  IOCTL(KVM_SET_SIGNAL_MASK, 0, 0),
  IOCTL(KVM_GET_FPU, 0, 0),
  IOCTL(KVM_SET_FPU, 0, 0),
  IOCTL(KVM_TPR_ACCESS_REPORTING, 0, 0),
  IOCTL(KVM_SET_VAPIC_ADDR, 0, 0),
#if defined(__s390__)
  IOCTL(KVM_S390_INTERRUPT, 0, 0),
  IOCTL(KVM_S390_STORE_STATUS, 0, 0),
  IOCTL(KVM_S390_SET_INITIAL_PSW, 0, 0),
  IOCTL(KVM_S390_INITIAL_RESET, 0, 0),
#endif
  IOCTL(KVM_GET_MP_STATE, 0, 0),
  IOCTL(KVM_SET_MP_STATE, 0, 0),
  IOCTL(KVM_NMI, 0, 0),
  IOCTL(KVM_SET_GUEST_DEBUG, 0, 0),
  IOCTL(KVM_X86_SETUP_MCE, 0, 0),
  IOCTL(KVM_X86_GET_MCE_CAP_SUPPORTED, 0, 0),
  IOCTL(KVM_IA64_VCPU_GET_STACK, 0, 0),
  IOCTL(KVM_IA64_VCPU_SET_STACK, 0, 0),
  IOCTL(KVM_ENABLE_CAP, 0, 0),
  IOCTL(KVM_DIRTY_TLB, 0, 0),
  IOCTL(KVM_GET_ONE_REG, 0, 0),
  IOCTL(KVM_SET_ONE_REG, 0, 0),
  IOCTL(KVM_KVMCLOCK_CTRL, 0, 0),
  IOCTL(KVM_GET_REG_LIST, 0, 0),
};

static const char *const kvm_devs[] = {
	"kvm",
};

static const struct ioctl_group kvm_grp = {
	.devtype = DEV_MISC,
	.devs = kvm_devs,
	.devs_cnt = ARRAY_SIZE(kvm_devs),
	.sanitise = pick_random_ioctl,
	.ioctls = kvm_ioctls,
	.ioctls_cnt = ARRAY_SIZE(kvm_ioctls),
};

REG_IOCTL_GROUP(kvm_grp)

#endif	/* USE_KVM */
