]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Include/IndustryStandard/VirtioFs.h
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / Include / IndustryStandard / VirtioFs.h
1 /** @file
2 Type and macro definitions specific to the Virtio Filesystem device.
3
4 At the time of this writing, the latest released Virtio specification (v1.1)
5 does not include the virtio-fs device. The development version of the
6 specification defines it however; see the latest version at
7 <https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>.
8
9 This header file is minimal, and only defines the types and macros that are
10 necessary for the OvmfPkg implementation.
11
12 Copyright (C) 2020, Red Hat, Inc.
13
14 SPDX-License-Identifier: BSD-2-Clause-Patent
15 **/
16
17 #ifndef VIRTIO_FS_H_
18 #define VIRTIO_FS_H_
19
20 #include <IndustryStandard/Virtio.h>
21
22 //
23 // Lowest numbered queue for sending normal priority requests.
24 //
25 #define VIRTIO_FS_REQUEST_QUEUE 1
26
27 //
28 // Number of bytes in the "VIRTIO_FS_CONFIG.Tag" field.
29 //
30 #define VIRTIO_FS_TAG_BYTES 36
31
32 //
33 // Device configuration layout.
34 //
35 #pragma pack (1)
36 typedef struct {
37 //
38 // The Tag field can be considered the filesystem label, or a mount point
39 // hint. It is UTF-8 encoded, and padded to full size with NUL bytes. If the
40 // encoded bytes take up the entire Tag field, then there is no NUL
41 // terminator.
42 //
43 UINT8 Tag[VIRTIO_FS_TAG_BYTES];
44 //
45 // The total number of request virtqueues exposed by the device (i.e.,
46 // excluding the "hiprio" queue).
47 //
48 UINT32 NumReqQueues;
49 } VIRTIO_FS_CONFIG;
50 #pragma pack ()
51
52 //
53 // FUSE-related definitions follow.
54 //
55 // From virtio-v1.1-cs01-87fa6b5d8155, 5.11 File System Device: "[...] The
56 // driver acts as the FUSE client mounting the file system. The virtio file
57 // system device provides the mechanism for transporting FUSE requests [...]"
58 //
59 // Unfortunately, the documentation of the FUSE wire protocol is lacking. The
60 // Virtio spec (as of this writing) simply defers to
61 // "include/uapi/linux/fuse.h" in the Linux kernel source -- see the reference
62 // in virtio spec file "introduction.tex", at commit 87fa6b5d8155.
63 //
64 // Of course, "include/uapi/linux/fuse.h" is a moving target (the virtio spec
65 // does not specify a particular FUSE interface version). The OvmfPkg code
66 // targets version 7.31, because that's the lowest version that the QEMU
67 // virtio-fs daemon supports at this time -- see QEMU commit 72c42e2d6551
68 // ("virtiofsd: Trim out compatibility code", 2020-01-23).
69 //
70 // Correspondingly, Linux's "include/uapi/linux/fuse.h" is consulted as checked
71 // out at commit (c6ff213fe5b8^) = d78092e4937d ("fuse: fix page dereference
72 // after free", 2020-09-18); that is, right before commit c6ff213fe5b8 ("fuse:
73 // add submount support to <uapi/linux/fuse.h>", 2020-09-18) introduces FUSE
74 // interface version 7.32.
75 //
76 #define VIRTIO_FS_FUSE_MAJOR 7
77 #define VIRTIO_FS_FUSE_MINOR 31
78
79 //
80 // The inode number of the root directory.
81 //
82 #define VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID 1
83
84 //
85 // Distinguished errno values.
86 //
87 #define VIRTIO_FS_FUSE_ERRNO_ENOENT (-2)
88
89 //
90 // File mode bitmasks.
91 //
92 #define VIRTIO_FS_FUSE_MODE_TYPE_MASK 0170000u
93 #define VIRTIO_FS_FUSE_MODE_TYPE_REG 0100000u
94 #define VIRTIO_FS_FUSE_MODE_TYPE_DIR 0040000u
95 #define VIRTIO_FS_FUSE_MODE_PERM_RWXU 0000700u
96 #define VIRTIO_FS_FUSE_MODE_PERM_RUSR 0000400u
97 #define VIRTIO_FS_FUSE_MODE_PERM_WUSR 0000200u
98 #define VIRTIO_FS_FUSE_MODE_PERM_XUSR 0000100u
99 #define VIRTIO_FS_FUSE_MODE_PERM_RWXG 0000070u
100 #define VIRTIO_FS_FUSE_MODE_PERM_RGRP 0000040u
101 #define VIRTIO_FS_FUSE_MODE_PERM_WGRP 0000020u
102 #define VIRTIO_FS_FUSE_MODE_PERM_XGRP 0000010u
103 #define VIRTIO_FS_FUSE_MODE_PERM_RWXO 0000007u
104 #define VIRTIO_FS_FUSE_MODE_PERM_ROTH 0000004u
105 #define VIRTIO_FS_FUSE_MODE_PERM_WOTH 0000002u
106 #define VIRTIO_FS_FUSE_MODE_PERM_XOTH 0000001u
107
108 //
109 // Flags for VirtioFsFuseOpSetAttr, in the VIRTIO_FS_FUSE_SETATTR_REQUEST.Valid
110 // field.
111 //
112 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_MODE BIT0
113 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_SIZE BIT3
114 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_ATIME BIT4
115 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_MTIME BIT5
116
117 //
118 // Flags for VirtioFsFuseOpOpen.
119 //
120 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDONLY 0
121 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDWR 2
122
123 //
124 // Flags for VirtioFsFuseOpInit.
125 //
126 #define VIRTIO_FS_FUSE_INIT_REQ_F_DO_READDIRPLUS BIT13
127
128 /**
129 Macro for calculating the size of a directory stream entry.
130
131 The macro may evaluate Namelen multiple times.
132
133 The macro evaluates to a UINTN value that is safe to cast to UINT32.
134
135 @param[in] Namelen The size of the filename byte array that follows
136 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE in the directory
137 stream, as reported by
138 VIRTIO_FS_FUSE_STATFS_RESPONSE.Namelen or
139 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE.Namelen. The filename
140 byte array is not NUL-terminated.
141
142 @retval 0 Namelen was zero or greater than SIZE_4KB.
143
144 @return The number of bytes in the directory entry, including the
145 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE header.
146 **/
147 #define VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE(Namelen) \
148 ((Namelen) == 0 || (Namelen) > SIZE_4KB ? \
149 (UINTN)0 : \
150 ALIGN_VALUE ( \
151 sizeof (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE) + (UINTN)(Namelen), \
152 sizeof (UINT64) \
153 ) \
154 )
155
156 //
157 // Flags for VirtioFsFuseOpRename2.
158 //
159 #define VIRTIO_FS_FUSE_RENAME2_REQ_F_NOREPLACE BIT0
160
161 //
162 // FUSE operation codes.
163 //
164 typedef enum {
165 VirtioFsFuseOpLookup = 1,
166 VirtioFsFuseOpForget = 2,
167 VirtioFsFuseOpGetAttr = 3,
168 VirtioFsFuseOpSetAttr = 4,
169 VirtioFsFuseOpMkDir = 9,
170 VirtioFsFuseOpUnlink = 10,
171 VirtioFsFuseOpRmDir = 11,
172 VirtioFsFuseOpOpen = 14,
173 VirtioFsFuseOpRead = 15,
174 VirtioFsFuseOpWrite = 16,
175 VirtioFsFuseOpStatFs = 17,
176 VirtioFsFuseOpRelease = 18,
177 VirtioFsFuseOpFsync = 20,
178 VirtioFsFuseOpFlush = 25,
179 VirtioFsFuseOpInit = 26,
180 VirtioFsFuseOpOpenDir = 27,
181 VirtioFsFuseOpReleaseDir = 29,
182 VirtioFsFuseOpFsyncDir = 30,
183 VirtioFsFuseOpCreate = 35,
184 VirtioFsFuseOpReadDirPlus = 44,
185 VirtioFsFuseOpRename2 = 45,
186 } VIRTIO_FS_FUSE_OPCODE;
187
188 #pragma pack (1)
189 //
190 // Request-response headers common to all request types.
191 //
192 typedef struct {
193 UINT32 Len;
194 UINT32 Opcode;
195 UINT64 Unique;
196 UINT64 NodeId;
197 UINT32 Uid;
198 UINT32 Gid;
199 UINT32 Pid;
200 UINT32 Padding;
201 } VIRTIO_FS_FUSE_REQUEST;
202
203 typedef struct {
204 UINT32 Len;
205 INT32 Error;
206 UINT64 Unique;
207 } VIRTIO_FS_FUSE_RESPONSE;
208
209 //
210 // Structure with which the Virtio Filesystem device reports a NodeId to the
211 // FUSE client (i.e., to the Virtio Filesystem driver). This structure is a
212 // part of the response headers for operations that inform the FUSE client of
213 // an inode.
214 //
215 typedef struct {
216 UINT64 NodeId;
217 UINT64 Generation;
218 UINT64 EntryValid;
219 UINT64 AttrValid;
220 UINT32 EntryValidNsec;
221 UINT32 AttrValidNsec;
222 } VIRTIO_FS_FUSE_NODE_RESPONSE;
223
224 //
225 // Structure describing the host-side attributes of an inode. This structure is
226 // a part of the response headers for operations that inform the FUSE client of
227 // an inode.
228 //
229 typedef struct {
230 UINT64 Ino;
231 UINT64 Size;
232 UINT64 Blocks;
233 UINT64 Atime;
234 UINT64 Mtime;
235 UINT64 Ctime;
236 UINT32 AtimeNsec;
237 UINT32 MtimeNsec;
238 UINT32 CtimeNsec;
239 UINT32 Mode;
240 UINT32 Nlink;
241 UINT32 Uid;
242 UINT32 Gid;
243 UINT32 Rdev;
244 UINT32 Blksize;
245 UINT32 Padding;
246 } VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE;
247
248 //
249 // Header for VirtioFsFuseOpForget.
250 //
251 typedef struct {
252 UINT64 NumberOfLookups;
253 } VIRTIO_FS_FUSE_FORGET_REQUEST;
254
255 //
256 // Headers for VirtioFsFuseOpGetAttr (VIRTIO_FS_FUSE_GETATTR_RESPONSE is also
257 // for VirtioFsFuseOpSetAttr).
258 //
259 typedef struct {
260 UINT32 GetAttrFlags;
261 UINT32 Dummy;
262 UINT64 FileHandle;
263 } VIRTIO_FS_FUSE_GETATTR_REQUEST;
264
265 typedef struct {
266 UINT64 AttrValid;
267 UINT32 AttrValidNsec;
268 UINT32 Dummy;
269 } VIRTIO_FS_FUSE_GETATTR_RESPONSE;
270
271 //
272 // Header for VirtioFsFuseOpSetAttr.
273 //
274 typedef struct {
275 UINT32 Valid;
276 UINT32 Padding;
277 UINT64 FileHandle;
278 UINT64 Size;
279 UINT64 LockOwner;
280 UINT64 Atime;
281 UINT64 Mtime;
282 UINT64 Ctime;
283 UINT32 AtimeNsec;
284 UINT32 MtimeNsec;
285 UINT32 CtimeNsec;
286 UINT32 Mode;
287 UINT32 Unused4;
288 UINT32 Uid;
289 UINT32 Gid;
290 UINT32 Unused5;
291 } VIRTIO_FS_FUSE_SETATTR_REQUEST;
292
293 //
294 // Header for VirtioFsFuseOpMkDir.
295 //
296 typedef struct {
297 UINT32 Mode;
298 UINT32 Umask;
299 } VIRTIO_FS_FUSE_MKDIR_REQUEST;
300
301 //
302 // Headers for VirtioFsFuseOpOpen and VirtioFsFuseOpOpenDir.
303 //
304 typedef struct {
305 UINT32 Flags;
306 UINT32 Unused;
307 } VIRTIO_FS_FUSE_OPEN_REQUEST;
308
309 typedef struct {
310 UINT64 FileHandle;
311 UINT32 OpenFlags;
312 UINT32 Padding;
313 } VIRTIO_FS_FUSE_OPEN_RESPONSE;
314
315 //
316 // Header for VirtioFsFuseOpRead and VirtioFsFuseOpReadDirPlus.
317 //
318 typedef struct {
319 UINT64 FileHandle;
320 UINT64 Offset;
321 UINT32 Size;
322 UINT32 ReadFlags;
323 UINT64 LockOwner;
324 UINT32 Flags;
325 UINT32 Padding;
326 } VIRTIO_FS_FUSE_READ_REQUEST;
327
328 //
329 // Headers for VirtioFsFuseOpWrite.
330 //
331 typedef struct {
332 UINT64 FileHandle;
333 UINT64 Offset;
334 UINT32 Size;
335 UINT32 WriteFlags;
336 UINT64 LockOwner;
337 UINT32 Flags;
338 UINT32 Padding;
339 } VIRTIO_FS_FUSE_WRITE_REQUEST;
340
341 typedef struct {
342 UINT32 Size;
343 UINT32 Padding;
344 } VIRTIO_FS_FUSE_WRITE_RESPONSE;
345
346 //
347 // Header for VirtioFsFuseOpStatFs.
348 //
349 typedef struct {
350 UINT64 Blocks;
351 UINT64 Bfree;
352 UINT64 Bavail;
353 UINT64 Files;
354 UINT64 Ffree;
355 UINT32 Bsize;
356 UINT32 Namelen;
357 UINT32 Frsize;
358 UINT32 Padding;
359 UINT32 Spare[6];
360 } VIRTIO_FS_FUSE_STATFS_RESPONSE;
361
362 //
363 // Header for VirtioFsFuseOpRelease and VirtioFsFuseOpReleaseDir.
364 //
365 typedef struct {
366 UINT64 FileHandle;
367 UINT32 Flags;
368 UINT32 ReleaseFlags;
369 UINT64 LockOwner;
370 } VIRTIO_FS_FUSE_RELEASE_REQUEST;
371
372 //
373 // Header for VirtioFsFuseOpFsync and VirtioFsFuseOpFsyncDir.
374 //
375 typedef struct {
376 UINT64 FileHandle;
377 UINT32 FsyncFlags;
378 UINT32 Padding;
379 } VIRTIO_FS_FUSE_FSYNC_REQUEST;
380
381 //
382 // Header for VirtioFsFuseOpFlush.
383 //
384 typedef struct {
385 UINT64 FileHandle;
386 UINT32 Unused;
387 UINT32 Padding;
388 UINT64 LockOwner;
389 } VIRTIO_FS_FUSE_FLUSH_REQUEST;
390
391 //
392 // Headers for VirtioFsFuseOpInit.
393 //
394 typedef struct {
395 UINT32 Major;
396 UINT32 Minor;
397 UINT32 MaxReadahead;
398 UINT32 Flags;
399 } VIRTIO_FS_FUSE_INIT_REQUEST;
400
401 typedef struct {
402 UINT32 Major;
403 UINT32 Minor;
404 UINT32 MaxReadahead;
405 UINT32 Flags;
406 UINT16 MaxBackground;
407 UINT16 CongestionThreshold;
408 UINT32 MaxWrite;
409 UINT32 TimeGran;
410 UINT16 MaxPages;
411 UINT16 MapAlignment;
412 UINT32 Unused[8];
413 } VIRTIO_FS_FUSE_INIT_RESPONSE;
414
415 //
416 // Header for VirtioFsFuseOpCreate.
417 //
418 typedef struct {
419 UINT32 Flags;
420 UINT32 Mode;
421 UINT32 Umask;
422 UINT32 Padding;
423 } VIRTIO_FS_FUSE_CREATE_REQUEST;
424
425 //
426 // Header for VirtioFsFuseOpReadDirPlus.
427 //
428 // Diverging from the rest of the headers, this structure embeds other
429 // structures. The reason is that a scatter list cannot be used to receive
430 // NodeResp and AttrResp separately; the record below is followed by a variable
431 // size filename byte array, and then such pairs are repeated a number of
432 // times. Thus, later header start offsets depend on earlier filename array
433 // sizes.
434 //
435 typedef struct {
436 VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp;
437 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp;
438 UINT64 NodeId;
439 UINT64 CookieForNextEntry;
440 UINT32 Namelen;
441 UINT32 Type;
442 } VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE;
443
444 //
445 // Header for VirtioFsFuseOpRename2.
446 //
447 typedef struct {
448 UINT64 NewDir;
449 UINT32 Flags;
450 UINT32 Padding;
451 } VIRTIO_FS_FUSE_RENAME2_REQUEST;
452 #pragma pack ()
453
454 #endif // VIRTIO_FS_H_