]> git.proxmox.com Git - mirror_qemu.git/blame - backends/hostmem-file.c
backends: Simplify host_memory_backend_memory_complete()
[mirror_qemu.git] / backends / hostmem-file.c
CommitLineData
52330e1a
PB
1/*
2 * QEMU Host Memory Backend for hugetlbfs
3 *
4 * Copyright (C) 2013-2014 Red Hat Inc
5 *
6 * Authors:
7 * Paolo Bonzini <pbonzini@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 */
0b8fa32f 12
9c058332 13#include "qemu/osdep.h"
da34e65c 14#include "qapi/error.h"
a4de8552 15#include "qemu/error-report.h"
0b8fa32f 16#include "qemu/module.h"
b85ea5fa 17#include "qemu/madvise.h"
52330e1a
PB
18#include "sysemu/hostmem.h"
19#include "qom/object_interfaces.h"
db1015e9 20#include "qom/object.h"
e92666b0
DH
21#include "qapi/visitor.h"
22#include "qapi/qapi-visit-common.h"
52330e1a 23
8063396b 24OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE)
52330e1a 25
52330e1a
PB
26
27struct HostMemoryBackendFile {
28 HostMemoryBackend parent_obj;
dbcb8981 29
52330e1a 30 char *mem_path;
98376843 31 uint64_t align;
4b870dc4 32 uint64_t offset;
a4de8552
JH
33 bool discard_data;
34 bool is_pmem;
86635aa4 35 bool readonly;
e92666b0 36 OnOffAuto rom;
52330e1a
PB
37};
38
39static void
40file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
41{
5c7ba877
IM
42#ifndef CONFIG_POSIX
43 error_setg(errp, "backend '%s' not supported on this host",
44 object_get_typename(OBJECT(backend)));
45#else
52330e1a 46 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
2d7a1eb6 47 g_autofree gchar *name = NULL;
9181fb70 48 uint32_t ram_flags;
52330e1a
PB
49
50 if (!backend->size) {
51 error_setg(errp, "can't create backend with size 0");
52 return;
53 }
54 if (!fb->mem_path) {
c2cb2b04 55 error_setg(errp, "mem-path property not set");
52330e1a
PB
56 return;
57 }
314aec4a 58
e92666b0
DH
59 switch (fb->rom) {
60 case ON_OFF_AUTO_AUTO:
61 /* Traditionally, opening the file readonly always resulted in ROM. */
62 fb->rom = fb->readonly ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
63 break;
64 case ON_OFF_AUTO_ON:
65 if (!fb->readonly) {
66 error_setg(errp, "property 'rom' = 'on' is not supported with"
67 " 'readonly' = 'off'");
68 return;
69 }
70 break;
71 case ON_OFF_AUTO_OFF:
72 if (fb->readonly && backend->share) {
73 error_setg(errp, "property 'rom' = 'off' is incompatible with"
74 " 'readonly' = 'on' and 'share' = 'on'");
75 return;
76 }
77 break;
78 default:
79 assert(false);
80 }
81
fa0cb34d 82 name = host_memory_backend_get_name(backend);
9181fb70 83 ram_flags = backend->share ? RAM_SHARED : 0;
e92666b0
DH
84 ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
85 ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
9181fb70
DH
86 ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
87 ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
b0182e53 88 ram_flags |= RAM_NAMED_FILE;
9181fb70
DH
89 memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
90 backend->size, fb->align, ram_flags,
5c52a219 91 fb->mem_path, fb->offset, errp);
52330e1a
PB
92#endif
93}
94
52330e1a
PB
95static char *get_mem_path(Object *o, Error **errp)
96{
97 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
98
99 return g_strdup(fb->mem_path);
100}
101
102static void set_mem_path(Object *o, const char *str, Error **errp)
103{
104 HostMemoryBackend *backend = MEMORY_BACKEND(o);
105 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
106
6f4c60e4 107 if (host_memory_backend_mr_inited(backend)) {
21d16836
ZY
108 error_setg(errp, "cannot change property 'mem-path' of %s",
109 object_get_typename(o));
52330e1a
PB
110 return;
111 }
ef1e1e07 112 g_free(fb->mem_path);
52330e1a
PB
113 fb->mem_path = g_strdup(str);
114}
115
11ae6ed8
EH
116static bool file_memory_backend_get_discard_data(Object *o, Error **errp)
117{
118 return MEMORY_BACKEND_FILE(o)->discard_data;
119}
120
121static void file_memory_backend_set_discard_data(Object *o, bool value,
122 Error **errp)
123{
124 MEMORY_BACKEND_FILE(o)->discard_data = value;
125}
126
98376843
HZ
127static void file_memory_backend_get_align(Object *o, Visitor *v,
128 const char *name, void *opaque,
129 Error **errp)
130{
131 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
132 uint64_t val = fb->align;
133
134 visit_type_size(v, name, &val, errp);
135}
136
137static void file_memory_backend_set_align(Object *o, Visitor *v,
138 const char *name, void *opaque,
139 Error **errp)
140{
141 HostMemoryBackend *backend = MEMORY_BACKEND(o);
142 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
98376843
HZ
143 uint64_t val;
144
145 if (host_memory_backend_mr_inited(backend)) {
dcfe4805
MA
146 error_setg(errp, "cannot change property '%s' of %s", name,
147 object_get_typename(o));
148 return;
98376843
HZ
149 }
150
668f62ec 151 if (!visit_type_size(v, name, &val, errp)) {
dcfe4805 152 return;
98376843
HZ
153 }
154 fb->align = val;
98376843
HZ
155}
156
4b870dc4
AG
157static void file_memory_backend_get_offset(Object *o, Visitor *v,
158 const char *name, void *opaque,
159 Error **errp)
160{
161 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
162 uint64_t val = fb->offset;
163
164 visit_type_size(v, name, &val, errp);
165}
166
167static void file_memory_backend_set_offset(Object *o, Visitor *v,
168 const char *name, void *opaque,
169 Error **errp)
170{
171 HostMemoryBackend *backend = MEMORY_BACKEND(o);
172 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
173 uint64_t val;
174
175 if (host_memory_backend_mr_inited(backend)) {
176 error_setg(errp, "cannot change property '%s' of %s", name,
177 object_get_typename(o));
178 return;
179 }
180
181 if (!visit_type_size(v, name, &val, errp)) {
182 return;
183 }
184 fb->offset = val;
185}
186
def835f0 187#ifdef CONFIG_LIBPMEM
a4de8552
JH
188static bool file_memory_backend_get_pmem(Object *o, Error **errp)
189{
190 return MEMORY_BACKEND_FILE(o)->is_pmem;
191}
192
193static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp)
194{
195 HostMemoryBackend *backend = MEMORY_BACKEND(o);
196 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
197
198 if (host_memory_backend_mr_inited(backend)) {
87dc3ce6
ZY
199 error_setg(errp, "cannot change property 'pmem' of %s.",
200 object_get_typename(o));
a4de8552
JH
201 return;
202 }
203
a4de8552
JH
204 fb->is_pmem = value;
205}
def835f0 206#endif /* CONFIG_LIBPMEM */
a4de8552 207
86635aa4
SH
208static bool file_memory_backend_get_readonly(Object *obj, Error **errp)
209{
210 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
211
212 return fb->readonly;
213}
214
215static void file_memory_backend_set_readonly(Object *obj, bool value,
216 Error **errp)
217{
218 HostMemoryBackend *backend = MEMORY_BACKEND(obj);
219 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
220
221 if (host_memory_backend_mr_inited(backend)) {
222 error_setg(errp, "cannot change property 'readonly' of %s.",
223 object_get_typename(obj));
224 return;
225 }
226
227 fb->readonly = value;
228}
229
e92666b0
DH
230static void file_memory_backend_get_rom(Object *obj, Visitor *v,
231 const char *name, void *opaque,
232 Error **errp)
233{
234 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
235 OnOffAuto rom = fb->rom;
236
237 visit_type_OnOffAuto(v, name, &rom, errp);
238}
239
240static void file_memory_backend_set_rom(Object *obj, Visitor *v,
241 const char *name, void *opaque,
242 Error **errp)
243{
244 HostMemoryBackend *backend = MEMORY_BACKEND(obj);
245 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
246
247 if (host_memory_backend_mr_inited(backend)) {
248 error_setg(errp, "cannot change property '%s' of %s.", name,
249 object_get_typename(obj));
250 return;
251 }
252
253 visit_type_OnOffAuto(v, name, &fb->rom, errp);
254}
255
11ae6ed8
EH
256static void file_backend_unparent(Object *obj)
257{
258 HostMemoryBackend *backend = MEMORY_BACKEND(obj);
259 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
260
261 if (host_memory_backend_mr_inited(backend) && fb->discard_data) {
262 void *ptr = memory_region_get_ram_ptr(&backend->mr);
263 uint64_t sz = memory_region_size(&backend->mr);
264
265 qemu_madvise(ptr, sz, QEMU_MADV_REMOVE);
266 }
267}
268
52330e1a 269static void
026ac483 270file_backend_class_init(ObjectClass *oc, void *data)
52330e1a 271{
026ac483
EH
272 HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
273
274 bc->alloc = file_backend_memory_alloc;
11ae6ed8 275 oc->unparent = file_backend_unparent;
026ac483 276
11ae6ed8 277 object_class_property_add_bool(oc, "discard-data",
d2623129 278 file_memory_backend_get_discard_data, file_memory_backend_set_discard_data);
026ac483 279 object_class_property_add_str(oc, "mem-path",
d2623129 280 get_mem_path, set_mem_path);
98376843
HZ
281 object_class_property_add(oc, "align", "int",
282 file_memory_backend_get_align,
283 file_memory_backend_set_align,
d2623129 284 NULL, NULL);
4b870dc4
AG
285 object_class_property_add(oc, "offset", "int",
286 file_memory_backend_get_offset,
287 file_memory_backend_set_offset,
288 NULL, NULL);
289 object_class_property_set_description(oc, "offset",
290 "Offset into the target file (ex: 1G)");
def835f0 291#ifdef CONFIG_LIBPMEM
a4de8552 292 object_class_property_add_bool(oc, "pmem",
d2623129 293 file_memory_backend_get_pmem, file_memory_backend_set_pmem);
def835f0 294#endif
86635aa4
SH
295 object_class_property_add_bool(oc, "readonly",
296 file_memory_backend_get_readonly,
297 file_memory_backend_set_readonly);
e92666b0
DH
298 object_class_property_add(oc, "rom", "OnOffAuto",
299 file_memory_backend_get_rom, file_memory_backend_set_rom, NULL, NULL);
300 object_class_property_set_description(oc, "rom",
301 "Whether to create Read Only Memory (ROM)");
52330e1a
PB
302}
303
bc78a013
MAL
304static void file_backend_instance_finalize(Object *o)
305{
306 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
307
308 g_free(fb->mem_path);
309}
310
52330e1a
PB
311static const TypeInfo file_backend_info = {
312 .name = TYPE_MEMORY_BACKEND_FILE,
313 .parent = TYPE_MEMORY_BACKEND,
314 .class_init = file_backend_class_init,
bc78a013 315 .instance_finalize = file_backend_instance_finalize,
52330e1a
PB
316 .instance_size = sizeof(HostMemoryBackendFile),
317};
318
319static void register_types(void)
320{
321 type_register_static(&file_backend_info);
322}
323
324type_init(register_types);