1 /*
2  * Copyright (c) 2023, Google Inc. All rights reserved.
3  * Author: codycswong@google.com (Cody Wong)
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files
7  * (the "Software"), to deal in the Software without restriction,
8  * including without limitation the rights to use, copy, modify, merge,
9  * publish, distribute, sublicense, and/or sell copies of the Software,
10  * and to permit persons to whom the Software is furnished to do so,
11  * subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #pragma once
25 
26 #include <dev/virtio.h>
27 #include <lib/bio.h>
28 #include <lk/compiler.h>
29 #include <kernel/spinlock.h>
30 #include <sys/types.h>
31 
32 #define VIRTIO_9P_RING_IDX 0
33 #define VIRTIO_9P_RING_SIZE 128
34 
35 // Assuming there can be only one outstanding request. Pick a 16-bit unsigned
36 // value arbtrarily as the default tag for no good reason.
37 #define P9_TAG_DEFAULT ((uint16_t)0x15)
38 #define P9_TAG_NOTAG ((uint16_t)~0)
39 
40 #define P9_FID_NOFID ((uint32_t)~0)
41 
42 #define P9_UNAME_NONUNAME ((uint32_t)~0)
43 
44 #define P9_MAXWELEM 16
45 
46 #ifdef V9P_HOST_DIR
47 #define V9P_MOUNT_ANAME V9P_HOST_DIR
48 #else
49 #define V9P_MOUNT_ANAME ""
50 #endif // V9P_MOUNT_ANAME
51 
52 // Linux file flags
53 #define O_RDONLY    00000000
54 #define O_WRONLY    00000001
55 #define O_RDWR      00000002
56 #ifndef O_CREAT
57 #define O_CREAT     00000100
58 #endif
59 #ifndef O_EXCL
60 #define O_EXCL      00000200
61 #endif
62 #ifndef O_NOCTTY
63 #define O_NOCTTY    00000400
64 #endif
65 #ifndef O_TRUNC
66 #define O_TRUNC     00001000
67 #endif
68 #ifndef O_APPEND
69 #define O_APPEND    00002000
70 #endif
71 #ifndef O_NONBLOCK
72 #define O_NONBLOCK  00004000
73 #endif
74 #ifndef O_DSYNC
75 #define O_DSYNC     00010000
76 #endif
77 #ifndef FASYNC
78 #define FASYNC      00020000
79 #endif
80 #ifndef O_DIRECT
81 #define O_DIRECT    00040000
82 #endif
83 #ifndef O_LARGEFILE
84 #define O_LARGEFILE 00100000
85 #endif
86 #ifndef O_DIRECTORY
87 #define O_DIRECTORY 00200000
88 #endif
89 #ifndef O_NOFOLLOW
90 #define O_NOFOLLOW  00400000
91 #endif
92 #ifndef O_NOATIME
93 #define O_NOATIME   01000000
94 #endif
95 #ifndef O_CLOEXEC
96 #define O_CLOEXEC   02000000
97 #endif
98 
99 // POSIX file modes
100 #define S_IRWXU  00700 // user (file owner) has read, write, and execute permission
101 #define S_IRUSR  00400 // user has read permission
102 #define S_IWUSR  00200 // user has write permission
103 #define S_IXUSR  00100 // user has execute permission
104 #define S_IRWXG  00070 // group has read, write, and execute permission
105 #define S_IRGRP  00040 // group has read permission
106 #define S_IWGRP  00020 // group has write permission
107 #define S_IXGRP  00010 // group has execute permission
108 #define S_IRWXO  00007 // others have read, write, and execute permission
109 #define S_IROTH  00004 // others have read permission
110 #define S_IWOTH  00002 // others have write permission
111 #define S_IXOTH  00001 // others have execute permission
112 /* According to POSIX, the effect when other bits are set in mode is
113  * unspecified.  On Linux, the following bits are also honored in mode: */
114 #define S_ISUID  0004000 // set-user-ID bit
115 #define S_ISGID  0002000 // set-group-ID bit (see inode(7)).
116 #define S_ISVTX  0001000 // sticky bit (see inode(7)).
117 
118 // Linux file modes
119 #define S_IFMT  00170000
120 #define S_IFSOCK 0140000
121 #define S_IFLNK  0120000
122 #define S_IFREG  0100000
123 #define S_IFBLK  0060000
124 #define S_IFDIR  0040000
125 #define S_IFCHR  0020000
126 #define S_IFIFO  0010000
127 #define S_ISUID  0004000
128 #define S_ISGID  0002000
129 #define S_ISVTX  0001000
130 
131 #define S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK)
132 #define S_ISREG(m)  (((m) & S_IFMT) == S_IFREG)
133 #define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR)
134 #define S_ISCHR(m)  (((m) & S_IFMT) == S_IFCHR)
135 #define S_ISBLK(m)  (((m) & S_IFMT) == S_IFBLK)
136 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
137 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
138 
139 #define P9_GETATTR_MODE         0x00000001ULL
140 #define P9_GETATTR_NLINK        0x00000002ULL
141 #define P9_GETATTR_UID          0x00000004ULL
142 #define P9_GETATTR_GID          0x00000008ULL
143 #define P9_GETATTR_RDEV         0x00000010ULL
144 #define P9_GETATTR_ATIME        0x00000020ULL
145 #define P9_GETATTR_MTIME        0x00000040ULL
146 #define P9_GETATTR_CTIME        0x00000080ULL
147 #define P9_GETATTR_INO          0x00000100ULL
148 #define P9_GETATTR_SIZE         0x00000200ULL
149 #define P9_GETATTR_BLOCKS       0x00000400ULL
150 
151 #define P9_GETATTR_BTIME        0x00000800ULL
152 #define P9_GETATTR_GEN          0x00001000ULL
153 #define P9_GETATTR_DATA_VERSION 0x00002000ULL
154 
155 #define P9_GETATTR_BASIC        0x000007ffULL /* Mask for fields up to BLOCKS */
156 #define P9_GETATTR_ALL          0x00003fffULL /* Mask for All fields above */
157 
158 enum virtio_9p_msg_type_t {
159     P9_TLERROR = 6,
160     P9_RLERROR,
161     P9_TSTATFS = 8,
162     P9_RSTATFS,
163     P9_TLOPEN = 12,
164     P9_RLOPEN,
165     P9_TLCREATE = 14,
166     P9_RLCREATE,
167     P9_TSYMLINK = 16,
168     P9_RSYMLINK,
169     P9_TMKNOD = 18,
170     P9_RMKNOD,
171     P9_TRENAME = 20,
172     P9_RRENAME,
173     P9_TREADLINK = 22,
174     P9_RREADLINK,
175     P9_TGETATTR = 24,
176     P9_RGETATTR,
177     P9_TSETATTR = 26,
178     P9_RSETATTR,
179     P9_TXATTRWALK = 30,
180     P9_RXATTRWALK,
181     P9_TXATTRCREATE = 32,
182     P9_RXATTRCREATE,
183     P9_TREADDIR = 40,
184     P9_RREADDIR,
185     P9_TFSYNC = 50,
186     P9_RFSYNC,
187     P9_TLOCK = 52,
188     P9_RLOCK,
189     P9_TGETLOCK = 54,
190     P9_RGETLOCK,
191     P9_TLINK = 70,
192     P9_RLINK,
193     P9_TMKDIR = 72,
194     P9_RMKDIR,
195     P9_TRENAMEAT = 74,
196     P9_RRENAMEAT,
197     P9_TUNLINKAT = 76,
198     P9_RUNLINKAT,
199     P9_TVERSION = 100,
200     P9_RVERSION,
201     P9_TAUTH = 102,
202     P9_RAUTH,
203     P9_TATTACH = 104,
204     P9_RATTACH,
205     P9_TERROR = 106,
206     P9_RERROR,
207     P9_TFLUSH = 108,
208     P9_RFLUSH,
209     P9_TWALK = 110,
210     P9_RWALK,
211     P9_TOPEN = 112,
212     P9_ROPEN,
213     P9_TCREATE = 114,
214     P9_RCREATE,
215     P9_TREAD = 116,
216     P9_RREAD,
217     P9_TWRITE = 118,
218     P9_RWRITE,
219     P9_TCLUNK = 120,
220     P9_RCLUNK,
221     P9_TREMOVE = 122,
222     P9_RREMOVE,
223     P9_TSTAT = 124,
224     P9_RSTAT,
225     P9_TWSTAT = 126,
226     P9_RWSTAT,
227 };
228 
229 typedef struct _virtio_9p_qid_t {
230     uint8_t type;
231     uint32_t version;
232     uint64_t path;
233 } virtio_9p_qid_t;
234 
235 enum p9_qid_t {
236     P9_QTDIR = 0x80,
237     P9_QTAPPEND = 0x40,
238     P9_QTEXCL = 0x20,
239     P9_QTMOUNT = 0x10,
240     P9_QTAUTH = 0x08,
241     P9_QTTMP = 0x04,
242     P9_QTSYMLINK = 0x02,
243     P9_QTLINK = 0x01,
244     P9_QTFILE = 0x00,
245 };
246 
247 typedef struct p9_dirent {
248     virtio_9p_qid_t qid;
249     uint64_t offset;
250     uint8_t type;
251     char *name;
252 } p9_dirent_t;
253 
254 typedef struct _virtio_9p_msg_t {
255     enum virtio_9p_msg_type_t msg_type;
256     uint16_t tag;
257 
258     // the 9p message structures supporting 9P2000.L
259     union {
260         // Tlerror
261         // Rlerror
262         struct {
263             uint32_t ecode;
264         } rlerror;
265 
266         // Tlopen
267         struct {
268             uint32_t fid;
269             uint32_t flags;
270         } tlopen;
271         // Rlopen
272         struct {
273             virtio_9p_qid_t qid;
274             uint32_t iounit;
275         } rlopen;
276 
277         // Tlcreate
278         struct {
279             uint32_t fid;
280             const char *name;
281             uint32_t flags;
282             uint32_t mode;
283             uint32_t gid;
284         } tlcreate;
285         // Rlcreate
286         struct {
287             virtio_9p_qid_t qid;
288             uint32_t iounit;
289         } rlcreate;
290 
291         // Tgetattr
292         struct {
293             uint32_t fid;
294             uint64_t request_mask;
295         } tgetattr;
296         // Rgetattr
297         struct {
298             uint64_t valid;
299             virtio_9p_qid_t qid;
300             uint32_t mode;
301             uint32_t uid;
302             uint32_t gid;
303             uint64_t nlink;
304             uint64_t rdev;
305             uint64_t size;
306             uint64_t blksize;
307             uint64_t blocks;
308             uint64_t atime_sec;
309             uint64_t atime_nsec;
310             uint64_t mtime_sec;
311             uint64_t mtime_nsec;
312             uint64_t ctime_sec;
313             uint64_t ctime_nsec;
314             uint64_t btime_sec;
315             uint64_t btime_nsec;
316             uint64_t gen;
317             uint64_t data_version;
318         } rgetattr;
319 
320         // Tversion
321         struct {
322             uint32_t msize;
323             const char *version;
324         } tversion;
325         // Rversion
326         struct {
327             uint32_t msize;
328             char *version;
329         } rversion;
330 
331         // Tauth
332         // Rauth
333 
334         // Rerror
335 
336         // Tflush
337         // Rflush
338 
339         // Tattach
340         struct {
341             uint32_t fid;
342             uint32_t afid;
343             const char *uname;
344             const char *aname;
345             uint32_t n_uname;
346         } tattach;
347         // Rattach
348         struct {
349             virtio_9p_qid_t qid;
350         } rattach;
351 
352         // Twalk
353         struct {
354             uint32_t fid;
355             uint32_t newfid;
356             uint16_t nwname;
357             const char *wname[P9_MAXWELEM];
358         } twalk;
359         // Rwalk
360         struct {
361             uint16_t nwqid;
362             virtio_9p_qid_t qid[P9_MAXWELEM];
363         } rwalk;
364 
365         // Topen
366         struct {
367             uint32_t fid;
368             uint8_t mode;
369         } topen;
370         // Ropen
371         struct {
372             virtio_9p_qid_t qid;
373             uint32_t iounit;
374         } ropen;
375 
376         // Tcreate
377         // Rcreate
378 
379         // Tread
380         struct {
381             uint32_t fid;
382             uint64_t offset;
383             uint32_t count;
384         } tread;
385         // Rread
386         struct {
387             uint32_t count;
388             uint8_t *data;
389         } rread;
390 
391         // Twrite
392         struct {
393             uint32_t fid;
394             uint64_t offset;
395             uint32_t count;
396             const uint8_t *data;
397         } twrite;
398         // Rwrite
399         struct {
400             uint32_t count;
401         } rwrite;
402 
403         // Tclunk
404         struct {
405             uint32_t fid;
406         } tclunk;
407         // Rclunk
408         struct {
409         } rclunk;
410 
411         // Tremove
412         struct {
413             uint32_t fid;
414         } tremove;
415         // Rremove
416         struct {
417         } rremove;
418 
419         // Tstat
420         // Rstat
421 
422         // Twstat
423         // Rwstat
424 
425         // Treaddir
426         struct {
427             uint32_t fid;
428             uint64_t offset;
429             uint32_t count;
430         } treaddir;
431         // Rreaddir
432         struct {
433             uint32_t count;
434             uint8_t *data;
435         } rreaddir;
436 
437         // Tmkdir
438         struct {
439             uint32_t dfid;
440             const char *name;
441             uint32_t mode;
442             uint32_t gid;
443         } tmkdir;
444         // Rmkdir
445         struct {
446             virtio_9p_qid_t qid;
447         } rmkdir;
448     } msg;
449 
450 } virtio_9p_msg_t;
451 
452 status_t virtio_9p_init(struct virtio_device *dev, uint32_t host_features) __NONNULL();
453 status_t virtio_9p_start(struct virtio_device *dev) __NONNULL();
454 struct virtio_device *virtio_9p_bdev_to_virtio_device(bdev_t *bdev);
455 struct virtio_device *virtio_get_9p_device(uint index);
456 
457 status_t virtio_9p_rpc(struct virtio_device *dev, const virtio_9p_msg_t *tmsg,
458                        virtio_9p_msg_t *rmsg);
459 void virtio_9p_msg_destroy(virtio_9p_msg_t *msg);
460 ssize_t p9_dirent_read(uint8_t *data, uint32_t size, p9_dirent_t *ent);
461 void p9_dirent_destroy(p9_dirent_t *ent);
462