Merge tag 'kernel.sys.v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner...
[linux-block.git] / drivers / virt / nitro_enclaves / ne_pci_dev.h
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  */
126 enum 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  */
153 struct 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  */
163 struct 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  */
171 struct 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  */
179 struct 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  */
187 struct 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  */
198 struct 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  */
210 struct 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  */
220 struct 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  */
228 struct 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  */
236 struct 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  */
245 struct 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  */
264 struct 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  */
295 struct 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  */
323 int 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 */
329 extern struct pci_driver ne_pci_driver;
330
331 #endif /* _NE_PCI_DEV_H_ */