# Copyright 2020 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

include <uapi/linux/fcntl.h>
include <linux/ioctl.h>
include <linux/vmw_vmci_defs.h>
include <drivers/misc/vmw_vmci/vmci_context.h>

resource fd_vmci[fd]

openat$vmci(fd const[AT_FDCWD], file ptr[in, string["/dev/vmci"]], flags const[O_RDWR], mode const[0]) fd_vmci

ioctl$IOCTL_VMCI_INIT_CONTEXT(fd fd_vmci, cmd const[IOCTL_VMCI_INIT_CONTEXT], arg ptr[in, vmci_init_blk])
ioctl$IOCTL_VMCI_DATAGRAM_SEND(fd fd_vmci, cmd const[IOCTL_VMCI_DATAGRAM_SEND], arg ptr[in, vmci_datagram_snd_rcv_info])
ioctl$IOCTL_VMCI_DATAGRAM_RECEIVE(fd fd_vmci, cmd const[IOCTL_VMCI_DATAGRAM_RECEIVE], arg ptr[in, vmci_datagram_snd_rcv_info])
ioctl$IOCTL_VMCI_QUEUEPAIR_ALLOC(fd fd_vmci, cmd const[IOCTL_VMCI_QUEUEPAIR_ALLOC], arg ptr[in, vmci_qp_alloc_info])
ioctl$IOCTL_VMCI_QUEUEPAIR_SETVA(fd fd_vmci, cmd const[IOCTL_VMCI_QUEUEPAIR_SETVA], arg ptr[in, vmci_qp_set_va_info])
ioctl$IOCTL_VMCI_QUEUEPAIR_SETPF(fd fd_vmci, cmd const[IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE], arg ptr[in, vmci_qp_page_file_info])
ioctl$IOCTL_VMCI_QUEUEPAIR_DETACH(fd fd_vmci, cmd const[IOCTL_VMCI_QUEUEPAIR_DETACH], arg ptr[in, vmci_qp_dtch_info])
ioctl$IOCTL_VMCI_CTX_ADD_NOTIFICATION(fd fd_vmci, cmd const[IOCTL_VMCI_CTX_ADD_NOTIFICATION], arg ptr[in, vmci_ctx_info])
ioctl$IOCTL_VMCI_CTX_REMOVE_NOTIFICATION(fd fd_vmci, cmd const[IOCTL_VMCI_CTX_REMOVE_NOTIFICATION], arg ptr[in, vmci_ctx_info])
ioctl$IOCTL_VMCI_CTX_GET_CPT_STATE(fd fd_vmci, cmd const[IOCTL_VMCI_CTX_GET_CPT_STATE], arg ptr[in, vmci_ctx_chkpt_buf_info])
ioctl$IOCTL_VMCI_CTX_SET_CPT_STATE(fd fd_vmci, cmd const[IOCTL_VMCI_CTX_SET_CPT_STATE], arg ptr[in, vmci_ctx_chkpt_buf_info])
ioctl$IOCTL_VMCI_GET_CONTEXT_ID(fd fd_vmci, cmd const[IOCTL_VMCI_GET_CONTEXT_ID], arg ptr[out, int32])
ioctl$IOCTL_VMCI_SET_NOTIFY(fd fd_vmci, cmd const[IOCTL_VMCI_SET_NOTIFY], arg ptr[in, vmci_set_notify_info])
ioctl$IOCTL_VMCI_NOTIFY_RESOURCE(fd fd_vmci, cmd const[IOCTL_VMCI_NOTIFY_RESOURCE], arg ptr[in, vmci_dbell_notify_resource_info])
ioctl$IOCTL_VMCI_NOTIFICATIONS_RECEIVE(fd fd_vmci, cmd const[IOCTL_VMCI_NOTIFICATIONS_RECEIVE], arg ptr[in, vmci_ctx_notify_recv_info])
ioctl$IOCTL_VMCI_VERSION(fd fd_vmci, cmd const[IOCTL_VMCI_VERSION], arg ptr[in, flags[vmci_version, int32]])
ioctl$IOCTL_VMCI_VERSION2(fd fd_vmci, cmd const[IOCTL_VMCI_VERSION2], arg ptr[in, flags[vmci_version, int32]])

vmci_init_blk {
	cid	vmaddr_cid
	flags	flags[vmci_privilege, int32]
}

vmci_handle {
	context	vmaddr_cid
	rsc	int32
}

vmci_datagram {
	dst		vmci_handle
	src		vmci_handle
	payload_size	len[payload, int64]
	payload		array[int8, 1024]
}

vmci_datagram_snd_rcv_info {
	addr	ptr64[in, vmci_datagram]
	len	len[addr, int32]
	result	int32
}

vmci_qp_alloc_info {
	handle		vmci_handle
	peer		vmaddr_cid
	flags		flags[vmci_qp, int32]
	produce_size	int64
	consume_size	int64
	ppn_va		int64
	num_ppns	int64
	result		int32
	version		int32
}

vmci_qp_set_va_info {
	handle		vmci_handle
	va		int64
	num_ppns	int64
	version		int32
	result		int32
}

vmci_qp_page_file_info {
	handle			vmci_handle
	produce_page_file	int64
	consume_page_file	int64
	produce_page_file_size	int64
	consume_page_file_size	int64
	result			int32
	version			int32
	produce_va		int64
	consume_va		int64
}

vmci_qp_dtch_info {
	handle	vmci_handle
	result	int32
	_pad	int32
}

vmci_ctx_info {
	remote_cid	vmaddr_cid
	result		int32
}

vmci_ctx_chkpt_buf_info {
	cpt_buf		ptr64[in, array[int32, 1024]]
	cpt_type	flags[vmci_cpt_state, int32]
	buf_size	len[cpt_buf, int32]
	result		int32
	_pad		const[0, int32]
}

vmci_set_notify_info {
	notify_uva	int64
	result		int32
	_pad		int32
}

vmci_dbell_notify_resource_info {
	handle	vmci_handle
	rsc	flags[vmci_notify_resource, int16]
	action	flags[vmci_notify_action, int16]
	result	int32
}

vmci_ctx_notify_recv_info {
	db_handle_buf_uva	int64
	db_handle_buf_size	int64
	qp_handle_buf_uva	int64
	qp_handle_buf_size	int64
	result			int32
	_pad			int32
}

vmci_privilege = VMCI_NO_PRIVILEGE_FLAGS, VMCI_PRIVILEGE_FLAG_RESTRICTED, VMCI_PRIVILEGE_FLAG_TRUSTED
vmci_qp = VMCI_QPFLAG_ATTACH_ONLY, VMCI_QPFLAG_LOCAL, VMCI_QPFLAG_NONBLOCK, VMCI_QPFLAG_PINNED
vmci_version = VMCI_VERSION_NOVMVM, VMCI_VERSION_NOTIFY, VMCI_VERSION_HOSTQP, VMCI_VERSION_PREHOSTQP, VMCI_VERSION_PREVERS2
vmci_cpt_state = VMCI_NOTIFICATION_CPT_STATE, VMCI_WELLKNOWN_CPT_STATE, VMCI_DG_OUT_STATE, VMCI_DG_IN_STATE, VMCI_DG_IN_SIZE_STATE, VMCI_DOORBELL_CPT_STATE
vmci_notify_resource = VMCI_NOTIFY_RESOURCE_QUEUE_PAIR, VMCI_NOTIFY_RESOURCE_DOOR_BELL
vmci_notify_action = VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY, VMCI_NOTIFY_RESOURCE_ACTION_CREATE, VMCI_NOTIFY_RESOURCE_ACTION_DESTROY

# These are defined in kernel source files.
define VMCI_NOTIFICATION_CPT_STATE	1
define VMCI_WELLKNOWN_CPT_STATE	2
define VMCI_DG_OUT_STATE	3
define VMCI_DG_IN_STATE	4
define VMCI_DG_IN_SIZE_STATE	5
define VMCI_DOORBELL_CPT_STATE	6
define VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY	0
define VMCI_NOTIFY_RESOURCE_ACTION_CREATE	1
define VMCI_NOTIFY_RESOURCE_ACTION_DESTROY	2
define VMCI_NOTIFY_RESOURCE_QUEUE_PAIR	0
define VMCI_NOTIFY_RESOURCE_DOOR_BELL	1
