120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMware VMCI Driver 320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Copyright (C) 2012 VMware, Inc. All rights reserved. 520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * This program is free software; you can redistribute it and/or modify it 720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * under the terms of the GNU General Public License as published by the 820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Free Software Foundation version 2 and no later version. 920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 1020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * This program is distributed in the hope that it will be useful, but 1120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * for more details. 1420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 1520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 1620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#ifndef _VMW_VMCI_DEF_H_ 1720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define _VMW_VMCI_DEF_H_ 1820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 1920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#include <linux/atomic.h> 2020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 2120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Register offsets. */ 2220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_STATUS_ADDR 0x00 2320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CONTROL_ADDR 0x04 2420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_ICR_ADDR 0x08 2520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_IMR_ADDR 0x0c 2620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_DATA_OUT_ADDR 0x10 2720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_DATA_IN_ADDR 0x14 2820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CAPS_ADDR 0x18 2920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_RESULT_LOW_ADDR 0x1c 3020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_RESULT_HIGH_ADDR 0x20 3120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 3220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Max number of devices. */ 3320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_DEVICES 1 3420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 3520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Status register bits. */ 3620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_STATUS_INT_ON 0x1 3720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 3820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Control register bits. */ 3920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CONTROL_RESET 0x1 4020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CONTROL_INT_ENABLE 0x2 4120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CONTROL_INT_DISABLE 0x4 4220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 4320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Capabilities register bits. */ 4420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CAPS_HYPERCALL 0x1 4520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CAPS_GUESTCALL 0x2 4620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CAPS_DATAGRAM 0x4 4720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CAPS_NOTIFICATIONS 0x8 4820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 4920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Interrupt Cause register bits. */ 5020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_ICR_DATAGRAM 0x1 5120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_ICR_NOTIFICATION 0x2 5220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 5320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Interrupt Mask register bits. */ 5420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_IMR_DATAGRAM 0x1 5520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_IMR_NOTIFICATION 0x2 5620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 5720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Interrupt type. */ 5820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangenum { 5920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_INTR_TYPE_INTX = 0, 6020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_INTR_TYPE_MSI = 1, 6120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_INTR_TYPE_MSIX = 2, 6220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 6320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 6420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Maximum MSI/MSI-X interrupt vectors in the device. */ 6520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_INTRS 2 6620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 6720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 6820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Supported interrupt vectors. There is one for each ICR value above, 6920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * but here they indicate the position in the vector array/message ID. 7020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 7120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangenum { 7220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_INTR_DATAGRAM = 0, 7320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_INTR_NOTIFICATION = 1, 7420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 7520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 7620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 7720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * A single VMCI device has an upper limit of 128MB on the amount of 7820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * memory that can be used for queue pairs. 7920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 8020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024) 8120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 8220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 8320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Queues with pre-mapped data pages must be small, so that we don't pin 8420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * too much kernel memory (especially on vmkernel). We limit a queuepair to 8520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 32 KB, or 16 KB per queue for symmetrical pairs. 8620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 8720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_PINNED_QP_MEMORY (32 * 1024) 8820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 8920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 9020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * We have a fixed set of resource IDs available in the VMX. 9120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * This allows us to have a very simple implementation since we statically 9220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * know how many will create datagram handles. If a new caller arrives and 9320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * we have run out of slots we can manually increment the maximum size of 9420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * available resource IDs. 9520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 9620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI reserved hypervisor datagram resource IDs. 9720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 9820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangenum { 9920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_RESOURCES_QUERY = 0, 10020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_GET_CONTEXT_ID = 1, 10120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SET_NOTIFY_BITMAP = 2, 10220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_DOORBELL_LINK = 3, 10320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_DOORBELL_UNLINK = 4, 10420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_DOORBELL_NOTIFY = 5, 10520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* 10620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_DATAGRAM_REQUEST_MAP and VMCI_DATAGRAM_REMOVE_MAP are 10720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * obsoleted by the removal of VM to VM communication. 10820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 10920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_DATAGRAM_REQUEST_MAP = 6, 11020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_DATAGRAM_REMOVE_MAP = 7, 11120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_SUBSCRIBE = 8, 11220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_UNSUBSCRIBE = 9, 11320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QUEUEPAIR_ALLOC = 10, 11420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QUEUEPAIR_DETACH = 11, 11520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 11620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* 11720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_VSOCK_VMX_LOOKUP was assigned to 12 for Fusion 3.0/3.1, 11820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * WS 7.0/7.1 and ESX 4.1 11920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 12020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_HGFS_TRANSPORT = 13, 12120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_UNITY_PBRPC_REGISTER = 14, 12220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_RPC_PRIVILEGED = 15, 12320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_RPC_UNPRIVILEGED = 16, 12420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_RESOURCE_MAX = 17, 12520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 12620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 12720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 12820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * struct vmci_handle - Ownership information structure 12920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * @context: The VMX context ID. 13020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * @resource: The resource ID (used for locating in resource hash). 13120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 13220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * The vmci_handle structure is used to track resources used within 13320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * vmw_vmci. 13420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 13520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_handle { 13620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 context; 13720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 resource; 13820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 13920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 14020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define vmci_make_handle(_cid, _rid) \ 14120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang (struct vmci_handle){ .context = _cid, .resource = _rid } 14220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 14320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline bool vmci_handle_is_equal(struct vmci_handle h1, 14420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle h2) 14520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 14620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return h1.context == h2.context && h1.resource == h2.resource; 14720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 14820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 14920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_INVALID_ID ~0 15020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic const struct vmci_handle VMCI_INVALID_HANDLE = { 15120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang .context = VMCI_INVALID_ID, 15220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang .resource = VMCI_INVALID_ID 15320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 15420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 15520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline bool vmci_handle_is_invalid(struct vmci_handle h) 15620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 15720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return vmci_handle_is_equal(h, VMCI_INVALID_HANDLE); 15820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 15920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 16020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 16120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * The below defines can be used to send anonymous requests. 16220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * This also indicates that no response is expected. 16320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 16420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_ANON_SRC_CONTEXT_ID VMCI_INVALID_ID 16520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_ANON_SRC_RESOURCE_ID VMCI_INVALID_ID 16620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic const struct vmci_handle VMCI_ANON_SRC_HANDLE = { 16720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang .context = VMCI_ANON_SRC_CONTEXT_ID, 16820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang .resource = VMCI_ANON_SRC_RESOURCE_ID 16920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 17020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 17120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* The lowest 16 context ids are reserved for internal use. */ 17220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_RESERVED_CID_LIMIT ((u32) 16) 17320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 17420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 17520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Hypervisor context id, used for calling into hypervisor 17620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * supplied services from the VM. 17720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 17820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_HYPERVISOR_CONTEXT_ID 0 17920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 18020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 18120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Well-known context id, a logical context that contains a set of 18220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * well-known services. This context ID is now obsolete. 18320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 18420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_WELL_KNOWN_CONTEXT_ID 1 18520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 18620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 18720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Context ID used by host endpoints. 18820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 18920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_HOST_CONTEXT_ID 2 19020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 19120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CONTEXT_IS_VM(_cid) (VMCI_INVALID_ID != (_cid) && \ 19220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang (_cid) > VMCI_HOST_CONTEXT_ID) 19320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 19420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 19520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * The VMCI_CONTEXT_RESOURCE_ID is used together with vmci_make_handle to make 19620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * handles that refer to a specific context. 19720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 19820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_CONTEXT_RESOURCE_ID 0 19920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 20020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 20120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI error codes. 20220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 20320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangenum { 20420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SUCCESS_QUEUEPAIR_ATTACH = 5, 20520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SUCCESS_QUEUEPAIR_CREATE = 4, 20620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SUCCESS_LAST_DETACH = 3, 20720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SUCCESS_ACCESS_GRANTED = 2, 20820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SUCCESS_ENTRY_DEAD = 1, 20920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SUCCESS = 0, 21020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_INVALID_RESOURCE = (-1), 21120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_INVALID_ARGS = (-2), 21220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NO_MEM = (-3), 21320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_DATAGRAM_FAILED = (-4), 21420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_MORE_DATA = (-5), 21520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NO_MORE_DATAGRAMS = (-6), 21620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NO_ACCESS = (-7), 21720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NO_HANDLE = (-8), 21820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_DUPLICATE_ENTRY = (-9), 21920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_DST_UNREACHABLE = (-10), 22020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_PAYLOAD_TOO_LARGE = (-11), 22120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_INVALID_PRIV = (-12), 22220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_GENERIC = (-13), 22320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_PAGE_ALREADY_SHARED = (-14), 22420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_CANNOT_SHARE_PAGE = (-15), 22520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_CANNOT_UNSHARE_PAGE = (-16), 22620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NO_PROCESS = (-17), 22720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NO_DATAGRAM = (-18), 22820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NO_RESOURCES = (-19), 22920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_UNAVAILABLE = (-20), 23020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NOT_FOUND = (-21), 23120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_ALREADY_EXISTS = (-22), 23220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_NOT_PAGE_ALIGNED = (-23), 23320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_INVALID_SIZE = (-24), 23420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_REGION_ALREADY_SHARED = (-25), 23520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_TIMEOUT = (-26), 23620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_DATAGRAM_INCOMPLETE = (-27), 23720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_INCORRECT_IRQL = (-28), 23820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_EVENT_UNKNOWN = (-29), 23920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_OBSOLETE = (-30), 24020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_QUEUEPAIR_MISMATCH = (-31), 24120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_QUEUEPAIR_NOTSET = (-32), 24220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_QUEUEPAIR_NOTOWNER = (-33), 24320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_QUEUEPAIR_NOTATTACHED = (-34), 24420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_QUEUEPAIR_NOSPACE = (-35), 24520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_QUEUEPAIR_NODATA = (-36), 24620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_BUSMEM_INVALIDATION = (-37), 24720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_MODULE_NOT_LOADED = (-38), 24820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_DEVICE_NOT_FOUND = (-39), 24920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_QUEUEPAIR_NOT_READY = (-40), 25020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_WOULD_BLOCK = (-41), 25120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 25220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* VMCI clients should return error code within this range */ 25320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_CLIENT_MIN = (-500), 25420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_ERROR_CLIENT_MAX = (-550), 25520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 25620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Internal error codes. */ 25720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_SHAREDMEM_ERROR_BAD_CONTEXT = (-1000), 25820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 25920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 26020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* VMCI reserved events. */ 26120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangenum { 26220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Only applicable to guest endpoints */ 26320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_CTX_ID_UPDATE = 0, 26420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 26520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Applicable to guest and host */ 26620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_CTX_REMOVED = 1, 26720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 26820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Only applicable to guest endpoints */ 26920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_QP_RESUMED = 2, 27020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 27120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Applicable to guest and host */ 27220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_QP_PEER_ATTACH = 3, 27320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 27420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Applicable to guest and host */ 27520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_QP_PEER_DETACH = 4, 27620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 27720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* 27820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Applicable to VMX and vmk. On vmk, 27920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * this event has the Context payload type. 28020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 28120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_MEM_ACCESS_ON = 5, 28220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 28320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* 28420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Applicable to VMX and vmk. Same as 28520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * above for the payload type. 28620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 28720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_MEM_ACCESS_OFF = 6, 28820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_EVENT_MAX = 7, 28920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 29020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 29120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 29220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Of the above events, a few are reserved for use in the VMX, and 29320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * other endpoints (guest and host kernel) should not use them. For 29420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * the rest of the events, we allow both host and guest endpoints to 29520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * subscribe to them, to maintain the same API for host and guest 29620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * endpoints. 29720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 29820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_EVENT_VALID_VMX(_event) ((_event) == VMCI_EVENT_MEM_ACCESS_ON || \ 29920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang (_event) == VMCI_EVENT_MEM_ACCESS_OFF) 30020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 30120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_EVENT_VALID(_event) ((_event) < VMCI_EVENT_MAX && \ 30220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang !VMCI_EVENT_VALID_VMX(_event)) 30320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 30420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Reserved guest datagram resource ids. */ 30520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_EVENT_HANDLER 0 30620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 30720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 30820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI coarse-grained privileges (per context or host 30920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * process/endpoint. An entity with the restricted flag is only 31020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * allowed to interact with the hypervisor and trusted entities. 31120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 31220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangenum { 31320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_NO_PRIVILEGE_FLAGS = 0, 31420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_PRIVILEGE_FLAG_RESTRICTED = 1, 31520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_PRIVILEGE_FLAG_TRUSTED = 2, 31620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_PRIVILEGE_ALL_FLAGS = (VMCI_PRIVILEGE_FLAG_RESTRICTED | 31720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_PRIVILEGE_FLAG_TRUSTED), 31820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS = VMCI_NO_PRIVILEGE_FLAGS, 31920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_LEAST_PRIVILEGE_FLAGS = VMCI_PRIVILEGE_FLAG_RESTRICTED, 32020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_MAX_PRIVILEGE_FLAGS = VMCI_PRIVILEGE_FLAG_TRUSTED, 32120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 32220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 32320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 0 through VMCI_RESERVED_RESOURCE_ID_MAX are reserved. */ 32420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_RESERVED_RESOURCE_ID_MAX 1023 32520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 32620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 32720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Driver version. 32820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 32920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Increment major version when you make an incompatible change. 33020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Compatibility goes both ways (old driver with new executable 33120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * as well as new driver with old executable). 33220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 33320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 33420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Never change VMCI_VERSION_SHIFT_WIDTH */ 33520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_SHIFT_WIDTH 16 33620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAKE_VERSION(_major, _minor) \ 33720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang ((_major) << VMCI_VERSION_SHIFT_WIDTH | (u16) (_minor)) 33820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 33920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_MAJOR(v) ((u32) (v) >> VMCI_VERSION_SHIFT_WIDTH) 34020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_MINOR(v) ((u16) (v)) 34120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 34220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 34320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_VERSION is always the current version. Subsequently listed 34420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * versions are ways of detecting previous versions of the connecting 34520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * application (i.e., VMX). 34620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 34720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_VERSION_NOVMVM: This version removed support for VM to VM 34820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * communication. 34920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 35020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_VERSION_NOTIFY: This version introduced doorbell notification 35120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * support. 35220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 35320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_VERSION_HOSTQP: This version introduced host end point support 35420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * for hosted products. 35520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 35620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_VERSION_PREHOSTQP: This is the version prior to the adoption of 35720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * support for host end-points. 35820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 35920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_VERSION_PREVERS2: This fictional version number is intended to 36020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * represent the version of a VMX which doesn't call into the driver 36120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * with ioctl VERSION2 and thus doesn't establish its version with the 36220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * driver. 36320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 36420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 36520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION VMCI_VERSION_NOVMVM 36620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_NOVMVM VMCI_MAKE_VERSION(11, 0) 36720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_NOTIFY VMCI_MAKE_VERSION(10, 0) 36820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_HOSTQP VMCI_MAKE_VERSION(9, 0) 36920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_PREHOSTQP VMCI_MAKE_VERSION(8, 0) 37020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_VERSION_PREVERS2 VMCI_MAKE_VERSION(1, 0) 37120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 37220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_SOCKETS_MAKE_VERSION(_p) \ 37320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang ((((_p)[0] & 0xFF) << 24) | (((_p)[1] & 0xFF) << 16) | ((_p)[2])) 37420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 37520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 37620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * The VMCI IOCTLs. We use identity code 7, as noted in ioctl-number.h, and 37720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * we start at sequence 9f. This gives us the same values that our shipping 37820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * products use, starting at 1951, provided we leave out the direction and 37920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * structure size. Note that VMMon occupies the block following us, starting 38020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * at 2001. 38120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 38220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_VERSION _IO(7, 0x9f) /* 1951 */ 38320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_INIT_CONTEXT _IO(7, 0xa0) 38420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_QUEUEPAIR_SETVA _IO(7, 0xa4) 38520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_NOTIFY_RESOURCE _IO(7, 0xa5) 38620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_NOTIFICATIONS_RECEIVE _IO(7, 0xa6) 38720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_VERSION2 _IO(7, 0xa7) 38820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_QUEUEPAIR_ALLOC _IO(7, 0xa8) 38920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE _IO(7, 0xa9) 39020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_QUEUEPAIR_DETACH _IO(7, 0xaa) 39120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_DATAGRAM_SEND _IO(7, 0xab) 39220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_DATAGRAM_RECEIVE _IO(7, 0xac) 39320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_CTX_ADD_NOTIFICATION _IO(7, 0xaf) 39420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_CTX_REMOVE_NOTIFICATION _IO(7, 0xb0) 39520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_CTX_GET_CPT_STATE _IO(7, 0xb1) 39620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_CTX_SET_CPT_STATE _IO(7, 0xb2) 39720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_GET_CONTEXT_ID _IO(7, 0xb3) 39820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_SOCKETS_VERSION _IO(7, 0xb4) 39920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_SOCKETS_GET_AF_VALUE _IO(7, 0xb8) 40020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) 40120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define IOCTL_VMCI_SET_NOTIFY _IO(7, 0xcb) /* 1995 */ 40220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/*IOCTL_VMMON_START _IO(7, 0xd1)*/ /* 2001 */ 40320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 40420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 40520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * struct vmci_queue_header - VMCI Queue Header information. 40620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 40720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * A Queue cannot stand by itself as designed. Each Queue's header 40820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * contains a pointer into itself (the producer_tail) and into its peer 40920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * (consumer_head). The reason for the separation is one of 41020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * accessibility: Each end-point can modify two things: where the next 41120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * location to enqueue is within its produce_q (producer_tail); and 41220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * where the next dequeue location is in its consume_q (consumer_head). 41320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 41420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * An end-point cannot modify the pointers of its peer (guest to 41520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * guest; NOTE that in the host both queue headers are mapped r/w). 41620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * But, each end-point needs read access to both Queue header 41720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * structures in order to determine how much space is used (or left) 41820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * in the Queue. This is because for an end-point to know how full 41920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * its produce_q is, it needs to use the consumer_head that points into 42020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * the produce_q but -that- consumer_head is in the Queue header for 42120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * that end-points consume_q. 42220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 42320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Thoroughly confused? Sorry. 42420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 42520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * producer_tail: the point to enqueue new entrants. When you approach 42620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * a line in a store, for example, you walk up to the tail. 42720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 42820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * consumer_head: the point in the queue from which the next element is 42920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * dequeued. In other words, who is next in line is he who is at the 43020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * head of the line. 43120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 43220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Also, producer_tail points to an empty byte in the Queue, whereas 43320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * consumer_head points to a valid byte of data (unless producer_tail == 43420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * consumer_head in which case consumer_head does not point to a valid 43520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * byte of data). 43620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 43720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * For a queue of buffer 'size' bytes, the tail and head pointers will be in 43820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * the range [0, size-1]. 43920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 44020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * If produce_q_header->producer_tail == consume_q_header->consumer_head 44120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * then the produce_q is empty. 44220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 44320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_queue_header { 44420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* All fields are 64bit and aligned. */ 44520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; /* Identifier. */ 44620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang atomic64_t producer_tail; /* Offset in this queue. */ 44720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang atomic64_t consumer_head; /* Offset in peer queue. */ 44820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 44920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 45020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 45120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * struct vmci_datagram - Base struct for vmci datagrams. 45220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * @dst: A vmci_handle that tracks the destination of the datagram. 45320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * @src: A vmci_handle that tracks the source of the datagram. 45420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * @payload_size: The size of the payload. 45520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 45620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * vmci_datagram structs are used when sending vmci datagrams. They include 45720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * the necessary source and destination information to properly route 45820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * the information along with the size of the package. 45920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 46020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_datagram { 46120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle dst; 46220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle src; 46320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 payload_size; 46420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 46520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 46620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 46720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Second flag is for creating a well-known handle instead of a per context 46820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * handle. Next flag is for deferring datagram delivery, so that the 46920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * datagram callback is invoked in a delayed context (not interrupt context). 47020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 47120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_FLAG_DG_NONE 0 47220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_FLAG_WELLKNOWN_DG_HND 0x1 47320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_FLAG_ANYCID_DG_HND 0x2 47420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_FLAG_DG_DELAYED_CB 0x4 47520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 47620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 47720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Maximum supported size of a VMCI datagram for routable datagrams. 47820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Datagrams going to the hypervisor are allowed to be larger. 47920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 48020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_DG_SIZE (17 * 4096) 48120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_DG_PAYLOAD_SIZE (VMCI_MAX_DG_SIZE - \ 48220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang sizeof(struct vmci_datagram)) 48320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_DG_PAYLOAD(_dg) (void *)((char *)(_dg) + \ 48420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang sizeof(struct vmci_datagram)) 48520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_DG_HEADERSIZE sizeof(struct vmci_datagram) 48620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_DG_SIZE(_dg) (VMCI_DG_HEADERSIZE + (size_t)(_dg)->payload_size) 48720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_DG_SIZE_ALIGNED(_dg) ((VMCI_DG_SIZE(_dg) + 7) & (~((size_t) 0x7))) 48820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_DATAGRAM_QUEUE_SIZE (VMCI_MAX_DG_SIZE * 2) 48920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 49020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_payload_qp { 49120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; /* queue_pair handle. */ 49220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 peer_id; /* Context id of attaching/detaching VM. */ 49320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 _pad; 49420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 49520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 49620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Flags for VMCI queue_pair API. */ 49720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangenum { 49820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Fail alloc if QP not created by peer. */ 49920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QPFLAG_ATTACH_ONLY = 1 << 0, 50020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 50120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Only allow attaches from local context. */ 50220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QPFLAG_LOCAL = 1 << 1, 50320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 50420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Host won't block when guest is quiesced. */ 50520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QPFLAG_NONBLOCK = 1 << 2, 50620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 50720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Pin data pages in ESX. Used with NONBLOCK */ 50820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QPFLAG_PINNED = 1 << 3, 50920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 51020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Update the following flag when adding new flags. */ 51120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QP_ALL_FLAGS = (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QPFLAG_LOCAL | 51220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED), 51320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 51420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Convenience flags */ 51520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QP_ASYMM = (VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED), 51620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang VMCI_QP_ASYMM_PEER = (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QP_ASYMM), 51720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 51820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 51920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 52020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * We allow at least 1024 more event datagrams from the hypervisor past the 52120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * normally allowed datagrams pending for a given context. We define this 52220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * limit on event datagrams from the hypervisor to guard against DoS attack 52320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * from a malicious VM which could repeatedly attach to and detach from a queue 52420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * pair, causing events to be queued at the destination VM. However, the rate 52520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * at which such events can be generated is small since it requires a VM exit 52620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * and handling of queue pair attach/detach call at the hypervisor. Event 52720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * datagrams may be queued up at the destination VM if it has interrupts 52820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * disabled or if it is not draining events for some other reason. 1024 52920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * datagrams is a grossly conservative estimate of the time for which 53020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * interrupts may be disabled in the destination VM, but at the same time does 53120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * not exacerbate the memory pressure problem on the host by much (size of each 53220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * event datagram is small). 53320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 53420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE \ 53520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang (VMCI_MAX_DATAGRAM_QUEUE_SIZE + \ 53620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 1024 * (sizeof(struct vmci_datagram) + \ 53720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang sizeof(struct vmci_event_data_max))) 53820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 53920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 54020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Struct used for querying, via VMCI_RESOURCES_QUERY, the availability of 54120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * hypervisor resources. Struct size is 16 bytes. All fields in struct are 54220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * aligned to their natural alignment. 54320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 54420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_resource_query_hdr { 54520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 54620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 num_resources; 54720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 _padding; 54820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 54920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 55020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 55120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Convenience struct for negotiating vectors. Must match layout of 55220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCIResourceQueryHdr minus the struct vmci_datagram header. 55320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 55420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_resource_query_msg { 55520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 num_resources; 55620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 _padding; 55720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 resources[1]; 55820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 55920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 56020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 56120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * The maximum number of resources that can be queried using 56220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_RESOURCE_QUERY is 31, as the result is encoded in the lower 31 56320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * bits of a positive return value. Negative values are reserved for 56420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * errors. 56520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 56620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_RESOURCE_QUERY_MAX_NUM 31 56720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 56820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Maximum size for the VMCI_RESOURCE_QUERY request. */ 56920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_RESOURCE_QUERY_MAX_SIZE \ 57020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang (sizeof(struct vmci_resource_query_hdr) + \ 57120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang sizeof(u32) * VMCI_RESOURCE_QUERY_MAX_NUM) 57220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 57320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 57420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Struct used for setting the notification bitmap. All fields in 57520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * struct are aligned to their natural alignment. 57620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 57720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_notify_bm_set_msg { 57820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 57920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 bitmap_ppn; 58020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 _pad; 58120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 58220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 58320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 58420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Struct used for linking a doorbell handle with an index in the 58520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * notify bitmap. All fields in struct are aligned to their natural 58620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * alignment. 58720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 58820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_doorbell_link_msg { 58920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 59020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; 59120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 notify_idx; 59220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 59320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 59420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 59520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Struct used for unlinking a doorbell handle from an index in the 59620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * notify bitmap. All fields in struct are aligned to their natural 59720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * alignment. 59820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 59920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_doorbell_unlink_msg { 60020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 60120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; 60220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 60320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 60420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 60520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Struct used for generating a notification on a doorbell handle. All 60620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * fields in struct are aligned to their natural alignment. 60720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 60820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_doorbell_notify_msg { 60920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 61020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; 61120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 61220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 61320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 61420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * This struct is used to contain data for events. Size of this struct is a 61520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * multiple of 8 bytes, and all fields are aligned to their natural alignment. 61620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 61720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_data { 61820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 event; /* 4 bytes. */ 61920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 _pad; 62020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Event payload is put here. */ 62120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 62220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 62320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 62420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Define the different VMCI_EVENT payload data types here. All structs must 62520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * be a multiple of 8 bytes, and fields must be aligned to their natural 62620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * alignment. 62720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 62820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_payld_ctx { 62920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 context_id; /* 4 bytes. */ 63020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 _pad; 63120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 63220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 63320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_payld_qp { 63420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; /* queue_pair handle. */ 63520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 peer_id; /* Context id of attaching/detaching VM. */ 63620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 _pad; 63720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 63820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 63920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 64020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * We define the following struct to get the size of the maximum event 64120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * data the hypervisor may send to the guest. If adding a new event 64220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * payload type above, add it to the following struct too (inside the 64320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * union). 64420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 64520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_data_max { 64620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_data event_data; 64720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang union { 64820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_payld_ctx context_payload; 64920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_payld_qp qp_payload; 65020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang } ev_data_payload; 65120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 65220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 65320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 65420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Struct used for VMCI_EVENT_SUBSCRIBE/UNSUBSCRIBE and 65520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI_EVENT_HANDLER messages. Struct size is 32 bytes. All fields 65620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * in struct are aligned to their natural alignment. 65720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 65820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_msg { 65920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 66020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 66120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Has event type and payload. */ 66220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_data event_data; 66320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 66420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* Payload gets put here. */ 66520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 66620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 66720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Event with context payload. */ 66820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_ctx { 66920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_msg msg; 67020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_payld_ctx payload; 67120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 67220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 67320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Event with QP payload. */ 67420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_event_qp { 67520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_msg msg; 67620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_event_payld_qp payload; 67720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 67820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 67920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 68020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Structs used for queue_pair alloc and detach messages. We align fields of 68120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * these structs to 64bit boundaries. 68220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 68320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_qp_alloc_msg { 68420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 68520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; 68620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 peer; 68720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u32 flags; 68820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 produce_size; 68920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 consume_size; 69020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 num_ppns; 69120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 69220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* List of PPNs placed here. */ 69320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 69420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 69520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_qp_detach_msg { 69620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram hdr; 69720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_handle handle; 69820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang}; 69920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 70020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* VMCI Doorbell API. */ 70120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#define VMCI_FLAG_DELAYED_CB 0x01 70220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 70320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangtypedef void (*vmci_callback) (void *client_data); 70420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 70520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 70620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * struct vmci_qp - A vmw_vmci queue pair handle. 70720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * 70820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * This structure is used as a handle to a queue pair created by 70920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * VMCI. It is intentionally left opaque to clients. 71020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 71120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstruct vmci_qp; 71220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 71320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* Callback needed for correctly waiting on events. */ 71420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangtypedef int (*vmci_datagram_recv_cb) (void *client_data, 71520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_datagram *msg); 71620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 71720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* VMCI Event API. */ 71820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangtypedef void (*vmci_event_cb) (u32 sub_id, const struct vmci_event_data *ed, 71920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang void *client_data); 72020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 72120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 72220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * We use the following inline function to access the payload data 72320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * associated with an event data. 72420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 72520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline const void * 72620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_event_data_const_payload(const struct vmci_event_data *ev_data) 72720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 72820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return (const char *)ev_data + sizeof(*ev_data); 72920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 73020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 73120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline void *vmci_event_data_payload(struct vmci_event_data *ev_data) 73220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 73320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return (void *)vmci_event_data_const_payload(ev_data); 73420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 73520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 73620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 73720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Helper to add a given offset to a head or tail pointer. Wraps the 73820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * value of the pointer around the max size of the queue. 73920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 74020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline void vmci_qp_add_pointer(atomic64_t *var, 74120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang size_t add, 74220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 size) 74320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 74420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 new_val = atomic64_read(var); 74520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 74620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang if (new_val >= size - add) 74720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang new_val -= size; 74820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 74920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang new_val += add; 75020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 75120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang atomic64_set(var, new_val); 75220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 75320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 75420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 75520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Helper routine to get the Producer Tail from the supplied queue. 75620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 75720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline u64 75820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_q_header_producer_tail(const struct vmci_queue_header *q_header) 75920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 76020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_queue_header *qh = (struct vmci_queue_header *)q_header; 76120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return atomic64_read(&qh->producer_tail); 76220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 76320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 76420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 76520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Helper routine to get the Consumer Head from the supplied queue. 76620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 76720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline u64 76820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_q_header_consumer_head(const struct vmci_queue_header *q_header) 76920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 77020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang struct vmci_queue_header *qh = (struct vmci_queue_header *)q_header; 77120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return atomic64_read(&qh->consumer_head); 77220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 77320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 77420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 77520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Helper routine to increment the Producer Tail. Fundamentally, 77620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * vmci_qp_add_pointer() is used to manipulate the tail itself. 77720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 77820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline void 77920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_q_header_add_producer_tail(struct vmci_queue_header *q_header, 78020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang size_t add, 78120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 queue_size) 78220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 78320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang vmci_qp_add_pointer(&q_header->producer_tail, add, queue_size); 78420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 78520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 78620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 78720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Helper routine to increment the Consumer Head. Fundamentally, 78820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * vmci_qp_add_pointer() is used to manipulate the head itself. 78920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 79020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline void 79120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_q_header_add_consumer_head(struct vmci_queue_header *q_header, 79220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang size_t add, 79320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 queue_size) 79420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 79520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang vmci_qp_add_pointer(&q_header->consumer_head, add, queue_size); 79620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 79720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 79820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 79920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Helper routine for getting the head and the tail pointer for a queue. 80020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Both the VMCIQueues are needed to get both the pointers for one queue. 80120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 80220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline void 80320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_q_header_get_pointers(const struct vmci_queue_header *produce_q_header, 80420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang const struct vmci_queue_header *consume_q_header, 80520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 *producer_tail, 80620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 *consumer_head) 80720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 80820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang if (producer_tail) 80920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang *producer_tail = vmci_q_header_producer_tail(produce_q_header); 81020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 81120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang if (consumer_head) 81220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang *consumer_head = vmci_q_header_consumer_head(consume_q_header); 81320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 81420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 81520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline void vmci_q_header_init(struct vmci_queue_header *q_header, 81620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang const struct vmci_handle handle) 81720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 81820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang q_header->handle = handle; 81920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang atomic64_set(&q_header->producer_tail, 0); 82020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang atomic64_set(&q_header->consumer_head, 0); 82120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 82220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 82320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 82420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Finds available free space in a produce queue to enqueue more 82520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * data or reports an error if queue pair corruption is detected. 82620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 82720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic s64 82820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_q_header_free_space(const struct vmci_queue_header *produce_q_header, 82920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang const struct vmci_queue_header *consume_q_header, 83020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang const u64 produce_q_size) 83120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 83220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 tail; 83320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 head; 83420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang u64 free_space; 83520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 83620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang tail = vmci_q_header_producer_tail(produce_q_header); 83720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang head = vmci_q_header_consumer_head(consume_q_header); 83820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 83920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang if (tail >= produce_q_size || head >= produce_q_size) 84020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return VMCI_ERROR_INVALID_SIZE; 84120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 84220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang /* 84320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Deduct 1 to avoid tail becoming equal to head which causes 84420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * ambiguity. If head and tail are equal it means that the 84520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * queue is empty. 84620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 84720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang if (tail >= head) 84820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang free_space = produce_q_size - (tail - head) - 1; 84920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang else 85020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang free_space = head - tail - 1; 85120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 85220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return free_space; 85320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 85420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 85520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang/* 85620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * vmci_q_header_free_space() does all the heavy lifting of 85720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * determing the number of free bytes in a Queue. This routine, 85820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * then subtracts that size from the full size of the Queue so 85920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * the caller knows how many bytes are ready to be dequeued. 86020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * Results: 86120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * On success, available data size in bytes (up to MAX_INT64). 86220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang * On failure, appropriate error code. 86320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang */ 86420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangstatic inline s64 86520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhangvmci_q_header_buf_ready(const struct vmci_queue_header *consume_q_header, 86620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang const struct vmci_queue_header *produce_q_header, 86720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang const u64 consume_q_size) 86820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang{ 86920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang s64 free_space; 87020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 87120259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang free_space = vmci_q_header_free_space(consume_q_header, 87220259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang produce_q_header, consume_q_size); 87320259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang if (free_space < VMCI_SUCCESS) 87420259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return free_space; 87520259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 87620259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang return consume_q_size - free_space - 1; 87720259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang} 87820259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 87920259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang 88020259849bb1ac1ffb0156eb359810e8b99cb644dGeorge Zhang#endif /* _VMW_VMCI_DEF_H_ */ 881