X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/11ddeea91a3b22bd4d4647c732bed32cb6d5112c..fe1755cbb21c34a40234e2c380d049b9b031c4e2:/oslib-posix.c diff --git a/oslib-posix.c b/oslib-posix.c index a304fb0f53..dbeb6272b8 100644 --- a/oslib-posix.c +++ b/oslib-posix.c @@ -36,8 +36,14 @@ extern int daemon(int, int); #endif #if defined(__linux__) && defined(__x86_64__) - /* Use 2MB alignment so transparent hugepages can be used by KVM */ + /* Use 2 MiB alignment so transparent hugepages can be used by KVM. + Valgrind does not support alignments larger than 1 MiB, + therefore we need special code which handles running on Valgrind. */ # define QEMU_VMALLOC_ALIGN (512 * 4096) +# define CONFIG_VALGRIND +#elif defined(__linux__) && defined(__s390x__) + /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ +# define QEMU_VMALLOC_ALIGN (256 * 4096) #else # define QEMU_VMALLOC_ALIGN getpagesize() #endif @@ -47,7 +53,26 @@ extern int daemon(int, int); #include "trace.h" #include "qemu_socket.h" +#if defined(CONFIG_VALGRIND) +static int running_on_valgrind = -1; +#else +# define running_on_valgrind 0 +#endif +#ifdef CONFIG_LINUX +#include +#endif +#ifdef CONFIG_EVENTFD +#include +#endif +int qemu_get_thread_id(void) +{ +#if defined(__linux__) + return syscall(SYS_gettid); +#else + return getpid(); +#endif +} int qemu_daemon(int nochdir, int noclose) { @@ -83,19 +108,31 @@ void *qemu_memalign(size_t alignment, size_t size) return ptr; } +/* conflicts with qemu_vmalloc in bsd-user/mmap.c */ +#if !defined(CONFIG_BSD_USER) /* alloc shared memory pages */ void *qemu_vmalloc(size_t size) { void *ptr; size_t align = QEMU_VMALLOC_ALIGN; - if (size < align) { +#if defined(CONFIG_VALGRIND) + if (running_on_valgrind < 0) { + /* First call, test whether we are running on Valgrind. + This is a substitute for RUNNING_ON_VALGRIND from valgrind.h. */ + const char *ld = getenv("LD_PRELOAD"); + running_on_valgrind = (ld != NULL && strstr(ld, "vgpreload")); + } +#endif + + if (size < align || running_on_valgrind) { align = getpagesize(); } ptr = qemu_memalign(align, size); trace_qemu_vmalloc(size, ptr); return ptr; } +#endif void qemu_vfree(void *ptr) { @@ -103,6 +140,13 @@ void qemu_vfree(void *ptr) free(ptr); } +void socket_set_block(int fd) +{ + int f; + f = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, f & ~O_NONBLOCK); +} + void socket_set_nonblock(int fd) { int f; @@ -139,8 +183,35 @@ int qemu_pipe(int pipefd[2]) return ret; } -int qemu_utimensat(int dirfd, const char *path, const struct timespec *times, - int flags) +/* + * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. + */ +int qemu_eventfd(int fds[2]) +{ +#ifdef CONFIG_EVENTFD + int ret; + + ret = eventfd(0, 0); + if (ret >= 0) { + fds[0] = ret; + fds[1] = dup(ret); + if (fds[1] == -1) { + close(ret); + return -1; + } + qemu_set_cloexec(ret); + qemu_set_cloexec(fds[1]); + return 0; + } + if (errno != ENOSYS) { + return -1; + } +#endif + + return qemu_pipe(fds); +} + +int qemu_utimens(const char *path, const struct timespec *times) { struct timeval tv[2], tv_now; struct stat st; @@ -148,7 +219,7 @@ int qemu_utimensat(int dirfd, const char *path, const struct timespec *times, #ifdef CONFIG_UTIMENSAT int ret; - ret = utimensat(dirfd, path, times, flags); + ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW); if (ret != -1 || errno != ENOSYS) { return ret; }