qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at master 109 lines 2.3 kB view raw
1/* 2 * signalfd/eventfd compatibility 3 * 4 * Copyright IBM, Corp. 2008 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 * 12 * Contributions after 2012-01-13 are licensed under the terms of the 13 * GNU GPL, version 2 or (at your option) any later version. 14 */ 15 16#include "qemu/osdep.h" 17#include "qemu/thread.h" 18 19#include <sys/syscall.h> 20 21struct sigfd_compat_info 22{ 23 sigset_t mask; 24 int fd; 25}; 26 27static void *sigwait_compat(void *opaque) 28{ 29 struct sigfd_compat_info *info = opaque; 30 31 while (1) { 32 int sig; 33 int err; 34 35 err = sigwait(&info->mask, &sig); 36 if (err != 0) { 37 if (errno == EINTR) { 38 continue; 39 } else { 40 return NULL; 41 } 42 } else { 43 struct qemu_signalfd_siginfo buffer; 44 size_t offset = 0; 45 46 memset(&buffer, 0, sizeof(buffer)); 47 buffer.ssi_signo = sig; 48 49 while (offset < sizeof(buffer)) { 50 ssize_t len; 51 52 len = write(info->fd, (char *)&buffer + offset, 53 sizeof(buffer) - offset); 54 if (len == -1 && errno == EINTR) 55 continue; 56 57 if (len <= 0) { 58 return NULL; 59 } 60 61 offset += len; 62 } 63 } 64 } 65} 66 67static int qemu_signalfd_compat(const sigset_t *mask) 68{ 69 struct sigfd_compat_info *info; 70 QemuThread thread; 71 int fds[2]; 72 73 info = malloc(sizeof(*info)); 74 if (info == NULL) { 75 errno = ENOMEM; 76 return -1; 77 } 78 79 if (pipe(fds) == -1) { 80 free(info); 81 return -1; 82 } 83 84 qemu_set_cloexec(fds[0]); 85 qemu_set_cloexec(fds[1]); 86 87 memcpy(&info->mask, mask, sizeof(*mask)); 88 info->fd = fds[1]; 89 90 qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, info, 91 QEMU_THREAD_DETACHED); 92 93 return fds[0]; 94} 95 96int qemu_signalfd(const sigset_t *mask) 97{ 98#if defined(CONFIG_SIGNALFD) 99 int ret; 100 101 ret = syscall(SYS_signalfd, -1, mask, _NSIG / 8); 102 if (ret != -1) { 103 qemu_set_cloexec(ret); 104 return ret; 105 } 106#endif 107 108 return qemu_signalfd_compat(mask); 109}