PCI Trusted Execution Environment Security Manager (TSM)¶
Subsystem Interfaces¶
-
struct pci_ide_partner¶
Per port pair Selective IDE Stream settings
Definition:
struct pci_ide_partner {
u16 rid_start;
u16 rid_end;
u8 stream_index;
struct pci_bus_region mem_assoc;
struct pci_bus_region pref_assoc;
unsigned int default_stream:1;
unsigned int setup:1;
unsigned int enable:1;
};
Members
rid_startPartner Port Requester ID range start
rid_endPartner Port Requester ID range end
stream_indexSelective IDE Stream Register Block selection
mem_assocPCI bus memory address association for targeting peer partner
pref_assocPCI bus prefetchable memory address association for targeting peer partner
default_streamEndpoint uses this stream for all upstream TLPs regardless of address and RID association registers
setupflag to track whether to run
pci_ide_stream_teardown()for this partner slotenableflag whether to run
pci_ide_stream_disable()for this partner slot
Description
By default, pci_ide_stream_alloc() initializes mem_assoc and pref_assoc
with the immediate ancestor downstream port memory ranges (i.e. Type 1
Configuration Space Header values). Caller may zero size ({0, -1}) the range
to drop it from consideration at pci_ide_stream_setup() time.
-
struct pci_ide_regs¶
Hardware register association settings for Selective IDE Streams
Definition:
struct pci_ide_regs {
u32 rid1;
u32 rid2;
struct {
u32 assoc1;
u32 assoc2;
u32 assoc3;
} addr[2];
int nr_addr;
};
Members
rid1IDE RID Association Register 1
rid2IDE RID Association Register 2
addrUp to two address association blocks (IDE Address Association Register 1 through 3) for MMIO and prefetchable MMIO
nr_addrNumber of address association blocks initialized
Description
See pci_ide_stream_to_regs()
-
struct pci_ide¶
PCIe Selective IDE Stream descriptor
Definition:
struct pci_ide {
struct pci_dev *pdev;
struct pci_ide_partner partner[PCI_IDE_PARTNER_MAX];
u8 host_bridge_stream;
int stream_id;
const char *name;
struct tsm_dev *tsm_dev;
};
Members
pdevPCIe Endpoint in the pci_ide_partner pair
partnerper-partner settings
host_bridge_streamallocated from host bridge ide_stream_ida pool
stream_idunique Stream ID (within Partner Port pairing)
namename of the established Selective IDE Stream in sysfs
tsm_devFor TSM established IDE, the TSM device context
Description
Negative stream_id values indicate “uninitialized” on the expectation that with TSM established IDE the TSM owns the stream_id allocation.
-
struct pci_ide *pci_ide_stream_alloc(struct pci_dev *pdev)¶
Reserve stream indices and probe for settings
Parameters
struct pci_dev *pdevIDE capable PCIe Endpoint Physical Function
Description
Retrieve the Requester ID range of pdev for programming its Root Port IDE RID Association registers, and conversely retrieve the Requester ID of the Root Port for programming pdev’s IDE RID Association registers.
Allocate a Selective IDE Stream Register Block instance per port.
Allocate a platform stream resource from the associated host bridge. Retrieve stream association parameters for Requester ID range and address range restrictions for the stream.
-
void pci_ide_stream_free(struct pci_ide *ide)¶
unwind
pci_ide_stream_alloc()
Parameters
struct pci_ide *ideidle IDE settings descriptor
Description
Free all of the stream index (register block) allocations acquired by
pci_ide_stream_alloc(). The stream represented by ide is assumed to
be unregistered and not instantiated in any device.
Parameters
struct pci_ide *idepartially or fully registered IDE settings descriptor
Description
In support of automatic cleanup of IDE setup routines perform IDE teardown in expected reverse order of setup and with respect to which aspects of IDE setup have successfully completed.
Be careful that setup order mirrors this shutdown order. Otherwise, open code releasing the IDE context.
Parameters
struct pci_ide *ideIDE settings descriptor
Description
After a Stream ID has been acquired for ide, record the presence of the stream in sysfs. The expectation is that ide is immutable while registered.
-
void pci_ide_stream_unregister(struct pci_ide *ide)¶
unwind
pci_ide_stream_register()
Parameters
struct pci_ide *ideidle IDE settings descriptor
Description
In preparation for freeing ide, remove sysfs enumeration for the stream.
-
void pci_ide_stream_setup(struct pci_dev *pdev, struct pci_ide *ide)¶
program settings to Selective IDE Stream registers
Parameters
struct pci_dev *pdevPCIe device object for either a Root Port or Endpoint Partner Port
struct pci_ide *ideregistered IDE settings descriptor
Description
When pdev is a PCI_EXP_TYPE_ENDPOINT then the PCI_IDE_EP partner settings are written to pdev’s Selective IDE Stream register block, and when pdev is a PCI_EXP_TYPE_ROOT_PORT, the PCI_IDE_RP settings are selected.
-
void pci_ide_stream_teardown(struct pci_dev *pdev, struct pci_ide *ide)¶
disable the stream and clear all settings
Parameters
struct pci_dev *pdevPCIe device object for either a Root Port or Endpoint Partner Port
struct pci_ide *ideregistered IDE settings descriptor
Description
For stream destruction, zero all registers that may have been written
by pci_ide_stream_setup(). Consider pci_ide_stream_disable() to leave
settings in place while temporarily disabling the stream.
Parameters
struct pci_dev *pdevPCIe device object for either a Root Port or Endpoint Partner Port
struct pci_ide *ideregistered and setup IDE settings descriptor
Description
Activate the stream by writing to the Selective IDE Stream Control Register.
Note that the state may go “insecure” at any point after returning 0, but those events are equivalent to a “link down” event and handled via asynchronous error reporting.
Caller is responsible to clear the enable bit in the -ENXIO case.
Return
0 if the stream successfully entered the “secure” state, and -EINVAL if ide is invalid, and -ENXIO if the stream fails to enter the secure state.
-
void pci_ide_stream_disable(struct pci_dev *pdev, struct pci_ide *ide)¶
disable a Selective IDE Stream
Parameters
struct pci_dev *pdevPCIe device object for either a Root Port or Endpoint Partner Port
struct pci_ide *ideregistered and setup IDE settings descriptor
Description
Clear the Selective IDE Stream Control Register, but leave all other registers untouched.
-
void pci_ide_set_nr_streams(struct pci_host_bridge *hb, u16 nr)¶
sets size of the pool of IDE Stream resources
Parameters
struct pci_host_bridge *hbhost bridge boundary for the stream pool
u16 nrnumber of streams
Description
Platform PCI init and/or expert test module use only. Limit IDE
Stream establishment by setting the number of stream resources
available at the host bridge. Platform init code must set this before
the first pci_ide_stream_alloc() call if the platform has less than the
default of 256 streams per host-bridge.
The “PCI_IDE” symbol namespace is required because this is typically a detail that is settled in early PCI init. I.e. this export is not for endpoint drivers.
-
struct pci_tdi¶
Core TEE I/O Device Interface (TDI) context
Definition:
struct pci_tdi {
struct pci_dev *pdev;
struct kvm *kvm;
u32 tdi_id;
};
Members
pdevhost side representation of guest-side TDI
kvmTEE VM context of bound TDI
tdi_idIdentifier (virtual BDF) for the TDI as referenced by the TSM and DSM
-
struct pci_tsm¶
Core TSM context for a given PCIe endpoint
Definition:
struct pci_tsm {
struct pci_dev *pdev;
struct pci_dev *dsm_dev;
struct tsm_dev *tsm_dev;
struct pci_tdi *tdi;
};
Members
pdevBack ref to device function, distinguishes type of pci_tsm context
dsm_devPCI Device Security Manager for link operations on pdev
tsm_devPCI TEE Security Manager device for Link Confidentiality or Device Function Security operations
tdiTDI context established by the bind link operation
Description
This structure is wrapped by low level TSM driver data and returned by
probe()/lock(), it is freed by the corresponding remove()/unlock().
For link operations it serves to cache the association between a Device Security Manager (DSM) and the functions that manager can assign to a TVM. That can be “self”, for assigning function0 of a TEE I/O device, a sub-function (SR-IOV virtual function, or non-function0 multifunction-device), or a downstream endpoint (PCIe upstream switch-port as DSM).
-
struct pci_tsm_pf0¶
Physical Function 0 TDISP link context
Definition:
struct pci_tsm_pf0 {
struct pci_tsm base_tsm;
struct mutex lock;
struct pci_doe_mb *doe_mb;
};
Members
base_tsmgeneric core “tsm” context
lockmutual exclustion for pci_tsm_ops invocation
doe_mbPCIe Data Object Exchange mailbox
-
enum pci_tsm_req_scope¶
Scope of guest requests to be validated by TSM
Constants
PCI_TSM_REQ_INFORead-only, without side effects, request for typical TDISP collateral information like Device Interface Reports. No device secrets are permitted, and no device state is changed.
PCI_TSM_REQ_STATE_CHANGERequest to change the TDISP state from UNLOCKED->LOCKED, LOCKED->RUN, or other architecture specific state changes to support those transitions for a TDI. No other (unrelated to TDISP) device / host state, configuration, or data change is permitted.
PCI_TSM_REQ_DEBUG_READRead-only request for debug information
A method to facilitate TVM information retrieval outside of typical TDISP operational requirements. No device secrets are permitted.
PCI_TSM_REQ_DEBUG_WRITEDevice state changes for debug purposes
The request may affect the operational state of the device outside of the TDISP operational model. If allowed, requires CAP_SYS_RAW_IO, and will taint the kernel.
Description
Guest requests are a transport for a TVM to communicate with a TSM + DSM for a given TDI. A TSM driver is responsible for maintaining the kernel security model and limit commands that may affect the host, or are otherwise outside the typical TDISP operational model.
Parameters
struct pci_dev *pdevPCI device function to bind
struct kvm *kvmPrivate memory attach context
u32 tdi_idIdentifier (virtual BDF) for the TDI as referenced by the TSM and DSM
Description
Returns 0 on success, or a negative error code on failure.
Context
Caller is responsible for constraining the bind lifetime to the
registered state of the device. For example, pci_tsm_bind() /
pci_tsm_unbind() limited to the VFIO driver bound state of the device.
-
ssize_t pci_tsm_guest_req(struct pci_dev *pdev, enum pci_tsm_req_scope scope, sockptr_t req_in, size_t in_len, sockptr_t req_out, size_t out_len, u64 *tsm_code)¶
helper to marshal guest requests to the TSM driver
Parameters
struct pci_dev *pdevpdev representing a bound tdi
enum pci_tsm_req_scope scopecaller asserts this passthrough request is limited to TDISP operations
sockptr_t req_inInput payload forwarded from the guest
size_t in_lenLength of req_in
sockptr_t req_outOutput payload buffer response to the guest
size_t out_lenLength of req_out on input, bytes filled in req_out on output
u64 *tsm_codeOptional TSM arch specific result code for the guest TSM
Description
This is a common entry point for requests triggered by userspace KVM-exit service handlers responding to TDI information or state change requests. The scope parameter limits requests to TDISP state management, or limited debug. This path is only suitable for commands and results that are the host kernel has no use, the host is only facilitating guest to TSM communication.
Returns 0 on success and -error on failure and positive “residue” on success but req_out is filled with less then out_len, or req_out is NULL and a residue number of bytes were not consumed from req_in. On success or failure tsm_code may be populated with a TSM implementation specific result code for the guest to consume.
Context
Caller is responsible for calling this within the pci_tsm_bind()
state of the TDI.
-
void pci_tsm_tdi_constructor(struct pci_dev *pdev, struct pci_tdi *tdi, struct kvm *kvm, u32 tdi_id)¶
base ‘
struct pci_tdi’ initialization for link TSMs
Parameters
struct pci_dev *pdevPCI device function representing the TDI
struct pci_tdi *tdicontext to initialize
struct kvm *kvmPrivate memory attach context
u32 tdi_idIdentifier (virtual BDF) for the TDI as referenced by the TSM and DSM
-
int pci_tsm_link_constructor(struct pci_dev *pdev, struct pci_tsm *tsm, struct tsm_dev *tsm_dev)¶
base ‘
struct pci_tsm’ initialization for link TSMs
Parameters
struct pci_dev *pdevThe PCI device
struct pci_tsm *tsmcontext to initialize
struct tsm_dev *tsm_devPlatform TEE Security Manager, initiator of security operations
-
int pci_tsm_pf0_constructor(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm, struct tsm_dev *tsm_dev)¶
common ‘
struct pci_tsm_pf0’ (DSM) initialization
Parameters
struct pci_dev *pdevPhysical Function 0 PCI device (as indicated by
is_pci_tsm_pf0())struct pci_tsm_pf0 *tsmcontext to initialize
struct tsm_dev *tsm_devPlatform TEE Security Manager, initiator of security operations