cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

oslib-win32.c (15079B)


      1/*
      2 * os-win32.c
      3 *
      4 * Copyright (c) 2003-2008 Fabrice Bellard
      5 * Copyright (c) 2010-2016 Red Hat, Inc.
      6 *
      7 * QEMU library functions for win32 which are shared between QEMU and
      8 * the QEMU tools.
      9 *
     10 * Permission is hereby granted, free of charge, to any person obtaining a copy
     11 * of this software and associated documentation files (the "Software"), to deal
     12 * in the Software without restriction, including without limitation the rights
     13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     14 * copies of the Software, and to permit persons to whom the Software is
     15 * furnished to do so, subject to the following conditions:
     16 *
     17 * The above copyright notice and this permission notice shall be included in
     18 * all copies or substantial portions of the Software.
     19 *
     20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     26 * THE SOFTWARE.
     27 *
     28 * The implementation of g_poll (functions poll_rest, g_poll) at the end of
     29 * this file are based on code from GNOME glib-2 and use a different license,
     30 * see the license comment there.
     31 */
     32
     33#include "qemu/osdep.h"
     34#include <windows.h>
     35#include "qemu-common.h"
     36#include "qapi/error.h"
     37#include "qemu/main-loop.h"
     38#include "trace.h"
     39#include "qemu/sockets.h"
     40#include "qemu/cutils.h"
     41#include "qemu/error-report.h"
     42#include <malloc.h>
     43
     44/* this must come after including "trace.h" */
     45#include <shlobj.h>
     46
     47void *qemu_oom_check(void *ptr)
     48{
     49    if (ptr == NULL) {
     50        fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
     51        abort();
     52    }
     53    return ptr;
     54}
     55
     56void *qemu_try_memalign(size_t alignment, size_t size)
     57{
     58    void *ptr;
     59
     60    g_assert(size != 0);
     61    if (alignment < sizeof(void *)) {
     62        alignment = sizeof(void *);
     63    } else {
     64        g_assert(is_power_of_2(alignment));
     65    }
     66    ptr = _aligned_malloc(size, alignment);
     67    trace_qemu_memalign(alignment, size, ptr);
     68    return ptr;
     69}
     70
     71void *qemu_memalign(size_t alignment, size_t size)
     72{
     73    return qemu_oom_check(qemu_try_memalign(alignment, size));
     74}
     75
     76static int get_allocation_granularity(void)
     77{
     78    SYSTEM_INFO system_info;
     79
     80    GetSystemInfo(&system_info);
     81    return system_info.dwAllocationGranularity;
     82}
     83
     84void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
     85                          bool noreserve)
     86{
     87    void *ptr;
     88
     89    if (noreserve) {
     90        /*
     91         * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE
     92         * area; we cannot easily mimic POSIX MAP_NORESERVE semantics.
     93         */
     94        error_report("Skipping reservation of swap space is not supported.");
     95        return NULL;
     96    }
     97
     98    ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
     99    trace_qemu_anon_ram_alloc(size, ptr);
    100
    101    if (ptr && align) {
    102        *align = MAX(get_allocation_granularity(), getpagesize());
    103    }
    104    return ptr;
    105}
    106
    107void qemu_vfree(void *ptr)
    108{
    109    trace_qemu_vfree(ptr);
    110    _aligned_free(ptr);
    111}
    112
    113void qemu_anon_ram_free(void *ptr, size_t size)
    114{
    115    trace_qemu_anon_ram_free(ptr, size);
    116    if (ptr) {
    117        VirtualFree(ptr, 0, MEM_RELEASE);
    118    }
    119}
    120
    121#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
    122/* FIXME: add proper locking */
    123struct tm *gmtime_r(const time_t *timep, struct tm *result)
    124{
    125    struct tm *p = gmtime(timep);
    126    memset(result, 0, sizeof(*result));
    127    if (p) {
    128        *result = *p;
    129        p = result;
    130    }
    131    return p;
    132}
    133
    134/* FIXME: add proper locking */
    135struct tm *localtime_r(const time_t *timep, struct tm *result)
    136{
    137    struct tm *p = localtime(timep);
    138    memset(result, 0, sizeof(*result));
    139    if (p) {
    140        *result = *p;
    141        p = result;
    142    }
    143    return p;
    144}
    145#endif /* _POSIX_THREAD_SAFE_FUNCTIONS */
    146
    147static int socket_error(void)
    148{
    149    switch (WSAGetLastError()) {
    150    case 0:
    151        return 0;
    152    case WSAEINTR:
    153        return EINTR;
    154    case WSAEINVAL:
    155        return EINVAL;
    156    case WSA_INVALID_HANDLE:
    157        return EBADF;
    158    case WSA_NOT_ENOUGH_MEMORY:
    159        return ENOMEM;
    160    case WSA_INVALID_PARAMETER:
    161        return EINVAL;
    162    case WSAENAMETOOLONG:
    163        return ENAMETOOLONG;
    164    case WSAENOTEMPTY:
    165        return ENOTEMPTY;
    166    case WSAEWOULDBLOCK:
    167         /* not using EWOULDBLOCK as we don't want code to have
    168          * to check both EWOULDBLOCK and EAGAIN */
    169        return EAGAIN;
    170    case WSAEINPROGRESS:
    171        return EINPROGRESS;
    172    case WSAEALREADY:
    173        return EALREADY;
    174    case WSAENOTSOCK:
    175        return ENOTSOCK;
    176    case WSAEDESTADDRREQ:
    177        return EDESTADDRREQ;
    178    case WSAEMSGSIZE:
    179        return EMSGSIZE;
    180    case WSAEPROTOTYPE:
    181        return EPROTOTYPE;
    182    case WSAENOPROTOOPT:
    183        return ENOPROTOOPT;
    184    case WSAEPROTONOSUPPORT:
    185        return EPROTONOSUPPORT;
    186    case WSAEOPNOTSUPP:
    187        return EOPNOTSUPP;
    188    case WSAEAFNOSUPPORT:
    189        return EAFNOSUPPORT;
    190    case WSAEADDRINUSE:
    191        return EADDRINUSE;
    192    case WSAEADDRNOTAVAIL:
    193        return EADDRNOTAVAIL;
    194    case WSAENETDOWN:
    195        return ENETDOWN;
    196    case WSAENETUNREACH:
    197        return ENETUNREACH;
    198    case WSAENETRESET:
    199        return ENETRESET;
    200    case WSAECONNABORTED:
    201        return ECONNABORTED;
    202    case WSAECONNRESET:
    203        return ECONNRESET;
    204    case WSAENOBUFS:
    205        return ENOBUFS;
    206    case WSAEISCONN:
    207        return EISCONN;
    208    case WSAENOTCONN:
    209        return ENOTCONN;
    210    case WSAETIMEDOUT:
    211        return ETIMEDOUT;
    212    case WSAECONNREFUSED:
    213        return ECONNREFUSED;
    214    case WSAELOOP:
    215        return ELOOP;
    216    case WSAEHOSTUNREACH:
    217        return EHOSTUNREACH;
    218    default:
    219        return EIO;
    220    }
    221}
    222
    223void qemu_set_block(int fd)
    224{
    225    unsigned long opt = 0;
    226    WSAEventSelect(fd, NULL, 0);
    227    ioctlsocket(fd, FIONBIO, &opt);
    228}
    229
    230int qemu_try_set_nonblock(int fd)
    231{
    232    unsigned long opt = 1;
    233    if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) {
    234        return -socket_error();
    235    }
    236    return 0;
    237}
    238
    239void qemu_set_nonblock(int fd)
    240{
    241    (void)qemu_try_set_nonblock(fd);
    242}
    243
    244int socket_set_fast_reuse(int fd)
    245{
    246    /* Enabling the reuse of an endpoint that was used by a socket still in
    247     * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
    248     * fast reuse is the default and SO_REUSEADDR does strange things. So we
    249     * don't have to do anything here. More info can be found at:
    250     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
    251    return 0;
    252}
    253
    254int inet_aton(const char *cp, struct in_addr *ia)
    255{
    256    uint32_t addr = inet_addr(cp);
    257    if (addr == 0xffffffff) {
    258        return 0;
    259    }
    260    ia->s_addr = addr;
    261    return 1;
    262}
    263
    264void qemu_set_cloexec(int fd)
    265{
    266}
    267
    268/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
    269#define _W32_FT_OFFSET (116444736000000000ULL)
    270
    271int qemu_gettimeofday(qemu_timeval *tp)
    272{
    273  union {
    274    unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
    275    FILETIME ft;
    276  }  _now;
    277
    278  if(tp) {
    279      GetSystemTimeAsFileTime (&_now.ft);
    280      tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
    281      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
    282  }
    283  /* Always return 0 as per Open Group Base Specifications Issue 6.
    284     Do not set errno on error.  */
    285  return 0;
    286}
    287
    288int qemu_get_thread_id(void)
    289{
    290    return GetCurrentThreadId();
    291}
    292
    293char *
    294qemu_get_local_state_pathname(const char *relative_pathname)
    295{
    296    HRESULT result;
    297    char base_path[MAX_PATH+1] = "";
    298
    299    result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
    300                             /* SHGFP_TYPE_CURRENT */ 0, base_path);
    301    if (result != S_OK) {
    302        /* misconfigured environment */
    303        g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
    304        abort();
    305    }
    306    return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
    307                           relative_pathname);
    308}
    309
    310void qemu_set_tty_echo(int fd, bool echo)
    311{
    312    HANDLE handle = (HANDLE)_get_osfhandle(fd);
    313    DWORD dwMode = 0;
    314
    315    if (handle == INVALID_HANDLE_VALUE) {
    316        return;
    317    }
    318
    319    GetConsoleMode(handle, &dwMode);
    320
    321    if (echo) {
    322        SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
    323    } else {
    324        SetConsoleMode(handle,
    325                       dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
    326    }
    327}
    328
    329static const char *exec_dir;
    330
    331void qemu_init_exec_dir(const char *argv0)
    332{
    333
    334    char *p;
    335    char buf[MAX_PATH];
    336    DWORD len;
    337
    338    if (exec_dir) {
    339        return;
    340    }
    341
    342    len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
    343    if (len == 0) {
    344        return;
    345    }
    346
    347    buf[len] = 0;
    348    p = buf + len - 1;
    349    while (p != buf && *p != '\\') {
    350        p--;
    351    }
    352    *p = 0;
    353    if (access(buf, R_OK) == 0) {
    354        exec_dir = g_strdup(buf);
    355    } else {
    356        exec_dir = CONFIG_BINDIR;
    357    }
    358}
    359
    360const char *qemu_get_exec_dir(void)
    361{
    362    return exec_dir;
    363}
    364
    365int getpagesize(void)
    366{
    367    SYSTEM_INFO system_info;
    368
    369    GetSystemInfo(&system_info);
    370    return system_info.dwPageSize;
    371}
    372
    373void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
    374                     Error **errp)
    375{
    376    int i;
    377    size_t pagesize = qemu_real_host_page_size;
    378
    379    memory = (memory + pagesize - 1) & -pagesize;
    380    for (i = 0; i < memory / pagesize; i++) {
    381        memset(area + pagesize * i, 0, 1);
    382    }
    383}
    384
    385char *qemu_get_pid_name(pid_t pid)
    386{
    387    /* XXX Implement me */
    388    abort();
    389}
    390
    391
    392pid_t qemu_fork(Error **errp)
    393{
    394    errno = ENOSYS;
    395    error_setg_errno(errp, errno,
    396                     "cannot fork child process");
    397    return -1;
    398}
    399
    400
    401#undef connect
    402int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
    403                      socklen_t addrlen)
    404{
    405    int ret;
    406    ret = connect(sockfd, addr, addrlen);
    407    if (ret < 0) {
    408        if (WSAGetLastError() == WSAEWOULDBLOCK) {
    409            errno = EINPROGRESS;
    410        } else {
    411            errno = socket_error();
    412        }
    413    }
    414    return ret;
    415}
    416
    417
    418#undef listen
    419int qemu_listen_wrap(int sockfd, int backlog)
    420{
    421    int ret;
    422    ret = listen(sockfd, backlog);
    423    if (ret < 0) {
    424        errno = socket_error();
    425    }
    426    return ret;
    427}
    428
    429
    430#undef bind
    431int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
    432                   socklen_t addrlen)
    433{
    434    int ret;
    435    ret = bind(sockfd, addr, addrlen);
    436    if (ret < 0) {
    437        errno = socket_error();
    438    }
    439    return ret;
    440}
    441
    442
    443#undef socket
    444int qemu_socket_wrap(int domain, int type, int protocol)
    445{
    446    int ret;
    447    ret = socket(domain, type, protocol);
    448    if (ret < 0) {
    449        errno = socket_error();
    450    }
    451    return ret;
    452}
    453
    454
    455#undef accept
    456int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
    457                     socklen_t *addrlen)
    458{
    459    int ret;
    460    ret = accept(sockfd, addr, addrlen);
    461    if (ret < 0) {
    462        errno = socket_error();
    463    }
    464    return ret;
    465}
    466
    467
    468#undef shutdown
    469int qemu_shutdown_wrap(int sockfd, int how)
    470{
    471    int ret;
    472    ret = shutdown(sockfd, how);
    473    if (ret < 0) {
    474        errno = socket_error();
    475    }
    476    return ret;
    477}
    478
    479
    480#undef ioctlsocket
    481int qemu_ioctlsocket_wrap(int fd, int req, void *val)
    482{
    483    int ret;
    484    ret = ioctlsocket(fd, req, val);
    485    if (ret < 0) {
    486        errno = socket_error();
    487    }
    488    return ret;
    489}
    490
    491
    492#undef closesocket
    493int qemu_closesocket_wrap(int fd)
    494{
    495    int ret;
    496    ret = closesocket(fd);
    497    if (ret < 0) {
    498        errno = socket_error();
    499    }
    500    return ret;
    501}
    502
    503
    504#undef getsockopt
    505int qemu_getsockopt_wrap(int sockfd, int level, int optname,
    506                         void *optval, socklen_t *optlen)
    507{
    508    int ret;
    509    ret = getsockopt(sockfd, level, optname, optval, optlen);
    510    if (ret < 0) {
    511        errno = socket_error();
    512    }
    513    return ret;
    514}
    515
    516
    517#undef setsockopt
    518int qemu_setsockopt_wrap(int sockfd, int level, int optname,
    519                         const void *optval, socklen_t optlen)
    520{
    521    int ret;
    522    ret = setsockopt(sockfd, level, optname, optval, optlen);
    523    if (ret < 0) {
    524        errno = socket_error();
    525    }
    526    return ret;
    527}
    528
    529
    530#undef getpeername
    531int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
    532                          socklen_t *addrlen)
    533{
    534    int ret;
    535    ret = getpeername(sockfd, addr, addrlen);
    536    if (ret < 0) {
    537        errno = socket_error();
    538    }
    539    return ret;
    540}
    541
    542
    543#undef getsockname
    544int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
    545                          socklen_t *addrlen)
    546{
    547    int ret;
    548    ret = getsockname(sockfd, addr, addrlen);
    549    if (ret < 0) {
    550        errno = socket_error();
    551    }
    552    return ret;
    553}
    554
    555
    556#undef send
    557ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
    558{
    559    int ret;
    560    ret = send(sockfd, buf, len, flags);
    561    if (ret < 0) {
    562        errno = socket_error();
    563    }
    564    return ret;
    565}
    566
    567
    568#undef sendto
    569ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
    570                         const struct sockaddr *addr, socklen_t addrlen)
    571{
    572    int ret;
    573    ret = sendto(sockfd, buf, len, flags, addr, addrlen);
    574    if (ret < 0) {
    575        errno = socket_error();
    576    }
    577    return ret;
    578}
    579
    580
    581#undef recv
    582ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
    583{
    584    int ret;
    585    ret = recv(sockfd, buf, len, flags);
    586    if (ret < 0) {
    587        errno = socket_error();
    588    }
    589    return ret;
    590}
    591
    592
    593#undef recvfrom
    594ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
    595                           struct sockaddr *addr, socklen_t *addrlen)
    596{
    597    int ret;
    598    ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
    599    if (ret < 0) {
    600        errno = socket_error();
    601    }
    602    return ret;
    603}
    604
    605bool qemu_write_pidfile(const char *filename, Error **errp)
    606{
    607    char buffer[128];
    608    int len;
    609    HANDLE file;
    610    OVERLAPPED overlap;
    611    BOOL ret;
    612    memset(&overlap, 0, sizeof(overlap));
    613
    614    file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
    615                      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    616
    617    if (file == INVALID_HANDLE_VALUE) {
    618        error_setg(errp, "Failed to create PID file");
    619        return false;
    620    }
    621    len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid());
    622    ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
    623                    NULL, &overlap);
    624    CloseHandle(file);
    625    if (ret == 0) {
    626        error_setg(errp, "Failed to write PID file");
    627        return false;
    628    }
    629    return true;
    630}
    631
    632char *qemu_get_host_name(Error **errp)
    633{
    634    wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1];
    635    DWORD size = G_N_ELEMENTS(tmp);
    636
    637    if (GetComputerNameW(tmp, &size) == 0) {
    638        error_setg_win32(errp, GetLastError(), "failed close handle");
    639        return NULL;
    640    }
    641
    642    return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL);
    643}
    644
    645size_t qemu_get_host_physmem(void)
    646{
    647    MEMORYSTATUSEX statex;
    648    statex.dwLength = sizeof(statex);
    649
    650    if (GlobalMemoryStatusEx(&statex)) {
    651        return statex.ullTotalPhys;
    652    }
    653    return 0;
    654}