summaryrefslogtreecommitdiff
path: root/include/linux/vmw_vmci_defs.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/vmw_vmci_defs.h')
-rw-r--r--include/linux/vmw_vmci_defs.h195
1 files changed, 125 insertions, 70 deletions
diff --git a/include/linux/vmw_vmci_defs.h b/include/linux/vmw_vmci_defs.h
index b724ef7005de..60c9eacd2cf3 100644
--- a/include/linux/vmw_vmci_defs.h
+++ b/include/linux/vmw_vmci_defs.h
@@ -1,61 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* VMware VMCI Driver
*
* Copyright (C) 2012 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
*/
#ifndef _VMW_VMCI_DEF_H_
#define _VMW_VMCI_DEF_H_
#include <linux/atomic.h>
+#include <linux/bits.h>
/* Register offsets. */
-#define VMCI_STATUS_ADDR 0x00
-#define VMCI_CONTROL_ADDR 0x04
-#define VMCI_ICR_ADDR 0x08
-#define VMCI_IMR_ADDR 0x0c
-#define VMCI_DATA_OUT_ADDR 0x10
-#define VMCI_DATA_IN_ADDR 0x14
-#define VMCI_CAPS_ADDR 0x18
-#define VMCI_RESULT_LOW_ADDR 0x1c
-#define VMCI_RESULT_HIGH_ADDR 0x20
+#define VMCI_STATUS_ADDR 0x00
+#define VMCI_CONTROL_ADDR 0x04
+#define VMCI_ICR_ADDR 0x08
+#define VMCI_IMR_ADDR 0x0c
+#define VMCI_DATA_OUT_ADDR 0x10
+#define VMCI_DATA_IN_ADDR 0x14
+#define VMCI_CAPS_ADDR 0x18
+#define VMCI_RESULT_LOW_ADDR 0x1c
+#define VMCI_RESULT_HIGH_ADDR 0x20
+#define VMCI_DATA_OUT_LOW_ADDR 0x24
+#define VMCI_DATA_OUT_HIGH_ADDR 0x28
+#define VMCI_DATA_IN_LOW_ADDR 0x2c
+#define VMCI_DATA_IN_HIGH_ADDR 0x30
+#define VMCI_GUEST_PAGE_SHIFT 0x34
/* Max number of devices. */
#define VMCI_MAX_DEVICES 1
/* Status register bits. */
-#define VMCI_STATUS_INT_ON 0x1
+#define VMCI_STATUS_INT_ON BIT(0)
/* Control register bits. */
-#define VMCI_CONTROL_RESET 0x1
-#define VMCI_CONTROL_INT_ENABLE 0x2
-#define VMCI_CONTROL_INT_DISABLE 0x4
+#define VMCI_CONTROL_RESET BIT(0)
+#define VMCI_CONTROL_INT_ENABLE BIT(1)
+#define VMCI_CONTROL_INT_DISABLE BIT(2)
/* Capabilities register bits. */
-#define VMCI_CAPS_HYPERCALL 0x1
-#define VMCI_CAPS_GUESTCALL 0x2
-#define VMCI_CAPS_DATAGRAM 0x4
-#define VMCI_CAPS_NOTIFICATIONS 0x8
+#define VMCI_CAPS_HYPERCALL BIT(0)
+#define VMCI_CAPS_GUESTCALL BIT(1)
+#define VMCI_CAPS_DATAGRAM BIT(2)
+#define VMCI_CAPS_NOTIFICATIONS BIT(3)
+#define VMCI_CAPS_PPN64 BIT(4)
+#define VMCI_CAPS_DMA_DATAGRAM BIT(5)
/* Interrupt Cause register bits. */
-#define VMCI_ICR_DATAGRAM 0x1
-#define VMCI_ICR_NOTIFICATION 0x2
+#define VMCI_ICR_DATAGRAM BIT(0)
+#define VMCI_ICR_NOTIFICATION BIT(1)
+#define VMCI_ICR_DMA_DATAGRAM BIT(2)
/* Interrupt Mask register bits. */
-#define VMCI_IMR_DATAGRAM 0x1
-#define VMCI_IMR_NOTIFICATION 0x2
+#define VMCI_IMR_DATAGRAM BIT(0)
+#define VMCI_IMR_NOTIFICATION BIT(1)
+#define VMCI_IMR_DMA_DATAGRAM BIT(2)
-/* Maximum MSI/MSI-X interrupt vectors in the device. */
-#define VMCI_MAX_INTRS 2
+/*
+ * Maximum MSI/MSI-X interrupt vectors in the device.
+ * If VMCI_CAPS_DMA_DATAGRAM is supported by the device,
+ * VMCI_MAX_INTRS_DMA_DATAGRAM vectors are available,
+ * otherwise only VMCI_MAX_INTRS_NOTIFICATION.
+ */
+#define VMCI_MAX_INTRS_NOTIFICATION 2
+#define VMCI_MAX_INTRS_DMA_DATAGRAM 3
+#define VMCI_MAX_INTRS VMCI_MAX_INTRS_DMA_DATAGRAM
/*
* Supported interrupt vectors. There is one for each ICR value above,
@@ -64,20 +73,76 @@
enum {
VMCI_INTR_DATAGRAM = 0,
VMCI_INTR_NOTIFICATION = 1,
+ VMCI_INTR_DMA_DATAGRAM = 2,
};
/*
* A single VMCI device has an upper limit of 128MB on the amount of
- * memory that can be used for queue pairs.
+ * memory that can be used for queue pairs. Since each queue pair
+ * consists of at least two pages, the memory limit also dictates the
+ * number of queue pairs a guest can create.
+ */
+#define VMCI_MAX_GUEST_QP_MEMORY ((size_t)(128 * 1024 * 1024))
+#define VMCI_MAX_GUEST_QP_COUNT (VMCI_MAX_GUEST_QP_MEMORY / PAGE_SIZE / 2)
+
+/*
+ * There can be at most PAGE_SIZE doorbells since there is one doorbell
+ * per byte in the doorbell bitmap page.
*/
-#define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024)
+#define VMCI_MAX_GUEST_DOORBELL_COUNT PAGE_SIZE
/*
* Queues with pre-mapped data pages must be small, so that we don't pin
* too much kernel memory (especially on vmkernel). We limit a queuepair to
* 32 KB, or 16 KB per queue for symmetrical pairs.
*/
-#define VMCI_MAX_PINNED_QP_MEMORY (32 * 1024)
+#define VMCI_MAX_PINNED_QP_MEMORY ((size_t)(32 * 1024))
+
+/*
+ * The version of the VMCI device that supports MMIO access to registers
+ * requests 256KB for BAR1 whereas the version of VMCI that supports
+ * MSI/MSI-X only requests 8KB. The layout of the larger 256KB region is:
+ * - the first 128KB are used for MSI/MSI-X.
+ * - the following 64KB are used for MMIO register access.
+ * - the remaining 64KB are unused.
+ */
+#define VMCI_WITH_MMIO_ACCESS_BAR_SIZE ((size_t)(256 * 1024))
+#define VMCI_MMIO_ACCESS_OFFSET ((size_t)(128 * 1024))
+#define VMCI_MMIO_ACCESS_SIZE ((size_t)(64 * 1024))
+
+/*
+ * For VMCI devices supporting the VMCI_CAPS_DMA_DATAGRAM capability, the
+ * sending and receiving of datagrams can be performed using DMA to/from
+ * a driver allocated buffer.
+ * Sending and receiving will be handled as follows:
+ * - when sending datagrams, the driver initializes the buffer where the
+ * data part will refer to the outgoing VMCI datagram, sets the busy flag
+ * to 1 and writes the address of the buffer to VMCI_DATA_OUT_HIGH_ADDR
+ * and VMCI_DATA_OUT_LOW_ADDR. Writing to VMCI_DATA_OUT_LOW_ADDR triggers
+ * the device processing of the buffer. When the device has processed the
+ * buffer, it will write the result value to the buffer and then clear the
+ * busy flag.
+ * - when receiving datagrams, the driver initializes the buffer where the
+ * data part will describe the receive buffer, clears the busy flag and
+ * writes the address of the buffer to VMCI_DATA_IN_HIGH_ADDR and
+ * VMCI_DATA_IN_LOW_ADDR. Writing to VMCI_DATA_IN_LOW_ADDR triggers the
+ * device processing of the buffer. The device will copy as many available
+ * datagrams into the buffer as possible, and then sets the busy flag.
+ * When the busy flag is set, the driver will process the datagrams in the
+ * buffer.
+ */
+struct vmci_data_in_out_header {
+ uint32_t busy;
+ uint32_t opcode;
+ uint32_t size;
+ uint32_t rsvd;
+ uint64_t result;
+};
+
+struct vmci_sg_elem {
+ uint64_t addr;
+ uint64_t size;
+};
/*
* We have a fixed set of resource IDs available in the VMX.
@@ -156,7 +221,7 @@ static inline bool vmci_handle_is_invalid(struct vmci_handle h)
*/
#define VMCI_ANON_SRC_CONTEXT_ID VMCI_INVALID_ID
#define VMCI_ANON_SRC_RESOURCE_ID VMCI_INVALID_ID
-static const struct vmci_handle VMCI_ANON_SRC_HANDLE = {
+static const struct vmci_handle __maybe_unused VMCI_ANON_SRC_HANDLE = {
.context = VMCI_ANON_SRC_CONTEXT_ID,
.resource = VMCI_ANON_SRC_RESOURCE_ID
};
@@ -366,11 +431,11 @@ enum {
((((_p)[0] & 0xFF) << 24) | (((_p)[1] & 0xFF) << 16) | ((_p)[2]))
/*
- * The VMCI IOCTLs. We use identity code 7, as noted in ioctl-number.h, and
- * we start at sequence 9f. This gives us the same values that our shipping
- * products use, starting at 1951, provided we leave out the direction and
- * structure size. Note that VMMon occupies the block following us, starting
- * at 2001.
+ * The VMCI IOCTLs. We use identity code 7, as noted in ioctl-number.rst,
+ * and we start at sequence 9f. This gives us the same values that our
+ * shipping products use, starting at 1951, provided we leave out the
+ * direction and structure size. Note that VMMon occupies the block
+ * following us, starting at 2001.
*/
#define IOCTL_VMCI_VERSION _IO(7, 0x9f) /* 1951 */
#define IOCTL_VMCI_INIT_CONTEXT _IO(7, 0xa0)
@@ -388,9 +453,7 @@ enum {
#define IOCTL_VMCI_CTX_GET_CPT_STATE _IO(7, 0xb1)
#define IOCTL_VMCI_CTX_SET_CPT_STATE _IO(7, 0xb2)
#define IOCTL_VMCI_GET_CONTEXT_ID _IO(7, 0xb3)
-#define IOCTL_VMCI_SOCKETS_VERSION _IO(7, 0xb4)
-#define IOCTL_VMCI_SOCKETS_GET_AF_VALUE _IO(7, 0xb8)
-#define IOCTL_VMCI_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9)
+/*IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9)*/
#define IOCTL_VMCI_SET_NOTIFY _IO(7, 0xcb) /* 1995 */
/*IOCTL_VMMON_START _IO(7, 0xd1)*/ /* 2001 */
@@ -436,8 +499,8 @@ enum {
struct vmci_queue_header {
/* All fields are 64bit and aligned. */
struct vmci_handle handle; /* Identifier. */
- atomic64_t producer_tail; /* Offset in this queue. */
- atomic64_t consumer_head; /* Offset in peer queue. */
+ u64 producer_tail; /* Offset in this queue. */
+ u64 consumer_head; /* Offset in peer queue. */
};
/*
@@ -462,9 +525,9 @@ struct vmci_datagram {
* datagram callback is invoked in a delayed context (not interrupt context).
*/
#define VMCI_FLAG_DG_NONE 0
-#define VMCI_FLAG_WELLKNOWN_DG_HND 0x1
-#define VMCI_FLAG_ANYCID_DG_HND 0x2
-#define VMCI_FLAG_DG_DELAYED_CB 0x4
+#define VMCI_FLAG_WELLKNOWN_DG_HND BIT(0)
+#define VMCI_FLAG_ANYCID_DG_HND BIT(1)
+#define VMCI_FLAG_DG_DELAYED_CB BIT(2)
/*
* Maximum supported size of a VMCI datagram for routable datagrams.
@@ -569,8 +632,10 @@ struct vmci_resource_query_msg {
*/
struct vmci_notify_bm_set_msg {
struct vmci_datagram hdr;
- u32 bitmap_ppn;
- u32 _pad;
+ union {
+ u32 bitmap_ppn32;
+ u64 bitmap_ppn64;
+ };
};
/*
@@ -691,7 +756,7 @@ struct vmci_qp_detach_msg {
};
/* VMCI Doorbell API. */
-#define VMCI_FLAG_DELAYED_CB 0x01
+#define VMCI_FLAG_DELAYED_CB BIT(0)
typedef void (*vmci_callback) (void *client_data);
@@ -736,13 +801,9 @@ static inline void *vmci_event_data_payload(struct vmci_event_data *ev_data)
* prefix will be used, so correctness isn't an issue, but using a
* 64bit operation still adds unnecessary overhead.
*/
-static inline u64 vmci_q_read_pointer(atomic64_t *var)
+static inline u64 vmci_q_read_pointer(u64 *var)
{
-#if defined(CONFIG_X86_32)
- return atomic_read((atomic_t *)var);
-#else
- return atomic64_read(var);
-#endif
+ return READ_ONCE(*(unsigned long *)var);
}
/*
@@ -751,23 +812,17 @@ static inline u64 vmci_q_read_pointer(atomic64_t *var)
* never exceeds a 32bit value in this case. On 32bit SMP, using a
* locked cmpxchg8b adds unnecessary overhead.
*/
-static inline void vmci_q_set_pointer(atomic64_t *var,
- u64 new_val)
+static inline void vmci_q_set_pointer(u64 *var, u64 new_val)
{
-#if defined(CONFIG_X86_32)
- return atomic_set((atomic_t *)var, (u32)new_val);
-#else
- return atomic64_set(var, new_val);
-#endif
+ /* XXX buggered on big-endian */
+ WRITE_ONCE(*(unsigned long *)var, (unsigned long)new_val);
}
/*
* Helper to add a given offset to a head or tail pointer. Wraps the
* value of the pointer around the max size of the queue.
*/
-static inline void vmci_qp_add_pointer(atomic64_t *var,
- size_t add,
- u64 size)
+static inline void vmci_qp_add_pointer(u64 *var, size_t add, u64 size)
{
u64 new_val = vmci_q_read_pointer(var);
@@ -844,8 +899,8 @@ static inline void vmci_q_header_init(struct vmci_queue_header *q_header,
const struct vmci_handle handle)
{
q_header->handle = handle;
- atomic64_set(&q_header->producer_tail, 0);
- atomic64_set(&q_header->consumer_head, 0);
+ q_header->producer_tail = 0;
+ q_header->consumer_head = 0;
}
/*