]> git.proxmox.com Git - qemu.git/blobdiff - osdep.c
disabled LDT test (kqemu 0.7.2 no longer needs it)
[qemu.git] / osdep.c
diff --git a/osdep.c b/osdep.c
index aa061a90ad1d2ec78a06eb243a4c057875960782..f2a69d9a7172c0e56c8598c8a37be119ef662a37 100644 (file)
--- a/osdep.c
+++ b/osdep.c
@@ -143,6 +143,22 @@ void *shmat(int shmid, const void *shmaddr, int shmflg)
     return ptr;
 }
 
+/****************************************************************/
+/* sigaction bypassing the threads */
+
+static int kernel_sigaction(int signum, const struct qemu_sigaction *act, 
+                            struct qemu_sigaction *oldact, 
+                            int sigsetsize)
+{
+    QEMU_SYSCALL4(rt_sigaction, signum, act, oldact, sigsetsize);
+}
+
+int qemu_sigaction(int signum, const struct qemu_sigaction *act, 
+                   struct qemu_sigaction *oldact)
+{
+    return kernel_sigaction(signum, act, oldact, 8);
+}
+
 /****************************************************************/
 /* memory allocation */
 
@@ -235,6 +251,8 @@ void qemu_free(void *ptr)
 {
     MemoryBlock *mb;
 
+    if (!ptr)
+        return;
     mb = (MemoryBlock *)((uint8_t *)ptr - BLOCK_HEADER_SIZE);
     mb->next = first_free_block;
     first_free_block = mb;
@@ -255,6 +273,14 @@ void *get_mmap_addr(unsigned long size)
 
 #else
 
+#ifdef _WIN32
+#include <windows.h>
+#elif defined(_BSD)
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+
 int qemu_write(int fd, const void *buf, size_t n)
 {
     int ret;
@@ -280,6 +306,127 @@ void *qemu_malloc(size_t size)
     return malloc(size);
 }
 
+#if defined(_WIN32)
+
+void *qemu_vmalloc(size_t size)
+{
+    /* FIXME: this is not exactly optimal solution since VirtualAlloc
+       has 64Kb granularity, but at least it guarantees us that the
+       memory is page aligned. */
+    return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void qemu_vfree(void *ptr)
+{
+    VirtualFree(ptr, 0, MEM_RELEASE);
+}
+
+#elif defined(USE_KQEMU)
+
+#include <sys/vfs.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+void *qemu_vmalloc(size_t size)
+{
+    static int phys_ram_fd = -1;
+    static int phys_ram_size = 0;
+    const char *tmpdir;
+    char phys_ram_file[1024];
+    void *ptr;
+    struct statfs stfs;
+
+    if (phys_ram_fd < 0) {
+        tmpdir = getenv("QEMU_TMPDIR");
+        if (!tmpdir)
+            tmpdir = "/dev/shm";
+        if (statfs(tmpdir, &stfs) == 0) {
+            int64_t free_space;
+            int ram_mb;
+
+            extern int ram_size;
+            free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
+            if ((ram_size + 8192 * 1024) >= free_space) {
+                ram_mb = (ram_size / (1024 * 1024));
+                fprintf(stderr, 
+                        "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
+                        tmpdir, ram_mb);
+                if (strcmp(tmpdir, "/dev/shm") == 0) {
+                    fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
+                            "umount /dev/shm\n"
+                            "mount -t tmpfs -o size=%dm none /dev/shm\n",
+                            ram_mb + 16);
+                } else {
+                    fprintf(stderr, 
+                            "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
+                            "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
+                            "temporary RAM file will be opened.\n");
+                }
+                exit(1);
+            }
+        }
+        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", 
+                 tmpdir);
+        if (mkstemp(phys_ram_file) < 0) {
+            fprintf(stderr, 
+                    "warning: could not create temporary file in '%s'.\n"
+                    "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
+                    "Using '/tmp' as fallback.\n",
+                    tmpdir);
+            snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", 
+                     "/tmp");
+            if (mkstemp(phys_ram_file) < 0) {
+                fprintf(stderr, "Could not create temporary memory file '%s'\n", 
+                        phys_ram_file);
+                exit(1);
+            }
+        }
+        phys_ram_fd = open(phys_ram_file, O_CREAT | O_TRUNC | O_RDWR, 0600);
+        if (phys_ram_fd < 0) {
+            fprintf(stderr, "Could not open temporary memory file '%s'\n", 
+                    phys_ram_file);
+            exit(1);
+        }
+        unlink(phys_ram_file);
+    }
+    size = (size + 4095) & ~4095;
+    ftruncate(phys_ram_fd, phys_ram_size + size);
+    ptr = mmap(NULL, 
+               size, 
+               PROT_WRITE | PROT_READ, MAP_SHARED, 
+               phys_ram_fd, phys_ram_size);
+    if (ptr == MAP_FAILED) {
+        fprintf(stderr, "Could not map physical memory\n");
+        exit(1);
+    }
+    phys_ram_size += size;
+    return ptr;
+}
+
+void qemu_vfree(void *ptr)
+{
+    /* may be useful some day, but currently we do not need to free */
+}
+
+#else
+
+/* alloc shared memory pages */
+void *qemu_vmalloc(size_t size)
+{
+#ifdef _BSD
+    return valloc(size);
+#else
+    return memalign(4096, size);
+#endif
+}
+
+void qemu_vfree(void *ptr)
+{
+    free(ptr);
+}
+
+#endif
+
 #endif
 
 void *qemu_mallocz(size_t size)
@@ -292,6 +439,16 @@ void *qemu_mallocz(size_t size)
     return ptr;
 }
 
+char *qemu_strdup(const char *str)
+{
+    char *ptr;
+    ptr = qemu_malloc(strlen(str) + 1);
+    if (!ptr)
+        return NULL;
+    strcpy(ptr, str);
+    return ptr;
+}
+
 /****************************************************************/
 /* printf support */