Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

API Reference

This page is auto-generated from the PCIem kernel headers. Do not edit it by hand — run make docs to regenerate.

PCIem exposes a userspace-facing API through /dev/pciem that lets developers configure and emulate PCIe devices entirely from userspace.

Contents

Constants

PCIEM_CAP_*

NameValueDescription
PCIEM_CAP_MSI0
PCIEM_CAP_MSIX1
PCIEM_CAP_PASID5
PCIEM_CAP_PCIE3
PCIEM_CAP_PM2
PCIEM_CAP_VSEC4

PCIEM_EVENT_*

NameValueDescription
PCIEM_EVENT_CONFIG_READ3
PCIEM_EVENT_CONFIG_WRITE4
PCIEM_EVENT_MMIO_READ1
PCIEM_EVENT_MMIO_WRITE2
PCIEM_EVENT_MSI_ACK5
PCIEM_EVENT_RESET6

PCIEM_TRACE_*

NameValueDescription
PCIEM_TRACE_READS(1 << 0)
PCIEM_TRACE_STOP_WRITES(1 << 2)
PCIEM_TRACE_WRITES(1 << 1)

PCIEM_ATOMIC_*

NameValueDescription
PCIEM_ATOMIC_CAS4
PCIEM_ATOMIC_FETCH_ADD1
PCIEM_ATOMIC_FETCH_AND5
PCIEM_ATOMIC_FETCH_OR6
PCIEM_ATOMIC_FETCH_SUB2
PCIEM_ATOMIC_FETCH_XOR7
PCIEM_ATOMIC_SWAP3

PCIEM_DMA_FLAG_*

NameValueDescription
PCIEM_DMA_FLAG_READ0x1
PCIEM_DMA_FLAG_WRITE0x2

PCIEM_IRQFD_FLAG_*

NameValueDescription
PCIEM_IRQFD_FLAG_DEASSERT(1 << 1)
PCIEM_IRQFD_FLAG_LEVEL(1 << 0)

PCIEM_WP_FLAG_BAR_*

NameValueDescription
PCIEM_WP_FLAG_BAR_KPROBES(1 << 0)
PCIEM_WP_FLAG_BAR_MANUAL(1 << 1)

PCIEM_CREATE_FLAG_BUS_MODE_*

NameValueDescription
PCIEM_CREATE_FLAG_BUS_MODE_ATTACH0x00000001Attach to an existing physical PCIe bus.
PCIEM_CREATE_FLAG_BUS_MODE_MASK0x00000003Mask to extract the bus mode bits from the flags field.
PCIEM_CREATE_FLAG_BUS_MODE_VIRTUAL0x00000000Create a virtual PCIe bus owned entirely by PCIem.

Miscellaneous

NameValueDescription
PCIEM_MAX_IRQFDS32
PCIEM_RING_SIZE256

Structures

Defined in pciem_api.h

pciem_create_device

struct pciem_create_device
{
    uint32_t flags;
};
FieldTypeDescription
flagsuint32_t

Used by: PCIEM_IOCTL_CREATE_DEVICE

pciem_bar_config

struct pciem_bar_config
{
    uint32_t bar_index;
    uint32_t flags;
    uint64_t size;
    uint32_t reserved;
};
FieldTypeDescription
bar_indexuint32_t
flagsuint32_t
sizeuint64_t
reserveduint32_t

Used by: PCIEM_IOCTL_ADD_BAR

pciem_cap_msi_userspace

struct pciem_cap_msi_userspace
{
    uint8_t num_vectors_log2;
    uint8_t has_64bit;
    uint8_t has_masking;
    uint8_t reserved;
};
FieldTypeDescription
num_vectors_log2uint8_t
has_64bituint8_t
has_maskinguint8_t
reserveduint8_t

pciem_cap_msix_userspace

struct pciem_cap_msix_userspace
{
    uint8_t bar_index;
    uint8_t reserved[3];
    uint32_t table_offset;
    uint32_t pba_offset;
    uint16_t table_size;
    uint16_t reserved2;
};
FieldTypeDescription
bar_indexuint8_t
reserveduint8_t[3]
table_offsetuint32_t
pba_offsetuint32_t
table_sizeuint16_t
reserved2uint16_t

pciem_cap_pasid_userspace

struct pciem_cap_pasid_userspace
{
    uint8_t max_pasid_width;
    uint8_t execute_permission;
    uint8_t privileged_mode;
    uint8_t reserved;
};
FieldTypeDescription
max_pasid_widthuint8_t
execute_permissionuint8_t
privileged_modeuint8_t
reserveduint8_t

pciem_cap_config

struct pciem_cap_config
{
    uint32_t cap_type;
    struct pciem_cap_msi_userspace msi;
    struct pciem_cap_msix_userspace msix;
    struct pciem_cap_pasid_userspace pasid;
};

Used by: PCIEM_IOCTL_ADD_CAPABILITY

pciem_config_space

struct pciem_config_space
{
    uint16_t vendor_id;
    uint16_t device_id;
    uint16_t subsys_vendor_id;
    uint16_t subsys_device_id;
    uint8_t revision;
    uint8_t class_code[3];
    uint8_t header_type;
    uint8_t reserved[7];
};
FieldTypeDescription
vendor_iduint16_t
device_iduint16_t
subsys_vendor_iduint16_t
subsys_device_iduint16_t
revisionuint8_t
class_codeuint8_t[3]
header_typeuint8_t
reserveduint8_t[7]

Used by: PCIEM_IOCTL_SET_CONFIG

pciem_event

struct pciem_event
{
    uint64_t seq;
    uint32_t type;
    uint32_t bar;
    uint64_t offset;
    uint32_t size;
    uint32_t reserved;
    uint64_t data;
    uint64_t timestamp;
};
FieldTypeDescription
sequint64_t
typeuint32_t
baruint32_t
offsetuint64_t
sizeuint32_t
reserveduint32_t
datauint64_t
timestampuint64_t

pciem_response

struct pciem_response
{
    uint64_t seq;
    uint64_t data;
    int32_t status;
    uint32_t reserved;
};
FieldTypeDescription
sequint64_t
datauint64_t
statusint32_t
reserveduint32_t

pciem_irq_inject

Parameters for PCIEM_IOCTL_INJECT_IRQ.

struct pciem_irq_inject
{
    uint32_t vector;
    uint32_t reserved;
};
FieldTypeDescription
vectoruint32_tMSI/MSI-X vector number to inject into the guest.
reserveduint32_tMust be zero.

Used by: PCIEM_IOCTL_INJECT_IRQ

pciem_dma_op

struct pciem_dma_op
{
    uint64_t guest_iova;
    uint64_t user_addr;
    uint32_t length;
    uint32_t pasid;
    uint32_t flags;
    uint32_t reserved;
};
FieldTypeDescription
guest_iovauint64_t
user_addruint64_t
lengthuint32_t
pasiduint32_t
flagsuint32_t
reserveduint32_t

Used by: PCIEM_IOCTL_DMA

pciem_dma_atomic

struct pciem_dma_atomic
{
    uint64_t guest_iova;
    uint64_t operand;
    uint64_t compare;
    uint32_t op_type;
    uint32_t pasid;
    uint64_t result;
};
FieldTypeDescription
guest_iovauint64_t
operanduint64_t
compareuint64_t
op_typeuint32_t
pasiduint32_t
resultuint64_t

Used by: PCIEM_IOCTL_DMA_ATOMIC

pciem_p2p_op_user

struct pciem_p2p_op_user
{
    uint64_t target_phys_addr;
    uint64_t user_addr;
    uint32_t length;
    uint32_t flags;
};
FieldTypeDescription
target_phys_addruint64_t
user_addruint64_t
lengthuint32_t
flagsuint32_t

Used by: PCIEM_IOCTL_P2P

pciem_bar_info_query

struct pciem_bar_info_query
{
    uint32_t bar_index;
    uint64_t phys_addr;
    uint64_t size;
    uint32_t flags;
};
FieldTypeDescription
bar_indexuint32_t
phys_addruint64_t
sizeuint64_t
flagsuint32_t

Used by: PCIEM_IOCTL_GET_BAR_INFO

pciem_eventfd_config

struct pciem_eventfd_config
{
    int32_t eventfd;
    uint32_t reserved;
};
FieldTypeDescription
eventfdint32_t
reserveduint32_t

Used by: PCIEM_IOCTL_SET_EVENTFD

pciem_irqfd_config

struct pciem_irqfd_config
{
    int32_t eventfd;
    uint32_t vector;
    uint32_t flags;
    uint32_t reserved;
};
FieldTypeDescription
eventfdint32_t
vectoruint32_t
flagsuint32_t
reserveduint32_t

Used by: PCIEM_IOCTL_SET_IRQFD

pciem_dma_indirect

struct pciem_dma_indirect
{
    uint64_t prp1;
    uint64_t prp2;
    uint64_t user_addr;
    uint32_t length;
    uint32_t page_size;
    uint32_t pasid;
    uint32_t flags;
    uint32_t reserved;
};
FieldTypeDescription
prp1uint64_t
prp2uint64_t
user_addruint64_t
lengthuint32_t
page_sizeuint32_t
pasiduint32_t
flagsuint32_t
reserveduint32_t

Used by: PCIEM_IOCTL_DMA_INDIRECT

pciem_trace_bar

struct pciem_trace_bar
{
    uint32_t bar_index;
    uint32_t flags;
};
FieldTypeDescription
bar_indexuint32_t
flagsuint32_t

Used by: PCIEM_IOCTL_TRACE_BAR

pciem_shared_ring

Lock-free single-producer/single-consumer event ring shared between the kernel and userspace.

The kernel writes events by advancing @head; userspace consumes them by advancing @tail. Each counter is cache-line padded. The ring is mapped read-only into userspace via mmap on the PCIem fd.

@head from @tail.

@tail from the event array.

struct pciem_shared_ring
{
    atomic_t head;
    char _pad1[60];
    atomic_t tail;
    char _pad2[60];
    struct pciem_event events[PCIEM_RING_SIZE];
};
FieldTypeDescription
headatomic_tWrite index, owned by the kernel. Incremented atomically after each event is committed.
_pad1char[60]Cache-line padding to isolate
tailatomic_tRead index, owned by userspace. Incremented after each event is consumed.
_pad2char[60]Cache-line padding to isolate
eventsstruct pciem_event[PCIEM_RING_SIZE]Circular buffer of PCIEM_RING_SIZE events.

IOCTLs

All ioctls are issued on the /dev/pciem file descriptor unless noted otherwise.

PCIEM_IOCTL_CREATE_DEVICE

#define PCIEM_IOCTL_CREATE_DEVICE _IOWR(PCIEM_IOCTL_MAGIC, 10, struct pciem_create_device)

Direction: read/write (both directions)

Parameter struct: pciem_create_device

struct pciem_create_device arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_CREATE_DEVICE, &arg);

PCIEM_IOCTL_ADD_BAR

#define PCIEM_IOCTL_ADD_BAR _IOW(PCIEM_IOCTL_MAGIC, 11, struct pciem_bar_config)

Direction: write (userspace → kernel)

Parameter struct: pciem_bar_config

struct pciem_bar_config arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_ADD_BAR, &arg);

PCIEM_IOCTL_ADD_CAPABILITY

#define PCIEM_IOCTL_ADD_CAPABILITY _IOW(PCIEM_IOCTL_MAGIC, 12, struct pciem_cap_config)

Direction: write (userspace → kernel)

Parameter struct: pciem_cap_config

struct pciem_cap_config arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_ADD_CAPABILITY, &arg);

PCIEM_IOCTL_SET_CONFIG

#define PCIEM_IOCTL_SET_CONFIG _IOW(PCIEM_IOCTL_MAGIC, 13, struct pciem_config_space)

Direction: write (userspace → kernel)

Parameter struct: pciem_config_space

struct pciem_config_space arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_SET_CONFIG, &arg);

PCIEM_IOCTL_REGISTER

#define PCIEM_IOCTL_REGISTER _IO(PCIEM_IOCTL_MAGIC, 14)

Direction: none (no data transfer)

int ret = ioctl(fd, PCIEM_IOCTL_REGISTER);

PCIEM_IOCTL_INJECT_IRQ

#define PCIEM_IOCTL_INJECT_IRQ _IOW(PCIEM_IOCTL_MAGIC, 15, struct pciem_irq_inject)

Direction: write (userspace → kernel)

Parameter struct: pciem_irq_inject

struct pciem_irq_inject arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_INJECT_IRQ, &arg);

PCIEM_IOCTL_DMA

#define PCIEM_IOCTL_DMA _IOWR(PCIEM_IOCTL_MAGIC, 16, struct pciem_dma_op)

Direction: read/write (both directions)

Parameter struct: pciem_dma_op

struct pciem_dma_op arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_DMA, &arg);

PCIEM_IOCTL_DMA_ATOMIC

#define PCIEM_IOCTL_DMA_ATOMIC _IOWR(PCIEM_IOCTL_MAGIC, 17, struct pciem_dma_atomic)

Direction: read/write (both directions)

Parameter struct: pciem_dma_atomic

struct pciem_dma_atomic arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_DMA_ATOMIC, &arg);

PCIEM_IOCTL_P2P

#define PCIEM_IOCTL_P2P _IOWR(PCIEM_IOCTL_MAGIC, 18, struct pciem_p2p_op_user)

Direction: read/write (both directions)

Parameter struct: pciem_p2p_op_user

struct pciem_p2p_op_user arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_P2P, &arg);

PCIEM_IOCTL_GET_BAR_INFO

#define PCIEM_IOCTL_GET_BAR_INFO _IOWR(PCIEM_IOCTL_MAGIC, 19, struct pciem_bar_info_query)

Direction: read/write (both directions)

Parameter struct: pciem_bar_info_query

struct pciem_bar_info_query arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_GET_BAR_INFO, &arg);

PCIEM_IOCTL_SET_EVENTFD

#define PCIEM_IOCTL_SET_EVENTFD _IOW(PCIEM_IOCTL_MAGIC, 21, struct pciem_eventfd_config)

Direction: write (userspace → kernel)

Parameter struct: pciem_eventfd_config

struct pciem_eventfd_config arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_SET_EVENTFD, &arg);

PCIEM_IOCTL_SET_IRQFD

#define PCIEM_IOCTL_SET_IRQFD _IOW(PCIEM_IOCTL_MAGIC, 22, struct pciem_irqfd_config)

Direction: write (userspace → kernel)

Parameter struct: pciem_irqfd_config

struct pciem_irqfd_config arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_SET_IRQFD, &arg);

PCIEM_IOCTL_DMA_INDIRECT

#define PCIEM_IOCTL_DMA_INDIRECT _IOWR(PCIEM_IOCTL_MAGIC, 24, struct pciem_dma_indirect)

Direction: read/write (both directions)

Parameter struct: pciem_dma_indirect

struct pciem_dma_indirect arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_DMA_INDIRECT, &arg);

PCIEM_IOCTL_TRACE_BAR

#define PCIEM_IOCTL_TRACE_BAR _IOWR(PCIEM_IOCTL_MAGIC, 25, struct pciem_trace_bar)

Direction: read/write (both directions)

Parameter struct: pciem_trace_bar

struct pciem_trace_bar arg = { /* ... */ };
int ret = ioctl(fd, PCIEM_IOCTL_TRACE_BAR, &arg);

PCIEM_IOCTL_START

#define PCIEM_IOCTL_START _IO(PCIEM_IOCTL_MAGIC, 26)

Direction: none (no data transfer)

int ret = ioctl(fd, PCIEM_IOCTL_START);