Example #1
0
/* FIXME Deprecate and remove keypairs or make it available in QMP.
 * password_secret should eventually be configurable in opts->location. Support
 * for it in .bdrv_open will make it work here as well. */
static int qemu_rbd_do_create(BlockdevCreateOptions *options,
                              const char *keypairs, const char *password_secret,
                              Error **errp)
{
    BlockdevCreateOptionsRbd *opts = &options->u.rbd;
    rados_t cluster;
    rados_ioctx_t io_ctx;
    int obj_order = 0;
    int ret;

    assert(options->driver == BLOCKDEV_DRIVER_RBD);
    if (opts->location->has_snapshot) {
        error_setg(errp, "Can't use snapshot name for image creation");
        return -EINVAL;
    }

    if (opts->has_cluster_size) {
        int64_t objsize = opts->cluster_size;
        if ((objsize - 1) & objsize) {    /* not a power of 2? */
            error_setg(errp, "obj size needs to be power of 2");
            return -EINVAL;
        }
        if (objsize < 4096) {
            error_setg(errp, "obj size too small");
            return -EINVAL;
        }
        obj_order = ctz32(objsize);
    }

    ret = qemu_rbd_connect(&cluster, &io_ctx, opts->location, false, keypairs,
                           password_secret, errp);
    if (ret < 0) {
        return ret;
    }

    ret = rbd_create(io_ctx, opts->location->image, opts->size, &obj_order);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error rbd create");
        goto out;
    }

    ret = 0;
out:
    rados_ioctx_destroy(io_ctx);
    rados_shutdown(cluster);
    return ret;
}
Example #2
0
static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
                                        const struct iovec *iov,
                                        size_t niov,
                                        int **fds,
                                        size_t *nfds,
                                        Error **errp)
{
    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
    ssize_t ret;
    struct msghdr msg = { NULL, };
    char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
    int sflags = 0;

    memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));

#ifdef MSG_CMSG_CLOEXEC
    sflags |= MSG_CMSG_CLOEXEC;
#endif

    msg.msg_iov = (struct iovec *)iov;
    msg.msg_iovlen = niov;
    if (fds && nfds) {
        msg.msg_control = control;
        msg.msg_controllen = sizeof(control);
    }

 retry:
    ret = recvmsg(sioc->fd, &msg, sflags);
    if (ret < 0) {
        if (errno == EAGAIN) {
            return QIO_CHANNEL_ERR_BLOCK;
        }
        if (errno == EINTR) {
            goto retry;
        }

        error_setg_errno(errp, errno,
                         "Unable to read from socket");
        return -1;
    }

    if (fds && nfds) {
        qio_channel_socket_copy_fds(&msg, fds, nfds);
    }

    return ret;
}
Example #3
0
static off_t qio_channel_file_seek(QIOChannel *ioc,
                                   off_t offset,
                                   int whence,
                                   Error **errp)
{
    QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
    off_t ret;

    ret = lseek(fioc->fd, offset, whence);
    if (ret == (off_t)-1) {
        error_setg_errno(errp, errno,
                         "Unable to seek to offset %lld whence %d in file",
                         (long long int)offset, whence);
        return -1;
    }
    return ret;
}
Example #4
0
static ssize_t block_crypto_write_func(QCryptoBlock *block,
                                       size_t offset,
                                       const uint8_t *buf,
                                       size_t buflen,
                                       Error **errp,
                                       void *opaque)
{
    struct BlockCryptoCreateData *data = opaque;
    ssize_t ret;

    ret = blk_pwrite(data->blk, offset, buf, buflen, 0);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not write encryption header");
        return ret;
    }
    return ret;
}
Example #5
0
static ssize_t block_crypto_read_func(QCryptoBlock *block,
                                      size_t offset,
                                      uint8_t *buf,
                                      size_t buflen,
                                      Error **errp,
                                      void *opaque)
{
    BlockDriverState *bs = opaque;
    ssize_t ret;

    ret = bdrv_pread(bs->file, offset, buf, buflen);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not read encryption header");
        return ret;
    }
    return ret;
}
Example #6
0
File: memfd.c Project: CTU-IIG/qemu
int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
                      uint64_t hugetlbsize, unsigned int seals, Error **errp)
{
    int htsize = hugetlbsize ? ctz64(hugetlbsize) : 0;

    if (htsize && 1ULL << htsize != hugetlbsize) {
        error_setg(errp, "Hugepage size must be a power of 2");
        return -1;
    }

    htsize = htsize << MFD_HUGE_SHIFT;

#ifdef CONFIG_LINUX
    int mfd = -1;
    unsigned int flags = MFD_CLOEXEC;

    if (seals) {
        flags |= MFD_ALLOW_SEALING;
    }
    if (hugetlb) {
        flags |= MFD_HUGETLB;
        flags |= htsize;
    }
    mfd = memfd_create(name, flags);
    if (mfd < 0) {
        goto err;
    }

    if (ftruncate(mfd, size) == -1) {
        goto err;
    }

    if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) {
        goto err;
    }

    return mfd;

err:
    if (mfd >= 0) {
        close(mfd);
    }
#endif
    error_setg_errno(errp, errno, "failed to create memfd");
    return -1;
}
Example #7
0
void socket_listen_cleanup(int fd, Error **errp)
{
    SocketAddress *addr;

    addr = socket_local_address(fd, errp);

    if (addr->type == SOCKET_ADDRESS_KIND_UNIX
        && addr->u.q_unix.data->path) {
        if (unlink(addr->u.q_unix.data->path) < 0 && errno != ENOENT) {
            error_setg_errno(errp, errno,
                             "Failed to unlink socket %s",
                             addr->u.q_unix.data->path);
        }
    }

    qapi_free_SocketAddress(addr);
}
Example #8
0
static void ga_wait_child(pid_t pid, int *status, Error **err)
{
    pid_t rpid;

    *status = 0;

    do {
        rpid = waitpid(pid, status, 0);
    } while (rpid == -1 && errno == EINTR);

    if (rpid == -1) {
        error_setg_errno(err, errno, "failed to wait for child (pid: %d)", pid);
        return;
    }

    g_assert(rpid == pid);
}
Example #9
0
static int check_constraints_on_bitmap(BlockDriverState *bs,
                                       const char *name,
                                       uint32_t granularity,
                                       Error **errp)
{
    BDRVQcow2State *s = bs->opaque;
    int granularity_bits = ctz32(granularity);
    int64_t len = bdrv_getlength(bs);

    assert(granularity > 0);
    assert((granularity & (granularity - 1)) == 0);

    if (len < 0) {
        error_setg_errno(errp, -len, "Failed to get size of '%s'",
                         bdrv_get_device_or_node_name(bs));
        return len;
    }

    if (granularity_bits > BME_MAX_GRANULARITY_BITS) {
        error_setg(errp, "Granularity exceeds maximum (%llu bytes)",
                   1ULL << BME_MAX_GRANULARITY_BITS);
        return -EINVAL;
    }
    if (granularity_bits < BME_MIN_GRANULARITY_BITS) {
        error_setg(errp, "Granularity is under minimum (%llu bytes)",
                   1ULL << BME_MIN_GRANULARITY_BITS);
        return -EINVAL;
    }

    if ((len > (uint64_t)BME_MAX_PHYS_SIZE << granularity_bits) ||
        (len > (uint64_t)BME_MAX_TABLE_SIZE * s->cluster_size <<
               granularity_bits))
    {
        error_setg(errp, "Too much space will be occupied by the bitmap. "
                   "Use larger granularity");
        return -EINVAL;
    }

    if (strlen(name) > BME_MAX_NAME_SIZE) {
        error_setg(errp, "Name length exceeds maximum (%u characters)",
                   BME_MAX_NAME_SIZE);
        return -EINVAL;
    }

    return 0;
}
Example #10
0
File: netmap.c Project: 8tab/qemu
/*
 * Open a netmap device. We assume there is only one queue
 * (which is the case for the VALE bridge).
 */
static struct nm_desc *netmap_open(const NetdevNetmapOptions *nm_opts,
                                   Error **errp)
{
    struct nm_desc *nmd;
    struct nmreq req;

    memset(&req, 0, sizeof(req));

    nmd = nm_open(nm_opts->ifname, &req, NETMAP_NO_TX_POLL,
                  NULL);
    if (nmd == NULL) {
        error_setg_errno(errp, errno, "Failed to nm_open() %s",
                         nm_opts->ifname);
        return NULL;
    }

    return nmd;
}
Example #11
0
ssize_t qio_channel_writev_full(QIOChannel *ioc,
                                const struct iovec *iov,
                                size_t niov,
                                int *fds,
                                size_t nfds,
                                Error **errp)
{
    QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);

    if ((fds || nfds) &&
        !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
        error_setg_errno(errp, EINVAL,
                         "Channel does not support file descriptor passing");
        return -1;
    }

    return klass->io_writev(ioc, iov, niov, fds, nfds, errp);
}
Example #12
0
File: colo.c Project: mmuman/qemu
static void colo_send_message(QEMUFile *f, COLOMessage msg,
                              Error **errp)
{
    int ret;

    if (msg >= COLO_MESSAGE__MAX) {
        error_setg(errp, "%s: Invalid message", __func__);
        return;
    }
    qemu_put_be32(f, msg);
    qemu_fflush(f);

    ret = qemu_file_get_error(f);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Can't send COLO message");
    }
    trace_colo_send_message(COLOMessage_lookup[msg]);
}
Example #13
0
File: colo.c Project: mmuman/qemu
static COLOMessage colo_receive_message(QEMUFile *f, Error **errp)
{
    COLOMessage msg;
    int ret;

    msg = qemu_get_be32(f);
    ret = qemu_file_get_error(f);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Can't receive COLO message");
        return msg;
    }
    if (msg >= COLO_MESSAGE__MAX) {
        error_setg(errp, "%s: Invalid message", __func__);
        return msg;
    }
    trace_colo_receive_message(COLOMessage_lookup[msg]);
    return msg;
}
Example #14
0
void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
{
    int ret;
    struct sigaction act, oldact;
    sigset_t set, oldset;

    memset(&act, 0, sizeof(act));
    act.sa_handler = &sigbus_handler;
    act.sa_flags = 0;

    ret = sigaction(SIGBUS, &act, &oldact);
    if (ret) {
        error_setg_errno(errp, errno,
            "os_mem_prealloc: failed to install signal handler");
        return;
    }

    /* unblock SIGBUS */
    sigemptyset(&set);
    sigaddset(&set, SIGBUS);
    pthread_sigmask(SIG_UNBLOCK, &set, &oldset);

    if (sigsetjmp(sigjump, 1)) {
        error_setg(errp, "os_mem_prealloc: Insufficient free host memory "
            "pages available to allocate guest RAM\n");
    } else {
        int i;
        size_t hpagesize = qemu_fd_getpagesize(fd);
        size_t numpages = DIV_ROUND_UP(memory, hpagesize);

        /* MAP_POPULATE silently ignores failures */
        for (i = 0; i < numpages; i++) {
            memset(area + (hpagesize * i), 0, 1);
        }
    }

    ret = sigaction(SIGBUS, &oldact, NULL);
    if (ret) {
        /* Terminate QEMU since it can't recover from error */
        perror("os_mem_prealloc: failed to reinstall signal handler");
        exit(1);
    }
    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}
Example #15
0
QIOChannelSocket *
qio_channel_socket_accept(QIOChannelSocket *ioc,
                          Error **errp)
{
    QIOChannelSocket *cioc;

    cioc = qio_channel_socket_new();
    cioc->remoteAddrLen = sizeof(ioc->remoteAddr);
    cioc->localAddrLen = sizeof(ioc->localAddr);

 retry:
    trace_qio_channel_socket_accept(ioc);
    cioc->fd = qemu_accept(ioc->fd, (struct sockaddr *)&cioc->remoteAddr,
                           &cioc->remoteAddrLen);
    if (cioc->fd < 0) {
        trace_qio_channel_socket_accept_fail(ioc);
        if (errno == EINTR) {
            goto retry;
        }
        goto error;
    }

    if (getsockname(cioc->fd, (struct sockaddr *)&cioc->localAddr,
                    &cioc->localAddrLen) < 0) {
        error_setg_errno(errp, errno,
                         "Unable to query local socket address");
        goto error;
    }

#ifndef WIN32
    if (cioc->localAddr.ss_family == AF_UNIX) {
        QIOChannel *ioc_local = QIO_CHANNEL(cioc);
        qio_channel_set_feature(ioc_local, QIO_CHANNEL_FEATURE_FD_PASS);
    }
#endif /* WIN32 */

    trace_qio_channel_socket_accept_complete(ioc, cioc, cioc->fd);
    return cioc;

 error:
    object_unref(OBJECT(cioc));
    return NULL;
}
Example #16
0
static int64_t ivshmem_recv_msg(IVShmemState *s, int *pfd, Error **errp)
{
    int64_t msg;
    int n, ret;

    n = 0;
    do {
        ret = qemu_chr_fe_read_all(s->server_chr, (uint8_t *)&msg + n,
                                 sizeof(msg) - n);
        if (ret < 0 && ret != -EINTR) {
            error_setg_errno(errp, -ret, "read from server failed");
            return INT64_MIN;
        }
        n += ret;
    } while (n < sizeof(msg));

    *pfd = qemu_chr_fe_get_msgfd(s->server_chr);
    return msg;
}
Example #17
0
File: rbd.c Project: nikunjad/qemu
static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset,
                             PreallocMode prealloc, Error **errp)
{
    BDRVRBDState *s = bs->opaque;
    int r;

    if (prealloc != PREALLOC_MODE_OFF) {
        error_setg(errp, "Unsupported preallocation mode '%s'",
                   PreallocMode_str(prealloc));
        return -ENOTSUP;
    }

    r = rbd_resize(s->image, offset);
    if (r < 0) {
        error_setg_errno(errp, -r, "Failed to resize file");
        return r;
    }

    return 0;
}
Example #18
0
File: colo.c Project: mmuman/qemu
static void colo_send_message_value(QEMUFile *f, COLOMessage msg,
                                    uint64_t value, Error **errp)
{
    Error *local_err = NULL;
    int ret;

    colo_send_message(f, msg, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    qemu_put_be64(f, value);
    qemu_fflush(f);

    ret = qemu_file_get_error(f);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Failed to send value for message:%s",
                         COLOMessage_lookup[msg]);
    }
}
Example #19
0
static int
qio_channel_socket_close(QIOChannel *ioc,
                         Error **errp)
{
    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);

    if (sioc->fd != -1) {
#ifdef WIN32
        WSAEventSelect(sioc->fd, NULL, 0);
#endif
        if (closesocket(sioc->fd) < 0) {
            sioc->fd = -1;
            error_setg_errno(errp, errno,
                             "Unable to close socket");
            return -1;
        }
        sioc->fd = -1;
    }
    return 0;
}
Example #20
0
static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
{
    GICv3State *s = KVM_ARM_GICV3(dev);
    KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s);
    Error *local_err = NULL;

    DPRINTF("kvm_arm_gicv3_realize\n");

    kgc->parent_realize(dev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    if (s->security_extn) {
        error_setg(errp, "the in-kernel VGICv3 does not implement the "
                   "security extensions");
        return;
    }

    gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);

    /* Try to create the device via the device control API */
    s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V3, false);
    if (s->dev_fd < 0) {
        error_setg_errno(errp, -s->dev_fd, "error creating in-kernel VGIC");
        return;
    }

    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
                      0, &s->num_irq, true);

    /* Tell the kernel to complete VGIC initialization now */
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                      KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);

    kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
                            KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd);
    kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
                            KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd);
}
Example #21
0
static int qio_channel_command_abort(QIOChannelCommand *ioc,
                                     Error **errp)
{
    pid_t ret;
    int status;
    int step = 0;

    /* See if intermediate process has exited; if not, try a nice
     * SIGTERM followed by a more severe SIGKILL.
     */
 rewait:
    trace_qio_channel_command_abort(ioc, ioc->pid);
    ret = waitpid(ioc->pid, &status, WNOHANG);
    trace_qio_channel_command_wait(ioc, ioc->pid, ret, status);
    if (ret == (pid_t)-1) {
        if (errno == EINTR) {
            goto rewait;
        } else {
            error_setg_errno(errp, errno,
                             "Cannot wait on pid %llu",
                             (unsigned long long)ioc->pid);
            return -1;
        }
    } else if (ret == 0) {
        if (step == 0) {
            kill(ioc->pid, SIGTERM);
        } else if (step == 1) {
            kill(ioc->pid, SIGKILL);
        } else {
            error_setg(errp,
                       "Process %llu refused to die",
                       (unsigned long long)ioc->pid);
            return -1;
        }
        step++;
        usleep(10 * 1000);
        goto rewait;
    }

    return 0;
}
Example #22
0
File: memfd.c Project: CTU-IIG/qemu
/*
 * This is a best-effort helper for shared memory allocation, with
 * optional sealing. The helper will do his best to allocate using
 * memfd with sealing, but may fallback on other methods without
 * sealing.
 */
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
                       int *fd, Error **errp)
{
    void *ptr;
    int mfd = qemu_memfd_create(name, size, false, 0, seals, NULL);

    /* some systems have memfd without sealing */
    if (mfd == -1) {
        mfd = qemu_memfd_create(name, size, false, 0, 0, NULL);
    }

    if (mfd == -1) {
        const char *tmpdir = g_get_tmp_dir();
        gchar *fname;

        fname = g_strdup_printf("%s/memfd-XXXXXX", tmpdir);
        mfd = mkstemp(fname);
        unlink(fname);
        g_free(fname);

        if (mfd == -1 ||
            ftruncate(mfd, size) == -1) {
            goto err;
        }
    }

    ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0);
    if (ptr == MAP_FAILED) {
        goto err;
    }

    *fd = mfd;
    return ptr;

err:
    error_setg_errno(errp, errno, "failed to allocate shared memory");
    if (mfd >= 0) {
        close(mfd);
    }
    return NULL;
}
Example #23
0
static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
                                         const struct iovec *iov,
                                         size_t niov,
                                         int *fds,
                                         size_t nfds,
                                         Error **errp)
{
    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
    ssize_t done = 0;
    ssize_t i;

    for (i = 0; i < niov; i++) {
        ssize_t ret;
    retry:
        ret = send(sioc->fd,
                   iov[i].iov_base,
                   iov[i].iov_len,
                   0);
        if (ret < 0) {
            if (errno == EAGAIN) {
                if (done) {
                    return done;
                } else {
                    return QIO_CHANNEL_ERR_BLOCK;
                }
            } else if (errno == EINTR) {
                goto retry;
            } else {
                error_setg_errno(errp, errno,
                                 "Unable to write to socket");
                return -1;
            }
        }
        done += ret;
        if (ret < iov[i].iov_len) {
            return done;
        }
    }

    return done;
}
Example #24
0
File: colo.c Project: mmuman/qemu
static uint64_t colo_receive_message_value(QEMUFile *f, uint32_t expect_msg,
                                           Error **errp)
{
    Error *local_err = NULL;
    uint64_t value;
    int ret;

    colo_receive_check_message(f, expect_msg, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return 0;
    }

    value = qemu_get_be64(f);
    ret = qemu_file_get_error(f);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Failed to get value for COLO message: %s",
                         COLOMessage_lookup[expect_msg]);
    }
    return value;
}
Example #25
0
void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid,
                     const char *node, const char *key, Error **errp,
                     const char *fmt, va_list ap)
{
    char *path, *value;
    int len;

    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
        g_strdup(key);
    len = g_vasprintf(&value, fmt, ap);

    trace_xs_node_vprintf(path, value);

    if (!xs_write(xsh, tid, path, value, len)) {
        error_setg_errno(errp, errno, "failed to write '%s' to '%s'",
                         value, path);
    }

    g_free(value);
    g_free(path);
}
Example #26
0
int
qcrypto_tls_creds_get_path(QCryptoTLSCreds *creds,
                           const char *filename,
                           bool required,
                           char **cred,
                           Error **errp)
{
    struct stat sb;
    int ret = -1;

    if (!creds->dir) {
        if (required) {
            error_setg(errp, "Missing 'dir' property value");
            return -1;
        } else {
            return 0;
        }
    }

    *cred = g_strdup_printf("%s/%s", creds->dir, filename);

    if (stat(*cred, &sb) < 0) {
        if (errno == ENOENT && !required) {
            ret = 0;
        } else {
            error_setg_errno(errp, errno,
                             "Unable to access credentials %s",
                             *cred);
        }
        g_free(*cred);
        *cred = NULL;
        goto cleanup;
    }

    ret = 0;
 cleanup:
    trace_qcrypto_tls_creds_get_path(creds, filename,
                                     *cred ? *cred : "<none>");
    return ret;
}
Example #27
0
File: tap.c Project: PennPanda/qemu
static void launch_script(const char *setup_script, const char *ifname,
                          int fd, Error **errp)
{
    int pid, status;
    char *args[3];
    char **parg;

    /* try to launch network script */
    pid = fork();
    if (pid < 0) {
        error_setg_errno(errp, errno, "could not launch network script %s",
                         setup_script);
        return;
    }
    if (pid == 0) {
        int open_max = sysconf(_SC_OPEN_MAX), i;

        for (i = 3; i < open_max; i++) {
            if (i != fd) {
                close(i);
            }
        }
        parg = args;
        *parg++ = (char *)setup_script;
        *parg++ = (char *)ifname;
        *parg = NULL;
        execv(setup_script, args);
        _exit(1);
    } else {
        while (waitpid(pid, &status, 0) != pid) {
            /* loop */
        }

        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
            return;
        }
        error_setg(errp, "network script %s failed with status %d",
                   setup_script, status);
    }
}
Example #28
0
static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
{
    GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
    Error *local_err = NULL;

    s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_ITS, false);
    if (s->dev_fd < 0) {
        error_setg_errno(errp, -s->dev_fd, "error creating in-kernel ITS");
        return;
    }

    /* explicit init of the ITS */
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                      KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort);

    /* register the base address */
    kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
                            KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd);

    gicv3_its_init_mmio(s, NULL);

    if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
        GITS_CTLR)) {
        error_setg(&s->migration_blocker, "This operating system kernel "
                   "does not support vITS migration");
        migrate_add_blocker(s->migration_blocker, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            error_free(s->migration_blocker);
            return;
        }
    } else {
        qemu_add_vm_change_state_handler(vm_change_state_handler, s);
    }

    kvm_msi_use_devid = true;
    kvm_gsi_direct_mapping = false;
    kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
}
Example #29
0
/* create the shared memory BAR when we are not using the server, so we can
 * create the BAR and map the memory immediately */
static int create_shared_memory_BAR(IVShmemState *s, int fd, uint8_t attr,
                                    Error **errp)
{
    void * ptr;

    ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if (ptr == MAP_FAILED) {
        error_setg_errno(errp, errno, "Failed to mmap shared memory");
        return -1;
    }

    memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2",
                               s->ivshmem_size, ptr);
    qemu_set_ram_fd(s->ivshmem.ram_addr, fd);
    vmstate_register_ram(&s->ivshmem, DEVICE(s));
    memory_region_add_subregion(&s->bar, 0, &s->ivshmem);

    /* region for shared memory */
    pci_register_bar(PCI_DEVICE(s), 2, attr, &s->bar);

    return 0;
}
Example #30
0
File: async.c Project: L0op/qemu
AioContext *aio_context_new(Error **errp)
{
    int ret;
    AioContext *ctx;
    ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
    ret = event_notifier_init(&ctx->notifier, false);
    if (ret < 0) {
        g_source_destroy(&ctx->source);
        error_setg_errno(errp, -ret, "Failed to initialize event notifier");
        return NULL;
    }
    aio_set_event_notifier(ctx, &ctx->notifier,
                           (EventNotifierHandler *)
                           event_notifier_test_and_clear);
    ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
    ctx->thread_pool = NULL;
    qemu_mutex_init(&ctx->bh_lock);
    rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
    timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);

    return ctx;
}