PCI Trusted Execution Environment Security Manager (TSM)

Subsystem Interfaces

structpci_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_start

Partner Port Requester ID range start

rid_end

Partner Port Requester ID range end (inclusive)

stream_index

Selective IDE Stream Register Block selection

mem_assoc

PCI bus memory address association for targeting peer partner

pref_assoc

PCI bus prefetchable memory address association fortargeting peer partner

default_stream

Endpoint uses this stream for all upstream TLPs regardless ofaddress and RID association registers

setup

flag to track whether to runpci_ide_stream_teardown() for thispartner slot

enable

flag whether to runpci_ide_stream_disable() for this partner slot

Description

By default,pci_ide_stream_alloc() initializesmem_assoc andpref_assocwith the immediate ancestor downstream port memory ranges (i.e. Type 1Configuration Space Header values). Caller may zero size ({0, -1}) the rangeto drop it from consideration atpci_ide_stream_setup() time.

structpci_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

rid1

IDE RID Association Register 1

rid2

IDE RID Association Register 2

addr

Up to two address association blocks (IDE Address Association Register1 through 3) for MMIO and prefetchable MMIO

nr_addr

Number of address association blocks initialized

Description

Seepci_ide_stream_to_regs()

structpci_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;};

Members

pdev

PCIe Endpoint in the pci_ide_partner pair

partner

per-partner settings

host_bridge_stream

allocated from host bridgeide_stream_ida pool

stream_id

unique Stream ID (within Partner Port pairing)

name

name of the established Selective IDE Stream in sysfs

Description

Negativestream_id values indicate “uninitialized” on theexpectation that with TSM established IDE the TSM owns the stream_idallocation.

structpci_ide*pci_ide_stream_alloc(structpci_dev*pdev)

Reserve stream indices and probe for settings

Parameters

structpci_dev*pdev

IDE capable PCIe Endpoint Physical Function

Description

Retrieve the Requester ID range ofpdev for programming its RootPort IDE RID Association registers, and conversely retrieve theRequester ID of the Root Port for programmingpdev’s IDE RIDAssociation 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 andaddress range restrictions for the stream.

voidpci_ide_stream_free(structpci_ide*ide)

unwindpci_ide_stream_alloc()

Parameters

structpci_ide*ide

idle IDE settings descriptor

Description

Free all of the stream index (register block) allocations acquired bypci_ide_stream_alloc(). The stream represented byide is assumed tobe unregistered and not instantiated in any device.

voidpci_ide_stream_release(structpci_ide*ide)

unwind and release anide context

Parameters

structpci_ide*ide

partially or fully registered IDE settings descriptor

Description

In support of automatic cleanup of IDE setup routines perform IDEteardown in expected reverse order of setup and with respect to whichaspects of IDE setup have successfully completed.

Be careful that setup order mirrors this shutdown order. Otherwise,open code releasing the IDE context.

intpci_ide_stream_register(structpci_ide*ide)

Prepare to activate an IDE Stream

Parameters

structpci_ide*ide

IDE settings descriptor

Description

After a Stream ID has been acquired foride, record the presence ofthe stream in sysfs. The expectation is thatide is immutable whileregistered.

voidpci_ide_stream_unregister(structpci_ide*ide)

unwindpci_ide_stream_register()

Parameters

structpci_ide*ide

idle IDE settings descriptor

Description

In preparation for freeingide, remove sysfs enumeration for thestream.

voidpci_ide_stream_setup(structpci_dev*pdev,structpci_ide*ide)

program settings to Selective IDE Stream registers

Parameters

structpci_dev*pdev

PCIe device object for either a Root Port or Endpoint Partner Port

structpci_ide*ide

registered IDE settings descriptor

Description

Whenpdev is a PCI_EXP_TYPE_ENDPOINT then the PCI_IDE_EP partnersettings are written topdev’s Selective IDE Stream register block,and whenpdev is a PCI_EXP_TYPE_ROOT_PORT, the PCI_IDE_RP settingsare selected.

voidpci_ide_stream_teardown(structpci_dev*pdev,structpci_ide*ide)

disable the stream and clear all settings

Parameters

structpci_dev*pdev

PCIe device object for either a Root Port or Endpoint Partner Port

structpci_ide*ide

registered IDE settings descriptor

Description

For stream destruction, zero all registers that may have been writtenbypci_ide_stream_setup(). Considerpci_ide_stream_disable() to leavesettings in place while temporarily disabling the stream.

intpci_ide_stream_enable(structpci_dev*pdev,structpci_ide*ide)

enable a Selective IDE Stream

Parameters

structpci_dev*pdev

PCIe device object for either a Root Port or Endpoint Partner Port

structpci_ide*ide

registered and setup IDE settings descriptor

Description

Activate the stream by writing to the Selective IDE Stream ControlRegister.

Note that the state may go “insecure” at any point after returning 0, butthose events are equivalent to a “link down” event and handled viaasynchronous 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 -EINVALifide is invalid, and -ENXIO if the stream fails to enter the secure state.

voidpci_ide_stream_disable(structpci_dev*pdev,structpci_ide*ide)

disable a Selective IDE Stream

Parameters

structpci_dev*pdev

PCIe device object for either a Root Port or Endpoint Partner Port

structpci_ide*ide

registered and setup IDE settings descriptor

Description

Clear the Selective IDE Stream Control Register, but leave all otherregisters untouched.

voidpci_ide_set_nr_streams(structpci_host_bridge*hb,u16nr)

sets size of the pool of IDE Stream resources

Parameters

structpci_host_bridge*hb

host bridge boundary for the stream pool

u16nr

number of streams

Description

Platform PCI init and/or expert test module use only. Limit IDEStream establishment by setting the number of stream resourcesavailable at the host bridge. Platform init code must set this beforethe firstpci_ide_stream_alloc() call if the platform has less than thedefault of 256 streams per host-bridge.

The “PCI_IDE” symbol namespace is required because this is typicallya detail that is settled in early PCI init. I.e. this export is notfor endpoint drivers.

structpci_tdi

Core TEE I/O Device Interface (TDI) context

Definition:

struct pci_tdi {    struct pci_dev *pdev;    struct kvm *kvm;    u32 tdi_id;};

Members

pdev

host side representation of guest-side TDI

kvm

TEE VM context of bound TDI

tdi_id

Identifier (virtual BDF) for the TDI as referenced by the TSM and DSM

structpci_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

pdev

Back ref to device function, distinguishes type of pci_tsm context

dsm_dev

PCI Device Security Manager for link operations onpdev

tsm_dev

PCI TEE Security Manager device for Link Confidentiality or DeviceFunction Security operations

tdi

TDI context established by thebind link operation

Description

This structure is wrapped by low level TSM driver data and returned byprobe()/lock(), it is freed by the correspondingremove()/unlock().

For link operations it serves to cache the association between a DeviceSecurity 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, asub-function (SR-IOV virtual function, or non-function0multifunction-device), or a downstream endpoint (PCIe upstream switch-port asDSM).

structpci_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_tsm

generic core “tsm” context

lock

mutual exclustion for pci_tsm_ops invocation

doe_mb

PCIe Data Object Exchange mailbox

enumpci_tsm_req_scope

Scope of guest requests to be validated by TSM

Constants

PCI_TSM_REQ_INFO

Read-only, without side effects, request fortypical TDISP collateral information like Device Interface Reports.No device secrets are permitted, and no device state is changed.

PCI_TSM_REQ_STATE_CHANGE

Request to change the TDISP state fromUNLOCKED->LOCKED, LOCKED->RUN, or other architecture specific statechanges to support those transitions for a TDI. No other (unrelatedto TDISP) device / host state, configuration, or data change ispermitted.

PCI_TSM_REQ_DEBUG_READ

Read-only request for debug information

A method to facilitate TVM information retrieval outside of typicalTDISP operational requirements. No device secrets are permitted.

PCI_TSM_REQ_DEBUG_WRITE

Device state changes for debug purposes

The request may affect the operational state of the device outside ofthe TDISP operational model. If allowed, requires CAP_SYS_RAW_IO, andwill taint the kernel.

Description

Guest requests are a transport for a TVM to communicate with a TSM + DSM fora given TDI. A TSM driver is responsible for maintaining the kernel securitymodel and limit commands that may affect the host, or are otherwise outsidethe typical TDISP operational model.

intpci_tsm_bind(structpci_dev*pdev,structkvm*kvm,u32tdi_id)

Bindpdev as a TDI forkvm

Parameters

structpci_dev*pdev

PCI device function to bind

structkvm*kvm

Private memory attach context

u32tdi_id

Identifier (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 theregistered state of the device. For example,pci_tsm_bind() /pci_tsm_unbind() limited to the VFIO driver bound state of the device.

ssize_tpci_tsm_guest_req(structpci_dev*pdev,enumpci_tsm_req_scopescope,sockptr_treq_in,size_tin_len,sockptr_treq_out,size_tout_len,u64*tsm_code)

helper to marshal guest requests to the TSM driver

Parameters

structpci_dev*pdev

pdev representing a bound tdi

enumpci_tsm_req_scopescope

caller asserts this passthrough request is limited to TDISP operations

sockptr_treq_in

Input payload forwarded from the guest

size_tin_len

Length ofreq_in

sockptr_treq_out

Output payload buffer response to the guest

size_tout_len

Length ofreq_out on input, bytes filled inreq_out on output

u64*tsm_code

Optional TSM arch specific result code for the guest TSM

Description

This is a common entry point for requests triggered by userspace KVM-exitservice handlers responding to TDI information or state change requests. Thescope parameter limits requests to TDISP state management, or limited debug.This path is only suitable for commands and results that are the host kernelhas no use, the host is only facilitating guest to TSM communication.

Returns 0 on success and -error on failure and positive “residue” on successbutreq_out is filled with less thenout_len, orreq_out is NULL and aresidue number of bytes were not consumed fromreq_in. On success orfailuretsm_code may be populated with a TSM implementation specific resultcode for the guest to consume.

Context

Caller is responsible for calling this within thepci_tsm_bind()state of the TDI.

voidpci_tsm_tdi_constructor(structpci_dev*pdev,structpci_tdi*tdi,structkvm*kvm,u32tdi_id)

base ‘structpci_tdi’ initialization for link TSMs

Parameters

structpci_dev*pdev

PCI device function representing the TDI

structpci_tdi*tdi

context to initialize

structkvm*kvm

Private memory attach context

u32tdi_id

Identifier (virtual BDF) for the TDI as referenced by the TSM and DSM

intpci_tsm_link_constructor(structpci_dev*pdev,structpci_tsm*tsm,structtsm_dev*tsm_dev)

base ‘structpci_tsm’ initialization for link TSMs

Parameters

structpci_dev*pdev

The PCI device

structpci_tsm*tsm

context to initialize

structtsm_dev*tsm_dev

Platform TEE Security Manager, initiator of security operations

intpci_tsm_pf0_constructor(structpci_dev*pdev,structpci_tsm_pf0*tsm,structtsm_dev*tsm_dev)

common ‘structpci_tsm_pf0’ (DSM) initialization

Parameters

structpci_dev*pdev

Physical Function 0 PCI device (as indicated byis_pci_tsm_pf0())

structpci_tsm_pf0*tsm

context to initialize

structtsm_dev*tsm_dev

Platform TEE Security Manager, initiator of security operations