Exemple #1
0
static void filter_redirector_setup(NetFilterState *nf, Error **errp)
{
    MirrorState *s = FILTER_REDIRECTOR(nf);
    Chardev *chr;

    if (!s->indev && !s->outdev) {
        error_setg(errp, "filter redirector needs 'indev' or "
                   "'outdev' at least one property set");
        return;
    } else if (s->indev && s->outdev) {
        if (!strcmp(s->indev, s->outdev)) {
            error_setg(errp, "'indev' and 'outdev' could not be same "
                       "for filter redirector");
            return;
        }
    }

    net_socket_rs_init(&s->rs, redirector_rs_finalize);

    if (s->indev) {
        chr = qemu_chr_find(s->indev);
        if (chr == NULL) {
            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                      "IN Device '%s' not found", s->indev);
            return;
        }

        if (!qemu_chr_fe_init(&s->chr_in, chr, errp)) {
            return;
        }

        qemu_chr_fe_set_handlers(&s->chr_in, redirector_chr_can_read,
                                 redirector_chr_read, redirector_chr_event,
                                 nf, NULL, true);
    }

    if (s->outdev) {
        chr = qemu_chr_find(s->outdev);
        if (chr == NULL) {
            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                      "OUT Device '%s' not found", s->outdev);
            return;
        }
        if (!qemu_chr_fe_init(&s->chr_out, chr, errp)) {
            return;
        }
    }
}
Exemple #2
0
static CharDriverState *net_vhost_parse_chardev(const NetdevVhostUserOptions *opts)
{
    CharDriverState *chr = qemu_chr_find(opts->chardev);
    VhostUserChardevProps props;

    if (chr == NULL) {
        error_report("chardev \"%s\" not found", opts->chardev);
        return NULL;
    }

    /* inspect chardev opts */
    memset(&props, 0, sizeof(props));
    if (qemu_opt_foreach(chr->opts, net_vhost_chardev_opts, &props, true) != 0) {
        return NULL;
    }

    if (!props.is_socket || !props.is_unix) {
        error_report("chardev \"%s\" is not a unix socket",
                     opts->chardev);
        return NULL;
    }

    qemu_chr_fe_claim_no_fail(chr);

    return chr;
}
Exemple #3
0
static void rng_egd_opened(RngBackend *b, Error **errp)
{
    RngEgd *s = RNG_EGD(b);

    if (s->chr_name == NULL) {
        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
                  "chardev", "a valid character device");
        return;
    }

    s->chr = qemu_chr_find(s->chr_name);
    if (s->chr == NULL) {
        error_set(errp, QERR_DEVICE_NOT_FOUND, s->chr_name);
        return;
    }

    if (qemu_chr_fe_claim(s->chr) != 0) {
        error_set(errp, QERR_DEVICE_IN_USE, s->chr_name);
        return;
    }

    /* FIXME we should resubmit pending requests when the CDS reconnects. */
    qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read,
                          NULL, s);
}
static int parse_chr(DeviceState *dev, const char *str, void **ptr)
{
    CharDriverState *chr = qemu_chr_find(str);
    if (chr == NULL) {
        return -ENOENT;
    }
    if (qemu_chr_fe_claim(chr) != 0) {
        return -EEXIST;
    }
    *ptr = chr;
    return 0;
}
Exemple #5
0
static int parse_chr(DeviceState *dev, const char *str, void **ptr)
{
    CharDriverState *chr = qemu_chr_find(str);
    if (chr == NULL) {
        return -ENOENT;
    }
    if (chr->avail_connections < 1) {
        return -EEXIST;
    }
    *ptr = chr;
    --chr->avail_connections;
    return 0;
}
Exemple #6
0
static void filter_mirror_setup(NetFilterState *nf, Error **errp)
{
    MirrorState *s = FILTER_MIRROR(nf);
    Chardev *chr;

    chr = qemu_chr_find(s->outdev);
    if (chr == NULL) {
        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                  "Device '%s' not found", s->outdev);
        return;
    }

    qemu_chr_fe_init(&s->chr_out, chr, errp);
}
Exemple #7
0
static int parse_chr(DeviceState *dev, Property *prop, const char *str)
{
    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);

    *ptr = qemu_chr_find(str);
    if (*ptr == NULL) {
        return -ENOENT;
    }
    if ((*ptr)->avail_connections < 1) {
        return -EEXIST;
    }
    --(*ptr)->avail_connections;
    return 0;
}
static void parse_chr(DeviceState *dev, const char *str, void **ptr,
                      const char *propname, Error **errp)
{
    CharDriverState *chr = qemu_chr_find(str);
    if (chr == NULL) {
        error_setg(errp, "Property '%s.%s' can't find value '%s'",
                   object_get_typename(OBJECT(dev)), propname, str);
        return;
    }
    if (qemu_chr_fe_claim(chr) != 0) {
        error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
                  object_get_typename(OBJECT(dev)), propname, str);
        return;
    }
    *ptr = chr;
}
Exemple #9
0
static int stm32_button_init(SysBusDevice *dev, const char* id) {
    stm32_button_state *s = FROM_SYSBUS(stm32_button_state, dev);
    
    //Initialisation de la pin de sortie
    //Initialisation of the output pin
    qdev_init_gpio_out(&dev->qdev, &s->gpio_out, 1);
    
    //Initialisation du Chardev
    s->chr = qdev_init_chardev(&dev->qdev);
    s->chr = qemu_chr_find(id);
    if (s->chr) {
        qemu_chr_add_handlers(s->chr, stm32_can_receive, stm32_receive, stm32_event, s);
    }
    
    stm32_button_reset(s);
    vmstate_register(&dev->qdev, -1, &vmstate_stm32_button, s);
 
    return 0;
}
Exemple #10
0
/*
 * Return 0 is success.
 * Return 1 is failed.
 */
static int find_and_check_chardev(Chardev **chr,
                                  char *chr_name,
                                  Error **errp)
{
    *chr = qemu_chr_find(chr_name);
    if (*chr == NULL) {
        error_setg(errp, "Device '%s' not found",
                   chr_name);
        return 1;
    }

    if (!qemu_chr_has_feature(*chr, QEMU_CHAR_FEATURE_RECONNECTABLE)) {
        error_setg(errp, "chardev \"%s\" is not reconnectable",
                   chr_name);
        return 1;
    }

    return 0;
}
Exemple #11
0
static int stm32_led_init(SysBusDevice *dev, const char* id) {
    stm32_led_state *s = FROM_SYSBUS(stm32_led_state, dev);
    
    
    //Initialisation des pins d'entrées
    qdev_init_gpio_in(&dev->qdev, stm32_led_recvirq, 1);

    //Initialiser le chardev
    s->chr = qdev_init_chardev(&dev->qdev);
    s->chr = qemu_chr_find(id);
    if (s->chr) {
        qemu_chr_add_handlers(s->chr, stm32_can_receive, stm32_receive, stm32_event, s);
    }
    
    stm32_led_reset(s);
    vmstate_register(&dev->qdev, -1, &vmstate_stm32_led, s);

    return 0;
}
Exemple #12
0
static void qemu_chr_open_mux(Chardev *chr,
                              ChardevBackend *backend,
                              bool *be_opened,
                              Error **errp)
{
    ChardevMux *mux = backend->u.mux.data;
    Chardev *drv;
    MuxChardev *d = MUX_CHARDEV(chr);

    drv = qemu_chr_find(mux->chardev);
    if (drv == NULL) {
        error_setg(errp, "mux: base chardev %s not found", mux->chardev);
        return;
    }

    d->focus = -1;
    /* only default to opened state if we've realized the initial
     * set of muxes
     */
    *be_opened = machine_init_done;
    qemu_chr_fe_init(&d->chr, drv, errp);
}
Exemple #13
0
static Chardev *net_vhost_claim_chardev(
    const NetdevVhostUserOptions *opts, Error **errp)
{
    Chardev *chr = qemu_chr_find(opts->chardev);

    if (chr == NULL) {
        error_setg(errp, "chardev \"%s\" not found", opts->chardev);
        return NULL;
    }

    if (!qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE)) {
        error_setg(errp, "chardev \"%s\" is not reconnectable",
                   opts->chardev);
        return NULL;
    }
    if (!qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_FD_PASS)) {
        error_setg(errp, "chardev \"%s\" does not support FD passing",
                   opts->chardev);
        return NULL;
    }

    return chr;
}
static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                    Error **errp)
{
    DeviceState *dev = DEVICE(obj);
    Error *local_err = NULL;
    Property *prop = opaque;
    CharBackend *be = qdev_get_prop_ptr(dev, prop);
    CharDriverState *s;
    char *str;

    if (dev->realized) {
        qdev_prop_set_after_realize(dev, name, errp);
        return;
    }

    visit_type_str(v, name, &str, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    if (!*str) {
        g_free(str);
        be->chr = NULL;
        return;
    }

    s = qemu_chr_find(str);
    if (s == NULL) {
        error_setg(errp, "Property '%s.%s' can't find value '%s'",
                   object_get_typename(obj), prop->name, str);
    } else if (!qemu_chr_fe_init(be, s, errp)) {
        error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
                      object_get_typename(obj), prop->name, str);
    }
    g_free(str);
}
Exemple #15
0
static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
{
    const char *value;

    value = qemu_opt_get(opts, "chardev");
    if (value) {
        Error *err = NULL;
        Chardev *dev = qemu_chr_find(value);

        if (!dev) {
            error_report("tpm-emulator: tpm chardev '%s' not found.", value);
            goto err;
        }

        if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
            error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
                          value);
            error_report_err(err);
            goto err;
        }

        tpm_emu->options->chardev = g_strdup(value);
    }

    if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
        goto err;
    }

    /* FIXME: tpm_util_test_tpmdev() accepts only on socket fd, as it also used
     * by passthrough driver, which not yet using GIOChannel.
     */
    if (tpm_util_test_tpmdev(QIO_CHANNEL_SOCKET(tpm_emu->data_ioc)->fd,
                             &tpm_emu->tpm_version)) {
        error_report("'%s' is not emulating TPM device. Error: %s",
                      tpm_emu->options->chardev, strerror(errno));
        goto err;
    }

    switch (tpm_emu->tpm_version) {
    case TPM_VERSION_1_2:
        trace_tpm_emulator_handle_device_opts_tpm12();
        break;
    case TPM_VERSION_2_0:
        trace_tpm_emulator_handle_device_opts_tpm2();
        break;
    default:
        trace_tpm_emulator_handle_device_opts_unspec();
    }

    if (tpm_emulator_probe_caps(tpm_emu) ||
        tpm_emulator_check_caps(tpm_emu)) {
        goto err;
    }

    return tpm_emulator_block_migration(tpm_emu);

err:
    trace_tpm_emulator_handle_device_opts_startup_error();

    return -1;
}
Exemple #16
0
static void char_mux_test(void)
{
    QemuOpts *opts;
    Chardev *chr, *base;
    char *data;
    FeHandler h1 = { 0, false, 0, false, }, h2 = { 0, false, 0, false, };
    CharBackend chr_be1, chr_be2;

    opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
                            1, &error_abort);
    qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
    qemu_opt_set(opts, "size", "128", &error_abort);
    qemu_opt_set(opts, "mux", "on", &error_abort);
    chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
    g_assert_nonnull(chr);
    qemu_opts_del(opts);

    qemu_chr_fe_init(&chr_be1, chr, &error_abort);
    qemu_chr_fe_set_handlers(&chr_be1,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h1,
                             NULL, true);

    qemu_chr_fe_init(&chr_be2, chr, &error_abort);
    qemu_chr_fe_set_handlers(&chr_be2,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h2,
                             NULL, true);
    qemu_chr_fe_take_focus(&chr_be2);

    base = qemu_chr_find("mux-label-base");
    g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);

    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 6);
    g_assert_cmpstr(h2.read_buf, ==, "hello");
    h2.read_count = 0;

    g_assert_cmpint(h1.last_event, !=, 42); /* should be MUX_OUT or OPENED */
    g_assert_cmpint(h2.last_event, !=, 42); /* should be MUX_IN or OPENED */
    /* sending event on the base broadcast to all fe, historical reasons? */
    qemu_chr_be_event(base, 42);
    g_assert_cmpint(h1.last_event, ==, 42);
    g_assert_cmpint(h2.last_event, ==, 42);
    qemu_chr_be_event(chr, -1);
    g_assert_cmpint(h1.last_event, ==, 42);
    g_assert_cmpint(h2.last_event, ==, -1);

    /* switch focus */
    qemu_chr_be_write(base, (void *)"\1b", 2);
    g_assert_cmpint(h1.last_event, ==, 42);
    g_assert_cmpint(h2.last_event, ==, CHR_EVENT_BREAK);

    qemu_chr_be_write(base, (void *)"\1c", 2);
    g_assert_cmpint(h1.last_event, ==, CHR_EVENT_MUX_IN);
    g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
    qemu_chr_be_event(chr, -1);
    g_assert_cmpint(h1.last_event, ==, -1);
    g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);

    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h2.read_count, ==, 0);
    g_assert_cmpint(h1.read_count, ==, 6);
    g_assert_cmpstr(h1.read_buf, ==, "hello");
    h1.read_count = 0;

    qemu_chr_be_write(base, (void *)"\1b", 2);
    g_assert_cmpint(h1.last_event, ==, CHR_EVENT_BREAK);
    g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);

    /* open/close state and corresponding events */
    g_assert_true(qemu_chr_fe_backend_open(&chr_be1));
    g_assert_true(qemu_chr_fe_backend_open(&chr_be2));
    g_assert_true(h1.is_open);
    g_assert_false(h1.openclose_mismatch);
    g_assert_true(h2.is_open);
    g_assert_false(h2.openclose_mismatch);

    h1.openclose_count = h2.openclose_count = 0;

    qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
                             NULL, NULL, false);
    qemu_chr_fe_set_handlers(&chr_be2, NULL, NULL, NULL, NULL,
                             NULL, NULL, false);
    g_assert_cmpint(h1.openclose_count, ==, 0);
    g_assert_cmpint(h2.openclose_count, ==, 0);

    h1.is_open = h2.is_open = false;
    qemu_chr_fe_set_handlers(&chr_be1,
                             NULL,
                             NULL,
                             fe_event,
                             NULL,
                             &h1,
                             NULL, false);
    qemu_chr_fe_set_handlers(&chr_be2,
                             NULL,
                             NULL,
                             fe_event,
                             NULL,
                             &h2,
                             NULL, false);
    g_assert_cmpint(h1.openclose_count, ==, 1);
    g_assert_false(h1.openclose_mismatch);
    g_assert_cmpint(h2.openclose_count, ==, 1);
    g_assert_false(h2.openclose_mismatch);

    qemu_chr_be_event(base, CHR_EVENT_CLOSED);
    qemu_chr_be_event(base, CHR_EVENT_OPENED);
    g_assert_cmpint(h1.openclose_count, ==, 3);
    g_assert_false(h1.openclose_mismatch);
    g_assert_cmpint(h2.openclose_count, ==, 3);
    g_assert_false(h2.openclose_mismatch);

    qemu_chr_fe_set_handlers(&chr_be2,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h2,
                             NULL, false);
    qemu_chr_fe_set_handlers(&chr_be1,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h1,
                             NULL, false);

    /* remove first handler */
    qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
                             NULL, NULL, true);
    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 0);

    qemu_chr_be_write(base, (void *)"\1c", 2);
    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 6);
    g_assert_cmpstr(h2.read_buf, ==, "hello");
    h2.read_count = 0;

    /* print help */
    qemu_chr_be_write(base, (void *)"\1?", 2);
    data = qmp_ringbuf_read("mux-label-base", 128, false, 0, &error_abort);
    g_assert_cmpint(strlen(data), !=, 0);
    g_free(data);

    qemu_chr_fe_deinit(&chr_be1, false);
    qemu_chr_fe_deinit(&chr_be2, true);
}
Exemple #17
0
static void char_mux_test(void)
{
    QemuOpts *opts;
    Chardev *chr, *base;
    char *data;
    FeHandler h1 = { 0, }, h2 = { 0, };
    CharBackend chr_be1, chr_be2;

    opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
                            1, &error_abort);
    qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
    qemu_opt_set(opts, "size", "128", &error_abort);
    qemu_opt_set(opts, "mux", "on", &error_abort);
    chr = qemu_chr_new_from_opts(opts, &error_abort);
    g_assert_nonnull(chr);
    qemu_opts_del(opts);

    qemu_chr_fe_init(&chr_be1, chr, &error_abort);
    qemu_chr_fe_set_handlers(&chr_be1,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h1,
                             NULL, true);

    qemu_chr_fe_init(&chr_be2, chr, &error_abort);
    qemu_chr_fe_set_handlers(&chr_be2,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h2,
                             NULL, true);
    qemu_chr_fe_take_focus(&chr_be2);

    base = qemu_chr_find("mux-label-base");
    g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);

    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 6);
    g_assert_cmpstr(h2.read_buf, ==, "hello");
    h2.read_count = 0;

    /* switch focus */
    qemu_chr_be_write(base, (void *)"\1c", 2);

    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h2.read_count, ==, 0);
    g_assert_cmpint(h1.read_count, ==, 6);
    g_assert_cmpstr(h1.read_buf, ==, "hello");
    h1.read_count = 0;

    /* remove first handler */
    qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
                             NULL, NULL, true);
    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 0);

    qemu_chr_be_write(base, (void *)"\1c", 2);
    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 6);
    g_assert_cmpstr(h2.read_buf, ==, "hello");
    h2.read_count = 0;

    /* print help */
    qemu_chr_be_write(base, (void *)"\1?", 2);
    data = qmp_ringbuf_read("mux-label-base", 128, false, 0, &error_abort);
    g_assert_cmpint(strlen(data), !=, 0);
    g_free(data);

    qemu_chr_fe_deinit(&chr_be1, false);
    qemu_chr_fe_deinit(&chr_be2, true);
}
Exemple #18
0
static void ss_realize(DeviceState *dev, Error **errp)
{
    SlaveBootInt *s = SBI(dev);
    const char *prefix = object_get_canonical_path(OBJECT(dev));
    unsigned int i;
    const char *port_name;
    Chardev *chr;

    for (i = 0; i < ARRAY_SIZE(slave_boot_regs_info); ++i) {
        DepRegisterInfo *r = &s->regs_info[
                                slave_boot_regs_info[i].decode.addr / 4];

        *r = (DepRegisterInfo) {
            .data = (uint8_t *)&s->regs[
                    slave_boot_regs_info[i].decode.addr / 4],
            .data_size = sizeof(uint32_t),
            .access = &slave_boot_regs_info[i],
            .debug = SBI_ERR_DEBUG,
            .prefix = prefix,
            .opaque = s,
        };
   }

    port_name = g_strdup("smap_busy_b");
    qdev_init_gpio_out_named(dev, &s->smap_busy, port_name, 1);
    g_free((gpointer) port_name);

    port_name = g_strdup("smap_in_b");
    qdev_init_gpio_in_named(dev, smap_update, port_name, 2);
    g_free((gpointer) port_name);

    chr = qemu_chr_find("sbi");
    qdev_prop_set_chr(dev, "chardev", chr);
    if (!qemu_chr_fe_get_driver(&s->chr)) {
        DPRINT("SBI interface not connected\n");
    } else {
        qemu_chr_fe_set_handlers(&s->chr, ss_sbi_can_receive, ss_sbi_receive,
                                 NULL, NULL, s, NULL, true);
    }

    fifo_create8(&s->fifo, 1024 * 4);
}

static void ss_reset(DeviceState *dev)
{
    SlaveBootInt *s = SBI(dev);
    uint32_t i;

    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
        dep_register_reset(&s->regs_info[i]);
    }
    fifo_reset(&s->fifo);
    s->busy_line = 1;
    qemu_set_irq(s->smap_busy, s->busy_line);
    ss_update_busy_line(s);
    sbi_update_irq(s);
    /* Note : cs always 0 when rp is not connected
     * i.e slave always respond to master data irrespective of
     * master state
     *
     * as rdwr is also 0, initial state of sbi is data load. Hack this bit
     * to become 1, when sbi changes to write mode. So, its assumed in
     * non remote-port model master should expect data when slave wishes
     * to send.
     */
}