cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ne_pci_dev.h (9004B)


      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_ */