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