util/userfaultfd: Add uffd_open()
Add a helper to create the uffd handle. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
		
							parent
							
								
									d9df92925e
								
							
						
					
					
						commit
						d5890ea072
					
				@ -13,10 +13,20 @@
 | 
				
			|||||||
#ifndef USERFAULTFD_H
 | 
					#ifndef USERFAULTFD_H
 | 
				
			||||||
#define USERFAULTFD_H
 | 
					#define USERFAULTFD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_LINUX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "qemu/osdep.h"
 | 
					#include "qemu/osdep.h"
 | 
				
			||||||
#include "exec/hwaddr.h"
 | 
					#include "exec/hwaddr.h"
 | 
				
			||||||
#include <linux/userfaultfd.h>
 | 
					#include <linux/userfaultfd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * uffd_open(): Open an userfaultfd handle for current context.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @flags: The flags we want to pass in when creating the handle.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns: the uffd handle if >=0, or <0 if error happens.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int uffd_open(int flags);
 | 
				
			||||||
int uffd_query_features(uint64_t *features);
 | 
					int uffd_query_features(uint64_t *features);
 | 
				
			||||||
int uffd_create_fd(uint64_t features, bool non_blocking);
 | 
					int uffd_create_fd(uint64_t features, bool non_blocking);
 | 
				
			||||||
void uffd_close_fd(int uffd_fd);
 | 
					void uffd_close_fd(int uffd_fd);
 | 
				
			||||||
@ -32,4 +42,6 @@ int uffd_wakeup(int uffd_fd, void *addr, uint64_t length);
 | 
				
			|||||||
int uffd_read_events(int uffd_fd, struct uffd_msg *msgs, int count);
 | 
					int uffd_read_events(int uffd_fd, struct uffd_msg *msgs, int count);
 | 
				
			||||||
bool uffd_poll_events(int uffd_fd, int tmo);
 | 
					bool uffd_poll_events(int uffd_fd, int tmo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_LINUX */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* USERFAULTFD_H */
 | 
					#endif /* USERFAULTFD_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,7 @@
 | 
				
			|||||||
#include "qemu-file.h"
 | 
					#include "qemu-file.h"
 | 
				
			||||||
#include "yank_functions.h"
 | 
					#include "yank_functions.h"
 | 
				
			||||||
#include "tls.h"
 | 
					#include "tls.h"
 | 
				
			||||||
 | 
					#include "qemu/userfaultfd.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Arbitrary limit on size of each discard command,
 | 
					/* Arbitrary limit on size of each discard command,
 | 
				
			||||||
 * keeps them around ~200 bytes
 | 
					 * keeps them around ~200 bytes
 | 
				
			||||||
@ -226,11 +227,9 @@ static bool receive_ufd_features(uint64_t *features)
 | 
				
			|||||||
    int ufd;
 | 
					    int ufd;
 | 
				
			||||||
    bool ret = true;
 | 
					    bool ret = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* if we are here __NR_userfaultfd should exists */
 | 
					    ufd = uffd_open(O_CLOEXEC);
 | 
				
			||||||
    ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
 | 
					 | 
				
			||||||
    if (ufd == -1) {
 | 
					    if (ufd == -1) {
 | 
				
			||||||
        error_report("%s: syscall __NR_userfaultfd failed: %s", __func__,
 | 
					        error_report("%s: uffd_open() failed: %s", __func__, strerror(errno));
 | 
				
			||||||
                     strerror(errno));
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -375,7 +374,7 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis)
 | 
				
			|||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
 | 
					    ufd = uffd_open(O_CLOEXEC);
 | 
				
			||||||
    if (ufd == -1) {
 | 
					    if (ufd == -1) {
 | 
				
			||||||
        error_report("%s: userfaultfd not available: %s", __func__,
 | 
					        error_report("%s: userfaultfd not available: %s", __func__,
 | 
				
			||||||
                     strerror(errno));
 | 
					                     strerror(errno));
 | 
				
			||||||
@ -1160,7 +1159,7 @@ static int postcopy_temp_pages_setup(MigrationIncomingState *mis)
 | 
				
			|||||||
int postcopy_ram_incoming_setup(MigrationIncomingState *mis)
 | 
					int postcopy_ram_incoming_setup(MigrationIncomingState *mis)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* Open the fd for the kernel to give us userfaults */
 | 
					    /* Open the fd for the kernel to give us userfaults */
 | 
				
			||||||
    mis->userfault_fd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
 | 
					    mis->userfault_fd = uffd_open(O_CLOEXEC | O_NONBLOCK);
 | 
				
			||||||
    if (mis->userfault_fd == -1) {
 | 
					    if (mis->userfault_fd == -1) {
 | 
				
			||||||
        error_report("%s: Failed to open userfault fd: %s", __func__,
 | 
					        error_report("%s: Failed to open userfault fd: %s", __func__,
 | 
				
			||||||
                     strerror(errno));
 | 
					                     strerror(errno));
 | 
				
			||||||
 | 
				
			|||||||
@ -61,14 +61,14 @@ static bool uffd_feature_thread_id;
 | 
				
			|||||||
#if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
 | 
					#if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
 | 
				
			||||||
#include <sys/eventfd.h>
 | 
					#include <sys/eventfd.h>
 | 
				
			||||||
#include <sys/ioctl.h>
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
#include <linux/userfaultfd.h>
 | 
					#include "qemu/userfaultfd.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool ufd_version_check(void)
 | 
					static bool ufd_version_check(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct uffdio_api api_struct;
 | 
					    struct uffdio_api api_struct;
 | 
				
			||||||
    uint64_t ioctl_mask;
 | 
					    uint64_t ioctl_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
 | 
					    int ufd = uffd_open(O_CLOEXEC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ufd == -1) {
 | 
					    if (ufd == -1) {
 | 
				
			||||||
        g_test_message("Skipping test: userfaultfd not available");
 | 
					        g_test_message("Skipping test: userfaultfd not available");
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,15 @@
 | 
				
			|||||||
#include <sys/syscall.h>
 | 
					#include <sys/syscall.h>
 | 
				
			||||||
#include <sys/ioctl.h>
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int uffd_open(int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(__NR_userfaultfd)
 | 
				
			||||||
 | 
					    return syscall(__NR_userfaultfd, flags);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    return -EINVAL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * uffd_query_features: query UFFD features
 | 
					 * uffd_query_features: query UFFD features
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -32,7 +41,7 @@ int uffd_query_features(uint64_t *features)
 | 
				
			|||||||
    struct uffdio_api api_struct = { 0 };
 | 
					    struct uffdio_api api_struct = { 0 };
 | 
				
			||||||
    int ret = -1;
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uffd_fd = syscall(__NR_userfaultfd, O_CLOEXEC);
 | 
					    uffd_fd = uffd_open(O_CLOEXEC);
 | 
				
			||||||
    if (uffd_fd < 0) {
 | 
					    if (uffd_fd < 0) {
 | 
				
			||||||
        trace_uffd_query_features_nosys(errno);
 | 
					        trace_uffd_query_features_nosys(errno);
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
@ -69,7 +78,7 @@ int uffd_create_fd(uint64_t features, bool non_blocking)
 | 
				
			|||||||
    uint64_t ioctl_mask = BIT(_UFFDIO_REGISTER) | BIT(_UFFDIO_UNREGISTER);
 | 
					    uint64_t ioctl_mask = BIT(_UFFDIO_REGISTER) | BIT(_UFFDIO_UNREGISTER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    flags = O_CLOEXEC | (non_blocking ? O_NONBLOCK : 0);
 | 
					    flags = O_CLOEXEC | (non_blocking ? O_NONBLOCK : 0);
 | 
				
			||||||
    uffd_fd = syscall(__NR_userfaultfd, flags);
 | 
					    uffd_fd = uffd_open(flags);
 | 
				
			||||||
    if (uffd_fd < 0) {
 | 
					    if (uffd_fd < 0) {
 | 
				
			||||||
        trace_uffd_create_fd_nosys(errno);
 | 
					        trace_uffd_create_fd_nosys(errno);
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user