1*f363d039SEric Auger /* SPDX-License-Identifier: BSD-3-Clause */ 2*f363d039SEric Auger /* 3*f363d039SEric Auger * Virtio-iommu definition v0.12 4*f363d039SEric Auger * 5*f363d039SEric Auger * Copyright (C) 2019 Arm Ltd. 6*f363d039SEric Auger */ 7*f363d039SEric Auger #ifndef _LINUX_VIRTIO_IOMMU_H 8*f363d039SEric Auger #define _LINUX_VIRTIO_IOMMU_H 9*f363d039SEric Auger 10*f363d039SEric Auger #include "standard-headers/linux/types.h" 11*f363d039SEric Auger 12*f363d039SEric Auger /* Feature bits */ 13*f363d039SEric Auger #define VIRTIO_IOMMU_F_INPUT_RANGE 0 14*f363d039SEric Auger #define VIRTIO_IOMMU_F_DOMAIN_RANGE 1 15*f363d039SEric Auger #define VIRTIO_IOMMU_F_MAP_UNMAP 2 16*f363d039SEric Auger #define VIRTIO_IOMMU_F_BYPASS 3 17*f363d039SEric Auger #define VIRTIO_IOMMU_F_PROBE 4 18*f363d039SEric Auger #define VIRTIO_IOMMU_F_MMIO 5 19*f363d039SEric Auger 20*f363d039SEric Auger struct virtio_iommu_range_64 { 21*f363d039SEric Auger uint64_t start; 22*f363d039SEric Auger uint64_t end; 23*f363d039SEric Auger }; 24*f363d039SEric Auger 25*f363d039SEric Auger struct virtio_iommu_range_32 { 26*f363d039SEric Auger uint32_t start; 27*f363d039SEric Auger uint32_t end; 28*f363d039SEric Auger }; 29*f363d039SEric Auger 30*f363d039SEric Auger struct virtio_iommu_config { 31*f363d039SEric Auger /* Supported page sizes */ 32*f363d039SEric Auger uint64_t page_size_mask; 33*f363d039SEric Auger /* Supported IOVA range */ 34*f363d039SEric Auger struct virtio_iommu_range_64 input_range; 35*f363d039SEric Auger /* Max domain ID size */ 36*f363d039SEric Auger struct virtio_iommu_range_32 domain_range; 37*f363d039SEric Auger /* Probe buffer size */ 38*f363d039SEric Auger uint32_t probe_size; 39*f363d039SEric Auger }; 40*f363d039SEric Auger 41*f363d039SEric Auger /* Request types */ 42*f363d039SEric Auger #define VIRTIO_IOMMU_T_ATTACH 0x01 43*f363d039SEric Auger #define VIRTIO_IOMMU_T_DETACH 0x02 44*f363d039SEric Auger #define VIRTIO_IOMMU_T_MAP 0x03 45*f363d039SEric Auger #define VIRTIO_IOMMU_T_UNMAP 0x04 46*f363d039SEric Auger #define VIRTIO_IOMMU_T_PROBE 0x05 47*f363d039SEric Auger 48*f363d039SEric Auger /* Status types */ 49*f363d039SEric Auger #define VIRTIO_IOMMU_S_OK 0x00 50*f363d039SEric Auger #define VIRTIO_IOMMU_S_IOERR 0x01 51*f363d039SEric Auger #define VIRTIO_IOMMU_S_UNSUPP 0x02 52*f363d039SEric Auger #define VIRTIO_IOMMU_S_DEVERR 0x03 53*f363d039SEric Auger #define VIRTIO_IOMMU_S_INVAL 0x04 54*f363d039SEric Auger #define VIRTIO_IOMMU_S_RANGE 0x05 55*f363d039SEric Auger #define VIRTIO_IOMMU_S_NOENT 0x06 56*f363d039SEric Auger #define VIRTIO_IOMMU_S_FAULT 0x07 57*f363d039SEric Auger #define VIRTIO_IOMMU_S_NOMEM 0x08 58*f363d039SEric Auger 59*f363d039SEric Auger struct virtio_iommu_req_head { 60*f363d039SEric Auger uint8_t type; 61*f363d039SEric Auger uint8_t reserved[3]; 62*f363d039SEric Auger }; 63*f363d039SEric Auger 64*f363d039SEric Auger struct virtio_iommu_req_tail { 65*f363d039SEric Auger uint8_t status; 66*f363d039SEric Auger uint8_t reserved[3]; 67*f363d039SEric Auger }; 68*f363d039SEric Auger 69*f363d039SEric Auger struct virtio_iommu_req_attach { 70*f363d039SEric Auger struct virtio_iommu_req_head head; 71*f363d039SEric Auger uint32_t domain; 72*f363d039SEric Auger uint32_t endpoint; 73*f363d039SEric Auger uint8_t reserved[8]; 74*f363d039SEric Auger struct virtio_iommu_req_tail tail; 75*f363d039SEric Auger }; 76*f363d039SEric Auger 77*f363d039SEric Auger struct virtio_iommu_req_detach { 78*f363d039SEric Auger struct virtio_iommu_req_head head; 79*f363d039SEric Auger uint32_t domain; 80*f363d039SEric Auger uint32_t endpoint; 81*f363d039SEric Auger uint8_t reserved[8]; 82*f363d039SEric Auger struct virtio_iommu_req_tail tail; 83*f363d039SEric Auger }; 84*f363d039SEric Auger 85*f363d039SEric Auger #define VIRTIO_IOMMU_MAP_F_READ (1 << 0) 86*f363d039SEric Auger #define VIRTIO_IOMMU_MAP_F_WRITE (1 << 1) 87*f363d039SEric Auger #define VIRTIO_IOMMU_MAP_F_MMIO (1 << 2) 88*f363d039SEric Auger 89*f363d039SEric Auger #define VIRTIO_IOMMU_MAP_F_MASK (VIRTIO_IOMMU_MAP_F_READ | \ 90*f363d039SEric Auger VIRTIO_IOMMU_MAP_F_WRITE | \ 91*f363d039SEric Auger VIRTIO_IOMMU_MAP_F_MMIO) 92*f363d039SEric Auger 93*f363d039SEric Auger struct virtio_iommu_req_map { 94*f363d039SEric Auger struct virtio_iommu_req_head head; 95*f363d039SEric Auger uint32_t domain; 96*f363d039SEric Auger uint64_t virt_start; 97*f363d039SEric Auger uint64_t virt_end; 98*f363d039SEric Auger uint64_t phys_start; 99*f363d039SEric Auger uint32_t flags; 100*f363d039SEric Auger struct virtio_iommu_req_tail tail; 101*f363d039SEric Auger }; 102*f363d039SEric Auger 103*f363d039SEric Auger struct virtio_iommu_req_unmap { 104*f363d039SEric Auger struct virtio_iommu_req_head head; 105*f363d039SEric Auger uint32_t domain; 106*f363d039SEric Auger uint64_t virt_start; 107*f363d039SEric Auger uint64_t virt_end; 108*f363d039SEric Auger uint8_t reserved[4]; 109*f363d039SEric Auger struct virtio_iommu_req_tail tail; 110*f363d039SEric Auger }; 111*f363d039SEric Auger 112*f363d039SEric Auger #define VIRTIO_IOMMU_PROBE_T_NONE 0 113*f363d039SEric Auger #define VIRTIO_IOMMU_PROBE_T_RESV_MEM 1 114*f363d039SEric Auger 115*f363d039SEric Auger #define VIRTIO_IOMMU_PROBE_T_MASK 0xfff 116*f363d039SEric Auger 117*f363d039SEric Auger struct virtio_iommu_probe_property { 118*f363d039SEric Auger uint16_t type; 119*f363d039SEric Auger uint16_t length; 120*f363d039SEric Auger }; 121*f363d039SEric Auger 122*f363d039SEric Auger #define VIRTIO_IOMMU_RESV_MEM_T_RESERVED 0 123*f363d039SEric Auger #define VIRTIO_IOMMU_RESV_MEM_T_MSI 1 124*f363d039SEric Auger 125*f363d039SEric Auger struct virtio_iommu_probe_resv_mem { 126*f363d039SEric Auger struct virtio_iommu_probe_property head; 127*f363d039SEric Auger uint8_t subtype; 128*f363d039SEric Auger uint8_t reserved[3]; 129*f363d039SEric Auger uint64_t start; 130*f363d039SEric Auger uint64_t end; 131*f363d039SEric Auger }; 132*f363d039SEric Auger 133*f363d039SEric Auger struct virtio_iommu_req_probe { 134*f363d039SEric Auger struct virtio_iommu_req_head head; 135*f363d039SEric Auger uint32_t endpoint; 136*f363d039SEric Auger uint8_t reserved[64]; 137*f363d039SEric Auger 138*f363d039SEric Auger uint8_t properties[]; 139*f363d039SEric Auger 140*f363d039SEric Auger /* 141*f363d039SEric Auger * Tail follows the variable-length properties array. No padding, 142*f363d039SEric Auger * property lengths are all aligned on 8 bytes. 143*f363d039SEric Auger */ 144*f363d039SEric Auger }; 145*f363d039SEric Auger 146*f363d039SEric Auger /* Fault types */ 147*f363d039SEric Auger #define VIRTIO_IOMMU_FAULT_R_UNKNOWN 0 148*f363d039SEric Auger #define VIRTIO_IOMMU_FAULT_R_DOMAIN 1 149*f363d039SEric Auger #define VIRTIO_IOMMU_FAULT_R_MAPPING 2 150*f363d039SEric Auger 151*f363d039SEric Auger #define VIRTIO_IOMMU_FAULT_F_READ (1 << 0) 152*f363d039SEric Auger #define VIRTIO_IOMMU_FAULT_F_WRITE (1 << 1) 153*f363d039SEric Auger #define VIRTIO_IOMMU_FAULT_F_EXEC (1 << 2) 154*f363d039SEric Auger #define VIRTIO_IOMMU_FAULT_F_ADDRESS (1 << 8) 155*f363d039SEric Auger 156*f363d039SEric Auger struct virtio_iommu_fault { 157*f363d039SEric Auger uint8_t reason; 158*f363d039SEric Auger uint8_t reserved[3]; 159*f363d039SEric Auger uint32_t flags; 160*f363d039SEric Auger uint32_t endpoint; 161*f363d039SEric Auger uint8_t reserved2[4]; 162*f363d039SEric Auger uint64_t address; 163*f363d039SEric Auger }; 164*f363d039SEric Auger 165*f363d039SEric Auger #endif 166