util: add memfd helpers
Add qemu_memfd_alloc/free() helpers. The function helps to allocate and seal shared memory. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Tested-by: Thibaut Collet <thibaut.collet@6wind.com>
This commit is contained in:
		
							parent
							
								
									f04cf9239a
								
							
						
					
					
						commit
						d3592199ba
					
				| @ -17,4 +17,8 @@ | ||||
| #define F_SEAL_WRITE    0x0008  /* prevent writes */ | ||||
| #endif | ||||
| 
 | ||||
| void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, | ||||
|                        int *fd); | ||||
| void qemu_memfd_free(void *ptr, size_t size, int fd); | ||||
| 
 | ||||
| #endif /* QEMU_MEMFD_H */ | ||||
|  | ||||
							
								
								
									
										72
									
								
								util/memfd.c
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								util/memfd.c
									
									
									
									
									
								
							| @ -27,6 +27,11 @@ | ||||
| 
 | ||||
| #include "qemu/osdep.h" | ||||
| 
 | ||||
| #include <glib.h> | ||||
| #include <glib/gprintf.h> | ||||
| 
 | ||||
| #include <sys/mman.h> | ||||
| 
 | ||||
| #include "qemu/memfd.h" | ||||
| 
 | ||||
| #ifdef CONFIG_MEMFD | ||||
| @ -35,7 +40,7 @@ | ||||
| #include <sys/syscall.h> | ||||
| #include <asm/unistd.h> | ||||
| 
 | ||||
| inline static int memfd_create(const char *name, unsigned int flags) | ||||
| static int memfd_create(const char *name, unsigned int flags) | ||||
| { | ||||
| #ifdef __NR_memfd_create | ||||
|     return syscall(__NR_memfd_create, name, flags); | ||||
| @ -52,3 +57,68 @@ inline static int memfd_create(const char *name, unsigned int flags) | ||||
| #ifndef MFD_ALLOW_SEALING | ||||
| #define MFD_ALLOW_SEALING 0x0002U | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * This is a best-effort helper for shared memory allocation, with | ||||
|  * optional sealing. The helper will do his best to allocate using | ||||
|  * memfd with sealing, but may fallback on other methods without | ||||
|  * sealing. | ||||
|  */ | ||||
| void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, | ||||
|                        int *fd) | ||||
| { | ||||
|     void *ptr; | ||||
|     int mfd = -1; | ||||
| 
 | ||||
|     *fd = -1; | ||||
| 
 | ||||
| #ifdef CONFIG_LINUX | ||||
|     if (seals) { | ||||
|         mfd = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC); | ||||
|     } | ||||
| 
 | ||||
|     if (mfd == -1) { | ||||
|         /* some systems have memfd without sealing */ | ||||
|         mfd = memfd_create(name, MFD_CLOEXEC); | ||||
|         seals = 0; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     if (mfd != -1) { | ||||
|         if (ftruncate(mfd, size) == -1) { | ||||
|             perror("ftruncate"); | ||||
|             close(mfd); | ||||
|             return NULL; | ||||
|         } | ||||
| 
 | ||||
|         if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) { | ||||
|             perror("fcntl"); | ||||
|             close(mfd); | ||||
|             return NULL; | ||||
|         } | ||||
|     } else { | ||||
|         perror("memfd"); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0); | ||||
|     if (ptr == MAP_FAILED) { | ||||
|         perror("mmap"); | ||||
|         close(mfd); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     *fd = mfd; | ||||
|     return ptr; | ||||
| } | ||||
| 
 | ||||
| void qemu_memfd_free(void *ptr, size_t size, int fd) | ||||
| { | ||||
|     if (ptr) { | ||||
|         munmap(ptr, size); | ||||
|     } | ||||
| 
 | ||||
|     if (fd != -1) { | ||||
|         close(fd); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Marc-André Lureau
						Marc-André Lureau