File Index
Files and directories
Sign in
FILE

ne_pci_dev.h

File preview with syntax highlighting.

linux-6.19.14/drivers/virt/nitro_enclaves/ne_pci_dev.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4 */
  5
  6#ifndef _NE_PCI_DEV_H_
  7#define _NE_PCI_DEV_H_
  8
  9#include <linux/atomic.h>
 10#include <linux/list.h>
 11#include <linux/mutex.h>
 12#include <linux/pci.h>
 13#include <linux/pci_ids.h>
 14#include <linux/wait.h>
 15
 16/**
 17 * DOC: Nitro Enclaves (NE) PCI device
 18 */
 19
 20/**
 21 * PCI_DEVICE_ID_NE - Nitro Enclaves PCI device id.
 22 */
 23#define PCI_DEVICE_ID_NE	(0xe4c1)
 24/**
 25 * PCI_BAR_NE - Nitro Enclaves PCI device MMIO BAR.
 26 */
 27#define PCI_BAR_NE		(0x03)
 28
 29/**
 30 * DOC: Device registers in the NE PCI device MMIO BAR
 31 */
 32
 33/**
 34 * NE_ENABLE - (1 byte) Register to notify the device that the driver is using
 35 *	       it (Read/Write).
 36 */
 37#define NE_ENABLE		(0x0000)
 38#define NE_ENABLE_OFF		(0x00)
 39#define NE_ENABLE_ON		(0x01)
 40
 41/**
 42 * NE_VERSION - (2 bytes) Register to select the device run-time version
 43 *		(Read/Write).
 44 */
 45#define NE_VERSION		(0x0002)
 46#define NE_VERSION_MAX		(0x0001)
 47
 48/**
 49 * NE_COMMAND - (4 bytes) Register to notify the device what command was
 50 *		requested (Write-Only).
 51 */
 52#define NE_COMMAND		(0x0004)
 53
 54/**
 55 * NE_EVTCNT - (4 bytes) Register to notify the driver that a reply or a device
 56 *	       event is available (Read-Only):
 57 *	       - Lower half  - command reply counter
 58 *	       - Higher half - out-of-band device event counter
 59 */
 60#define NE_EVTCNT		(0x000c)
 61#define NE_EVTCNT_REPLY_SHIFT	(0)
 62#define NE_EVTCNT_REPLY_MASK	(0x0000ffff)
 63#define NE_EVTCNT_REPLY(cnt)	(((cnt) & NE_EVTCNT_REPLY_MASK) >> \
 64				NE_EVTCNT_REPLY_SHIFT)
 65#define NE_EVTCNT_EVENT_SHIFT	(16)
 66#define NE_EVTCNT_EVENT_MASK	(0xffff0000)
 67#define NE_EVTCNT_EVENT(cnt)	(((cnt) & NE_EVTCNT_EVENT_MASK) >> \
 68				NE_EVTCNT_EVENT_SHIFT)
 69
 70/**
 71 * NE_SEND_DATA - (240 bytes) Buffer for sending the command request payload
 72 *		  (Read/Write).
 73 */
 74#define NE_SEND_DATA		(0x0010)
 75
 76/**
 77 * NE_RECV_DATA - (240 bytes) Buffer for receiving the command reply payload
 78 *		  (Read-Only).
 79 */
 80#define NE_RECV_DATA		(0x0100)
 81
 82/**
 83 * DOC: Device MMIO buffer sizes
 84 */
 85
 86/**
 87 * NE_SEND_DATA_SIZE - Size of the send buffer, in bytes.
 88 */
 89#define NE_SEND_DATA_SIZE	(240)
 90
 91/**
 92 * NE_RECV_DATA_SIZE - Size of the receive buffer, in bytes.
 93 */
 94#define NE_RECV_DATA_SIZE	(240)
 95
 96/**
 97 * DOC: MSI-X interrupt vectors
 98 */
 99
100/**
101 * NE_VEC_REPLY - MSI-X vector used for command reply notification.
102 */
103#define NE_VEC_REPLY		(0)
104
105/**
106 * NE_VEC_EVENT - MSI-X vector used for out-of-band events e.g. enclave crash.
107 */
108#define NE_VEC_EVENT		(1)
109
110/**
111 * enum ne_pci_dev_cmd_type - Device command types.
112 * @INVALID_CMD:		Invalid command.
113 * @ENCLAVE_START:		Start an enclave, after setting its resources.
114 * @ENCLAVE_GET_SLOT:		Get the slot uid of an enclave.
115 * @ENCLAVE_STOP:		Terminate an enclave.
116 * @SLOT_ALLOC :		Allocate a slot for an enclave.
117 * @SLOT_FREE:			Free the slot allocated for an enclave
118 * @SLOT_ADD_MEM:		Add a memory region to an enclave slot.
119 * @SLOT_ADD_VCPU:		Add a vCPU to an enclave slot.
120 * @SLOT_COUNT :		Get the number of allocated slots.
121 * @NEXT_SLOT:			Get the next slot in the list of allocated slots.
122 * @SLOT_INFO:			Get the info for a slot e.g. slot uid, vCPUs count.
123 * @SLOT_ADD_BULK_VCPUS:	Add a number of vCPUs, not providing CPU ids.
124 * @MAX_CMD:			A gatekeeper for max possible command type.
125 */
126enum ne_pci_dev_cmd_type {
127	INVALID_CMD		= 0,
128	ENCLAVE_START		= 1,
129	ENCLAVE_GET_SLOT	= 2,
130	ENCLAVE_STOP		= 3,
131	SLOT_ALLOC		= 4,
132	SLOT_FREE		= 5,
133	SLOT_ADD_MEM		= 6,
134	SLOT_ADD_VCPU		= 7,
135	SLOT_COUNT		= 8,
136	NEXT_SLOT		= 9,
137	SLOT_INFO		= 10,
138	SLOT_ADD_BULK_VCPUS	= 11,
139	MAX_CMD,
140};
141
142/**
143 * DOC: Device commands - payload structure for requests and replies.
144 */
145
146/**
147 * struct enclave_start_req - ENCLAVE_START request.
148 * @slot_uid:		Slot unique id mapped to the enclave to start.
149 * @enclave_cid:	Context ID (CID) for the enclave vsock device.
150 *			If 0, CID is autogenerated.
151 * @flags:		Flags for the enclave to start with (e.g. debug mode).
152 */
153struct enclave_start_req {
154	u64	slot_uid;
155	u64	enclave_cid;
156	u64	flags;
157};
158
159/**
160 * struct enclave_get_slot_req - ENCLAVE_GET_SLOT request.
161 * @enclave_cid:	Context ID (CID) for the enclave vsock device.
162 */
163struct enclave_get_slot_req {
164	u64	enclave_cid;
165};
166
167/**
168 * struct enclave_stop_req - ENCLAVE_STOP request.
169 * @slot_uid:	Slot unique id mapped to the enclave to stop.
170 */
171struct enclave_stop_req {
172	u64	slot_uid;
173};
174
175/**
176 * struct slot_alloc_req - SLOT_ALLOC request.
177 * @unused:	In order to avoid weird sizeof edge cases.
178 */
179struct slot_alloc_req {
180	u8	unused;
181};
182
183/**
184 * struct slot_free_req - SLOT_FREE request.
185 * @slot_uid:	Slot unique id mapped to the slot to free.
186 */
187struct slot_free_req {
188	u64	slot_uid;
189};
190
191/* TODO: Add flags field to the request to add memory region. */
192/**
193 * struct slot_add_mem_req - SLOT_ADD_MEM request.
194 * @slot_uid:	Slot unique id mapped to the slot to add the memory region to.
195 * @paddr:	Physical address of the memory region to add to the slot.
196 * @size:	Memory size, in bytes, of the memory region to add to the slot.
197 */
198struct slot_add_mem_req {
199	u64	slot_uid;
200	u64	paddr;
201	u64	size;
202};
203
204/**
205 * struct slot_add_vcpu_req - SLOT_ADD_VCPU request.
206 * @slot_uid:	Slot unique id mapped to the slot to add the vCPU to.
207 * @vcpu_id:	vCPU ID of the CPU to add to the enclave.
208 * @padding:	Padding for the overall data structure.
209 */
210struct slot_add_vcpu_req {
211	u64	slot_uid;
212	u32	vcpu_id;
213	u8	padding[4];
214};
215
216/**
217 * struct slot_count_req - SLOT_COUNT request.
218 * @unused:	In order to avoid weird sizeof edge cases.
219 */
220struct slot_count_req {
221	u8	unused;
222};
223
224/**
225 * struct next_slot_req - NEXT_SLOT request.
226 * @slot_uid:	Slot unique id of the next slot in the iteration.
227 */
228struct next_slot_req {
229	u64	slot_uid;
230};
231
232/**
233 * struct slot_info_req - SLOT_INFO request.
234 * @slot_uid:	Slot unique id mapped to the slot to get information about.
235 */
236struct slot_info_req {
237	u64	slot_uid;
238};
239
240/**
241 * struct slot_add_bulk_vcpus_req - SLOT_ADD_BULK_VCPUS request.
242 * @slot_uid:	Slot unique id mapped to the slot to add vCPUs to.
243 * @nr_vcpus:	Number of vCPUs to add to the slot.
244 */
245struct slot_add_bulk_vcpus_req {
246	u64	slot_uid;
247	u64	nr_vcpus;
248};
249
250/**
251 * struct ne_pci_dev_cmd_reply - NE PCI device command reply.
252 * @rc :		Return code of the logic that processed the request.
253 * @padding0:		Padding for the overall data structure.
254 * @slot_uid:		Valid for all commands except SLOT_COUNT.
255 * @enclave_cid:	Valid for ENCLAVE_START command.
256 * @slot_count :	Valid for SLOT_COUNT command.
257 * @mem_regions:	Valid for SLOT_ALLOC and SLOT_INFO commands.
258 * @mem_size:		Valid for SLOT_INFO command.
259 * @nr_vcpus:		Valid for SLOT_INFO command.
260 * @flags:		Valid for SLOT_INFO command.
261 * @state:		Valid for SLOT_INFO command.
262 * @padding1:		Padding for the overall data structure.
263 */
264struct ne_pci_dev_cmd_reply {
265	s32	rc;
266	u8	padding0[4];
267	u64	slot_uid;
268	u64	enclave_cid;
269	u64	slot_count;
270	u64	mem_regions;
271	u64	mem_size;
272	u64	nr_vcpus;
273	u64	flags;
274	u16	state;
275	u8	padding1[6];
276};
277
278/**
279 * struct ne_pci_dev - Nitro Enclaves (NE) PCI device.
280 * @cmd_reply_avail:		Variable set if a reply has been sent by the
281 *				PCI device.
282 * @cmd_reply_wait_q:		Wait queue for handling command reply from the
283 *				PCI device.
284 * @enclaves_list:		List of the enclaves managed by the PCI device.
285 * @enclaves_list_mutex:	Mutex for accessing the list of enclaves.
286 * @event_wq:			Work queue for handling out-of-band events
287 *				triggered by the Nitro Hypervisor which require
288 *				enclave state scanning and propagation to the
289 *				enclave process.
290 * @iomem_base :		MMIO region of the PCI device.
291 * @notify_work:		Work item for every received out-of-band event.
292 * @pci_dev_mutex:		Mutex for accessing the PCI device MMIO space.
293 * @pdev:			PCI device data structure.
294 */
295struct ne_pci_dev {
296	atomic_t		cmd_reply_avail;
297	wait_queue_head_t	cmd_reply_wait_q;
298	struct list_head	enclaves_list;
299	struct mutex		enclaves_list_mutex;
300	struct workqueue_struct	*event_wq;
301	void __iomem		*iomem_base;
302	struct work_struct	notify_work;
303	struct mutex		pci_dev_mutex;
304	struct pci_dev		*pdev;
305};
306
307/**
308 * ne_do_request() - Submit command request to the PCI device based on the command
309 *		     type and retrieve the associated reply.
310 * @pdev:		PCI device to send the command to and receive the reply from.
311 * @cmd_type:		Command type of the request sent to the PCI device.
312 * @cmd_request:	Command request payload.
313 * @cmd_request_size:	Size of the command request payload.
314 * @cmd_reply:		Command reply payload.
315 * @cmd_reply_size:	Size of the command reply payload.
316 *
317 * Context: Process context. This function uses the ne_pci_dev mutex to handle
318 *	    one command at a time.
319 * Return:
320 * * 0 on success.
321 * * Negative return value on failure.
322 */
323int ne_do_request(struct pci_dev *pdev, enum ne_pci_dev_cmd_type cmd_type,
324		  void *cmd_request, size_t cmd_request_size,
325		  struct ne_pci_dev_cmd_reply *cmd_reply,
326		  size_t cmd_reply_size);
327
328/* Nitro Enclaves (NE) PCI device driver */
329extern struct pci_driver ne_pci_driver;
330
331#endif /* _NE_PCI_DEV_H_ */
~/ Read-only file preview.