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