new file mode 100644
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_X86_KVMI_H
+#define _UAPI_ASM_X86_KVMI_H
+
+/*
+ * KVMI x86 specific structures and definitions
+ *
+ */
+
+#include <asm/kvm.h>
+#include <linux/types.h>
+
+#define KVMI_EVENT_UNHOOK 0
+#define KVMI_EVENT_CR 1 /* control register was modified */
+#define KVMI_EVENT_MSR 2 /* model specific reg. was modified */
+#define KVMI_EVENT_XSETBV 3 /* ext. control register was modified */
+#define KVMI_EVENT_BREAKPOINT 4 /* breakpoint was reached */
+#define KVMI_EVENT_HYPERCALL 5 /* user hypercall */
+#define KVMI_EVENT_PF 6 /* hyp. page fault was encountered */
+#define KVMI_EVENT_TRAP 7 /* trap was injected */
+#define KVMI_EVENT_DESCRIPTOR 8 /* descriptor table access */
+#define KVMI_EVENT_CREATE_VCPU 9
+#define KVMI_EVENT_PAUSE_VCPU 10
+/* TODO: find a way to split the events between common and arch dependent */
+#define KVMI_NUM_EVENTS 11 /* increment with each added event */
+
+#define KVMI_EVENT_UNHOOK_FLAG (1 << KVMI_EVENT_UNHOOK)
+#define KVMI_EVENT_CR_FLAG (1 << KVMI_EVENT_CR)
+#define KVMI_EVENT_MSR_FLAG (1 << KVMI_EVENT_MSR)
+#define KVMI_EVENT_XSETBV_FLAG (1 << KVMI_EVENT_XSETBV)
+#define KVMI_EVENT_BREAKPOINT_FLAG (1 << KVMI_EVENT_BREAKPOINT)
+#define KVMI_EVENT_HYPERCALL_FLAG (1 << KVMI_EVENT_HYPERCALL)
+#define KVMI_EVENT_PF_FLAG (1 << KVMI_EVENT_PF)
+#define KVMI_EVENT_TRAP_FLAG (1 << KVMI_EVENT_TRAP)
+#define KVMI_EVENT_DESCRIPTOR_FLAG (1 << KVMI_EVENT_DESCRIPTOR)
+#define KVMI_EVENT_CREATE_VCPU_FLAG (1 << KVMI_EVENT_CREATE_VCPU)
+#define KVMI_EVENT_PAUSE_VCPU_FLAG (1 << KVMI_EVENT_PAUSE_VCPU)
+
+#define KVMI_EVENT_ACTION_CONTINUE 0
+#define KVMI_EVENT_ACTION_RETRY 1
+#define KVMI_EVENT_ACTION_CRASH 2
+
+#define KVMI_KNOWN_VCPU_EVENTS ( \
+ KVMI_EVENT_CR_FLAG | \
+ KVMI_EVENT_MSR_FLAG | \
+ KVMI_EVENT_XSETBV_FLAG | \
+ KVMI_EVENT_BREAKPOINT_FLAG | \
+ KVMI_EVENT_HYPERCALL_FLAG | \
+ KVMI_EVENT_PF_FLAG | \
+ KVMI_EVENT_TRAP_FLAG | \
+ KVMI_EVENT_DESCRIPTOR_FLAG | \
+ KVMI_EVENT_PAUSE_VCPU_FLAG)
+
+#define KVMI_KNOWN_VM_EVENTS ( \
+ KVMI_EVENT_CREATE_VCPU_FLAG | \
+ KVMI_EVENT_UNHOOK_FLAG)
+
+#define KVMI_KNOWN_EVENTS (KVMI_KNOWN_VCPU_EVENTS | KVMI_KNOWN_VM_EVENTS)
+
+#define KVMI_ALLOWED_VM_EVENT(event_id, event_mask) \
+ ((1 << (event_id)) & ((event_mask) & KVMI_KNOWN_VM_EVENTS))
+#define KVMI_ALLOWED_VCPU_EVENT(event_id, event_mask) \
+ ((1 << (event_id)) & ((event_mask) & KVMI_KNOWN_VCPU_EVENTS))
+
+#define KVMI_PAGE_ACCESS_R (1 << 0)
+#define KVMI_PAGE_ACCESS_W (1 << 1)
+#define KVMI_PAGE_ACCESS_X (1 << 2)
+
+struct kvmi_event_cr {
+ __u16 cr;
+ __u16 padding[3];
+ __u64 old_value;
+ __u64 new_value;
+};
+
+struct kvmi_event_msr {
+ __u32 msr;
+ __u32 padding;
+ __u64 old_value;
+ __u64 new_value;
+};
+
+struct kvmi_event_breakpoint {
+ __u64 gpa;
+};
+
+struct kvmi_event_pf {
+ __u64 gva;
+ __u64 gpa;
+ __u32 mode;
+ __u32 padding;
+};
+
+struct kvmi_event_trap {
+ __u32 vector;
+ __u32 type;
+ __u32 error_code;
+ __u32 padding;
+ __u64 cr2;
+};
+
+#define KVMI_DESC_IDTR 1
+#define KVMI_DESC_GDTR 2
+#define KVMI_DESC_LDTR 3
+#define KVMI_DESC_TR 4
+
+struct kvmi_event_descriptor {
+ union {
+ struct {
+ __u32 instr_info;
+ __u32 padding;
+ __u64 exit_qualification;
+ } vmx;
+ struct {
+ __u64 exit_info;
+ __u64 padding;
+ } svm;
+ } arch;
+ __u8 descriptor;
+ __u8 write;
+ __u8 padding[6];
+};
+
+struct kvmi_event {
+ __u32 event;
+ __u16 vcpu;
+ __u8 mode; /* 2, 4 or 8 */
+ __u8 padding;
+ struct kvm_regs regs;
+ struct kvm_sregs sregs;
+ struct {
+ __u64 sysenter_cs;
+ __u64 sysenter_esp;
+ __u64 sysenter_eip;
+ __u64 efer;
+ __u64 star;
+ __u64 lstar;
+ __u64 cstar;
+ __u64 pat;
+ __u64 shadow_gs;
+ } msrs;
+};
+
+struct kvmi_event_cr_reply {
+ __u64 new_val;
+};
+
+struct kvmi_event_msr_reply {
+ __u64 new_val;
+};
+
+struct kvmi_event_pf_reply {
+ __u8 singlestep;
+ __u8 rep_complete;
+ __u16 padding;
+ __u32 ctx_size;
+ __u8 ctx_data[256];
+};
+
+struct kvmi_control_cr {
+ __u16 vcpu;
+ __u8 enable;
+ __u8 padding;
+ __u32 cr;
+};
+
+struct kvmi_control_msr {
+ __u16 vcpu;
+ __u8 enable;
+ __u8 padding;
+ __u32 msr;
+};
+
+struct kvmi_guest_info {
+ __u16 vcpu_count;
+ __u16 padding1;
+ __u32 padding2;
+ __u64 tsc_speed;
+};
+
+struct kvmi_inject_exception {
+ __u16 vcpu;
+ __u8 nr;
+ __u8 has_error;
+ __u16 error_code;
+ __u16 padding;
+ __u64 address;
+};
+
+struct kvmi_get_registers {
+ __u16 vcpu;
+ __u16 nmsrs;
+ __u16 padding[2];
+ __u32 msrs_idx[0];
+};
+
+struct kvmi_get_registers_reply {
+ __u32 mode;
+ __u32 padding;
+ struct kvm_regs regs;
+ struct kvm_sregs sregs;
+ struct kvm_msrs msrs;
+};
+
+struct kvmi_set_registers {
+ __u16 vcpu;
+ __u16 padding[3];
+ struct kvm_regs regs;
+};
+
+struct kvmi_get_cpuid {
+ __u16 vcpu;
+ __u16 padding[3];
+ __u32 function;
+ __u32 index;
+};
+
+struct kvmi_get_cpuid_reply {
+ __u32 eax;
+ __u32 ebx;
+ __u32 ecx;
+ __u32 edx;
+};
+
+struct kvmi_get_xsave {
+ __u16 vcpu;
+ __u16 padding[3];
+};
+
+struct kvmi_get_xsave_reply {
+ __u32 region[0];
+};
+
+#endif /* _UAPI_ASM_X86_KVMI_H */
@@ -976,6 +976,8 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_EXCEPTION_PAYLOAD 164
#define KVM_CAP_ARM_VM_IPA_SIZE 165
+#define KVM_CAP_INTROSPECTION 999
+
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
@@ -1501,6 +1503,16 @@ struct kvm_sev_dbg {
__u32 len;
};
+struct kvm_introspection {
+ int fd;
+ __u32 padding;
+ __u32 commands;
+ __u32 events;
+ __u8 uuid[16];
+};
+#define KVM_INTROSPECTION_HOOK _IOW(KVMIO, 0xff, struct kvm_introspection)
+#define KVM_INTROSPECTION_UNHOOK _IO(KVMIO, 0xfe)
+
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
@@ -10,13 +10,18 @@
* - kvm_para_available
*/
-/* Return values for hypercalls */
+/* Return values for hypercalls and VM introspection */
#define KVM_ENOSYS 1000
#define KVM_EFAULT EFAULT
#define KVM_EINVAL EINVAL
#define KVM_E2BIG E2BIG
#define KVM_EPERM EPERM
#define KVM_EOPNOTSUPP 95
+#define KVM_EAGAIN 11
+#define KVM_EBUSY EBUSY
+#define KVM_ENOENT ENOENT
+#define KVM_ENOMEM ENOMEM
+#define KVM_EACCES EACCES
#define KVM_HC_VAPIC_POLL_IRQ 1
#define KVM_HC_MMU_OP 2
@@ -29,6 +34,10 @@
#define KVM_HC_CLOCK_PAIRING 9
#define KVM_HC_SEND_IPI 10
+#define KVM_HC_MEM_MAP 32
+#define KVM_HC_MEM_UNMAP 33
+#define KVM_HC_XEN_HVM_OP 34 /* Xen's __HYPERVISOR_hvm_op */
+
/*
* hypercalls use architecture specific
*/
new file mode 100644
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __UAPI_KVMI_H__
+#define __UAPI_KVMI_H__
+
+/*
+ * KVMI specific structures and definitions
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/kvmi.h>
+
+#define KVMI_VERSION 0x00000001
+
+#define KVMI_GET_VERSION 1
+#define KVMI_GET_GUEST_INFO 3
+#define KVMI_GET_REGISTERS 6
+#define KVMI_SET_REGISTERS 7
+#define KVMI_GET_PAGE_ACCESS 10
+#define KVMI_SET_PAGE_ACCESS 11
+#define KVMI_INJECT_EXCEPTION 12
+#define KVMI_READ_PHYSICAL 13
+#define KVMI_WRITE_PHYSICAL 14
+#define KVMI_GET_MAP_TOKEN 15
+#define KVMI_CONTROL_EVENTS 17
+#define KVMI_CONTROL_CR 18
+#define KVMI_CONTROL_MSR 19
+#define KVMI_EVENT 23
+#define KVMI_EVENT_REPLY 24
+#define KVMI_GET_CPUID 25
+#define KVMI_GET_XSAVE 26
+#define KVMI_PAUSE_ALL_VCPUS 27
+#define KVMI_CONTROL_VM_EVENTS 28
+
+/* TODO: find a way to split the commands between common and arch dependent */
+
+#define KVMI_GET_VERSION_FLAG (1 << KVMI_GET_VERSION)
+#define KVMI_GET_GUEST_INFO_FLAG (1 << KVMI_GET_GUEST_INFO)
+#define KVMI_GET_REGISTERS_FLAG (1 << KVMI_GET_REGISTERS)
+#define KVMI_SET_REGISTERS_FLAG (1 << KVMI_SET_REGISTERS)
+#define KVMI_GET_PAGE_ACCESS_FLAG (1 << KVMI_GET_PAGE_ACCESS)
+#define KVMI_SET_PAGE_ACCESS_FLAG (1 << KVMI_SET_PAGE_ACCESS)
+#define KVMI_INJECT_EXCEPTION_FLAG (1 << KVMI_INJECT_EXCEPTION)
+#define KVMI_READ_PHYSICAL_FLAG (1 << KVMI_READ_PHYSICAL)
+#define KVMI_WRITE_PHYSICAL_FLAG (1 << KVMI_WRITE_PHYSICAL)
+#define KVMI_GET_MAP_TOKEN_FLAG (1 << KVMI_GET_MAP_TOKEN)
+#define KVMI_CONTROL_EVENTS_FLAG (1 << KVMI_CONTROL_EVENTS)
+#define KVMI_CONTROL_CR_FLAG (1 << KVMI_CONTROL_CR)
+#define KVMI_CONTROL_MSR_FLAG (1 << KVMI_CONTROL_MSR)
+#define KVMI_EVENT_FLAG (1 << KVMI_EVENT)
+#define KVMI_EVENT_REPLY_FLAG (1 << KVMI_EVENT_REPLY)
+#define KVMI_GET_CPUID_FLAG (1 << KVMI_GET_CPUID)
+#define KVMI_GET_XSAVE_FLAG (1 << KVMI_GET_XSAVE)
+#define KVMI_PAUSE_ALL_VCPUS_FLAG (1 << KVMI_PAUSE_ALL_VCPUS)
+#define KVMI_CONTROL_VM_EVENTS_FLAG (1 << KVMI_CONTROL_VM_EVENTS)
+
+#define KVMI_KNOWN_COMMANDS (\
+ KVMI_GET_VERSION_FLAG | \
+ KVMI_GET_GUEST_INFO_FLAG | \
+ KVMI_GET_REGISTERS_FLAG | \
+ KVMI_SET_REGISTERS_FLAG | \
+ KVMI_GET_PAGE_ACCESS_FLAG | \
+ KVMI_SET_PAGE_ACCESS_FLAG | \
+ KVMI_INJECT_EXCEPTION_FLAG | \
+ KVMI_READ_PHYSICAL_FLAG | \
+ KVMI_WRITE_PHYSICAL_FLAG | \
+ KVMI_GET_MAP_TOKEN_FLAG | \
+ KVMI_CONTROL_EVENTS_FLAG | \
+ KVMI_CONTROL_CR_FLAG | \
+ KVMI_CONTROL_MSR_FLAG | \
+ KVMI_EVENT_FLAG | \
+ KVMI_EVENT_REPLY_FLAG | \
+ KVMI_GET_CPUID_FLAG | \
+ KVMI_GET_XSAVE_FLAG | \
+ KVMI_PAUSE_ALL_VCPUS_FLAG | \
+ KVMI_CONTROL_VM_EVENTS_FLAG)
+
+#define KVMI_ALLOWED_COMMAND(cmd_id, cmd_mask) \
+ ((1 << (cmd_id)) & ((cmd_mask) & KVMI_KNOWN_COMMANDS))
+
+#define KVMI_MSG_SIZE 4096
+
+struct kvmi_msg_hdr {
+ __u16 id;
+ __u16 size;
+ __u32 seq;
+};
+
+struct kvmi_error_code {
+ __s32 err;
+ __u32 padding;
+};
+
+struct kvmi_get_version_reply {
+ __u32 version;
+ __u32 commands;
+ __u32 events;
+ __u32 padding;
+};
+
+struct kvmi_get_guest_info {
+ __u16 vcpu;
+ __u16 padding[3];
+};
+
+struct kvmi_get_guest_info_reply {
+ __u32 vcpu_count;
+ __u32 padding;
+ __u64 tsc_speed;
+};
+
+struct kvmi_pause_all_vcpus_reply {
+ __u32 vcpu_count;
+ __u32 padding;
+};
+
+struct kvmi_event_reply {
+ __u32 action;
+ __u32 event;
+};
+
+struct kvmi_control_events {
+ __u16 vcpu;
+ __u16 padding;
+ __u32 events;
+};
+
+struct kvmi_control_vm_events {
+ __u32 events;
+ __u32 padding;
+};
+
+struct kvmi_get_page_access {
+ __u16 vcpu;
+ __u16 count;
+ __u16 view;
+ __u16 padding;
+ __u64 gpa[0];
+};
+
+struct kvmi_get_page_access_reply {
+ __u8 access[0];
+};
+
+struct kvmi_page_access_entry {
+ __u64 gpa;
+ __u8 access;
+ __u8 padding[7];
+};
+
+struct kvmi_set_page_access {
+ __u16 vcpu;
+ __u16 count;
+ __u16 view;
+ __u16 padding;
+ struct kvmi_page_access_entry entries[0];
+};
+
+struct kvmi_read_physical {
+ __u64 gpa;
+ __u64 size;
+};
+
+struct kvmi_write_physical {
+ __u64 gpa;
+ __u64 size;
+ __u8 data[0];
+};
+
+struct kvmi_map_mem_token {
+ __u64 token[4];
+};
+
+struct kvmi_get_map_token_reply {
+ struct kvmi_map_mem_token token;
+};
+
+/* Map other guest's gpa to local gva */
+struct kvmi_mem_map {
+ struct kvmi_map_mem_token token;
+ __u64 gpa;
+ __u64 gva;
+};
+
+/*
+ * ioctls for /dev/kvmmem
+ */
+#define KVM_INTRO_MEM_MAP _IOW('i', 0x01, struct kvmi_mem_map)
+#define KVM_INTRO_MEM_UNMAP _IOW('i', 0x02, unsigned long)
+
+#endif /* __UAPI_KVMI_H__ */