1 #ifndef __XEN_HYPFS_H__
2 #define __XEN_HYPFS_H__
3 
4 #ifdef CONFIG_HYPFS
5 #include <xen/list.h>
6 #include <xen/string.h>
7 #include <public/hypfs.h>
8 
9 struct hypfs_entry_leaf;
10 
11 struct hypfs_entry {
12     unsigned short type;
13     unsigned short encoding;
14     unsigned int size;
15     unsigned int max_size;
16     const char *name;
17     struct list_head list;
18     int (*read)(const struct hypfs_entry *entry,
19                 XEN_GUEST_HANDLE_PARAM(void) uaddr);
20     int (*write)(struct hypfs_entry_leaf *leaf,
21                  XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
22 };
23 
24 struct hypfs_entry_leaf {
25     struct hypfs_entry e;
26     union {
27         const void *content;
28         void *write_ptr;
29     } u;
30 };
31 
32 struct hypfs_entry_dir {
33     struct hypfs_entry e;
34     struct list_head dirlist;
35 };
36 
37 #define HYPFS_DIR_INIT(var, nam)                  \
38     struct hypfs_entry_dir __read_mostly var = {  \
39         .e.type = XEN_HYPFS_TYPE_DIR,             \
40         .e.encoding = XEN_HYPFS_ENC_PLAIN,        \
41         .e.name = (nam),                          \
42         .e.size = 0,                              \
43         .e.max_size = 0,                          \
44         .e.list = LIST_HEAD_INIT(var.e.list),     \
45         .e.read = hypfs_read_dir,                 \
46         .dirlist = LIST_HEAD_INIT(var.dirlist),   \
47     }
48 
49 #define HYPFS_VARSIZE_INIT(var, typ, nam, msz)    \
50     struct hypfs_entry_leaf __read_mostly var = { \
51         .e.type = (typ),                          \
52         .e.encoding = XEN_HYPFS_ENC_PLAIN,        \
53         .e.name = (nam),                          \
54         .e.max_size = (msz),                      \
55         .e.read = hypfs_read_leaf,                \
56     }
57 
58 /* Content and size need to be set via hypfs_string_set_reference(). */
59 #define HYPFS_STRING_INIT(var, nam)               \
60     HYPFS_VARSIZE_INIT(var, XEN_HYPFS_TYPE_STRING, nam, 0)
61 
62 /*
63  * Set content and size of a XEN_HYPFS_TYPE_STRING node. The node will point
64  * to str, so any later modification of *str should be followed by a call
65  * to hypfs_string_set_reference() in order to update the size of the node
66  * data.
67  */
hypfs_string_set_reference(struct hypfs_entry_leaf * leaf,const char * str)68 static inline void hypfs_string_set_reference(struct hypfs_entry_leaf *leaf,
69                                               const char *str)
70 {
71     leaf->u.content = str;
72     leaf->e.size = strlen(str) + 1;
73 }
74 
75 #define HYPFS_FIXEDSIZE_INIT(var, typ, nam, contvar, wr) \
76     struct hypfs_entry_leaf __read_mostly var = {        \
77         .e.type = (typ),                                 \
78         .e.encoding = XEN_HYPFS_ENC_PLAIN,               \
79         .e.name = (nam),                                 \
80         .e.size = sizeof(contvar),                       \
81         .e.max_size = (wr) ? sizeof(contvar) : 0,        \
82         .e.read = hypfs_read_leaf,                       \
83         .e.write = (wr),                                 \
84         .u.content = &(contvar),                         \
85     }
86 
87 #define HYPFS_UINT_INIT(var, nam, contvar)                       \
88     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, NULL)
89 #define HYPFS_UINT_INIT_WRITABLE(var, nam, contvar)              \
90     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, \
91                          hypfs_write_leaf)
92 
93 #define HYPFS_INT_INIT(var, nam, contvar)                        \
94     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, NULL)
95 #define HYPFS_INT_INIT_WRITABLE(var, nam, contvar)               \
96     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, \
97                          hypfs_write_leaf)
98 
99 #define HYPFS_BOOL_INIT(var, nam, contvar)                       \
100     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, NULL)
101 #define HYPFS_BOOL_INIT_WRITABLE(var, nam, contvar)              \
102     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, \
103                          hypfs_write_bool)
104 
105 extern struct hypfs_entry_dir hypfs_root;
106 
107 int hypfs_add_dir(struct hypfs_entry_dir *parent,
108                   struct hypfs_entry_dir *dir, bool nofault);
109 int hypfs_add_leaf(struct hypfs_entry_dir *parent,
110                    struct hypfs_entry_leaf *leaf, bool nofault);
111 int hypfs_read_dir(const struct hypfs_entry *entry,
112                    XEN_GUEST_HANDLE_PARAM(void) uaddr);
113 int hypfs_read_leaf(const struct hypfs_entry *entry,
114                     XEN_GUEST_HANDLE_PARAM(void) uaddr);
115 int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
116                      XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
117 int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
118                      XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
119 int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
120                        XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
121 #endif
122 
123 #endif /* __XEN_HYPFS_H__ */
124