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