hostmem-memfd: add checks before adding hostmem-memfd & properties

Run some memfd-related checks before registering hostmem-memfd &
various properties. This will help libvirt to figure out what the host
is supposed to be capable of.

qemu_memfd_check() is changed to a less optimized version, since it is
used with various flags, it no longer caches the result.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20180906161415.8543-1-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Marc-André Lureau 2018-09-06 20:14:15 +04:00 committed by Paolo Bonzini
parent 7184de64a1
commit 3829640049
4 changed files with 46 additions and 47 deletions

View file

@ -140,6 +140,7 @@ memfd_backend_class_init(ObjectClass *oc, void *data)
bc->alloc = memfd_backend_memory_alloc; bc->alloc = memfd_backend_memory_alloc;
if (qemu_memfd_check(MFD_HUGETLB)) {
object_class_property_add_bool(oc, "hugetlb", object_class_property_add_bool(oc, "hugetlb",
memfd_backend_get_hugetlb, memfd_backend_get_hugetlb,
memfd_backend_set_hugetlb, memfd_backend_set_hugetlb,
@ -148,11 +149,14 @@ memfd_backend_class_init(ObjectClass *oc, void *data)
memfd_backend_get_hugetlbsize, memfd_backend_get_hugetlbsize,
memfd_backend_set_hugetlbsize, memfd_backend_set_hugetlbsize,
NULL, NULL, &error_abort); NULL, NULL, &error_abort);
}
if (qemu_memfd_check(MFD_ALLOW_SEALING)) {
object_class_property_add_bool(oc, "seal", object_class_property_add_bool(oc, "seal",
memfd_backend_get_seal, memfd_backend_get_seal,
memfd_backend_set_seal, memfd_backend_set_seal,
&error_abort); &error_abort);
} }
}
static const TypeInfo memfd_backend_info = { static const TypeInfo memfd_backend_info = {
.name = TYPE_MEMORY_BACKEND_MEMFD, .name = TYPE_MEMORY_BACKEND_MEMFD,
@ -164,7 +168,9 @@ static const TypeInfo memfd_backend_info = {
static void register_types(void) static void register_types(void)
{ {
if (qemu_memfd_check(0)) {
type_register_static(&memfd_backend_info); type_register_static(&memfd_backend_info);
} }
}
type_init(register_types); type_init(register_types);

View file

@ -16,12 +16,28 @@
#define F_SEAL_WRITE 0x0008 /* prevent writes */ #define F_SEAL_WRITE 0x0008 /* prevent writes */
#endif #endif
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
#endif
#ifndef MFD_ALLOW_SEALING
#define MFD_ALLOW_SEALING 0x0002U
#endif
#ifndef MFD_HUGETLB
#define MFD_HUGETLB 0x0004U
#endif
#ifndef MFD_HUGE_SHIFT
#define MFD_HUGE_SHIFT 26
#endif
int qemu_memfd_create(const char *name, size_t size, bool hugetlb, int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
uint64_t hugetlbsize, unsigned int seals, Error **errp); uint64_t hugetlbsize, unsigned int seals, Error **errp);
bool qemu_memfd_alloc_check(void); bool qemu_memfd_alloc_check(void);
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
int *fd, Error **errp); int *fd, Error **errp);
void qemu_memfd_free(void *ptr, size_t size, int fd); void qemu_memfd_free(void *ptr, size_t size, int fd);
bool qemu_memfd_check(void); bool qemu_memfd_check(unsigned int flags);
#endif /* QEMU_MEMFD_H */ #endif /* QEMU_MEMFD_H */

View file

@ -169,7 +169,7 @@ static char *get_qemu_cmd(TestServer *s,
int mem, enum test_memfd memfd, const char *mem_path, int mem, enum test_memfd memfd, const char *mem_path,
const char *chr_opts, const char *extra) const char *chr_opts, const char *extra)
{ {
if (memfd == TEST_MEMFD_AUTO && qemu_memfd_check()) { if (memfd == TEST_MEMFD_AUTO && qemu_memfd_check(0)) {
memfd = TEST_MEMFD_YES; memfd = TEST_MEMFD_YES;
} }
@ -903,7 +903,7 @@ static void test_multiqueue(void)
s->queues = 2; s->queues = 2;
test_server_listen(s); test_server_listen(s);
if (qemu_memfd_check()) { if (qemu_memfd_check(0)) {
cmd = g_strdup_printf( cmd = g_strdup_printf(
QEMU_CMD_MEMFD QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d " QEMU_CMD_MEMFD QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
"-device virtio-net-pci,netdev=net0,mq=on,vectors=%d", "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
@ -963,7 +963,7 @@ int main(int argc, char **argv)
/* run the main loop thread so the chardev may operate */ /* run the main loop thread so the chardev may operate */
thread = g_thread_new(NULL, thread_function, loop); thread = g_thread_new(NULL, thread_function, loop);
if (qemu_memfd_check()) { if (qemu_memfd_check(0)) {
qtest_add_data_func("/vhost-user/read-guest-mem/memfd", qtest_add_data_func("/vhost-user/read-guest-mem/memfd",
GINT_TO_POINTER(TEST_MEMFD_YES), GINT_TO_POINTER(TEST_MEMFD_YES),
test_read_guest_mem); test_read_guest_mem);

View file

@ -45,22 +45,6 @@ static int memfd_create(const char *name, unsigned int flags)
} }
#endif #endif
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
#endif
#ifndef MFD_ALLOW_SEALING
#define MFD_ALLOW_SEALING 0x0002U
#endif
#ifndef MFD_HUGETLB
#define MFD_HUGETLB 0x0004U
#endif
#ifndef MFD_HUGE_SHIFT
#define MFD_HUGE_SHIFT 26
#endif
int qemu_memfd_create(const char *name, size_t size, bool hugetlb, int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
uint64_t hugetlbsize, unsigned int seals, Error **errp) uint64_t hugetlbsize, unsigned int seals, Error **errp)
{ {
@ -201,23 +185,16 @@ bool qemu_memfd_alloc_check(void)
* *
* Check if host supports memfd. * Check if host supports memfd.
*/ */
bool qemu_memfd_check(void) bool qemu_memfd_check(unsigned int flags)
{ {
#ifdef CONFIG_LINUX #ifdef CONFIG_LINUX
static int memfd_check = MEMFD_TODO; int mfd = memfd_create("test", flags);
if (memfd_check == MEMFD_TODO) {
int mfd = memfd_create("test", 0);
if (mfd >= 0) { if (mfd >= 0) {
memfd_check = MEMFD_OK;
close(mfd); close(mfd);
} else { return true;
memfd_check = MEMFD_KO;
} }
}
return memfd_check == MEMFD_OK;
#else
return false;
#endif #endif
return false;
} }