Commit b074e622 authored by Christian Borntraeger's avatar Christian Borntraeger
Browse files

s390x/sclpconsole: Fix and simplify interrupt injection



valgrind complains about a memory leak in irq setup of sclpconsole:

==42117== 8 bytes in 1 blocks are definitely lost in loss record 89 of 833
==42117==    at 0x4031AFE: malloc (vg_replace_malloc.c:292)
==42117==    by 0x8022F855: malloc_and_trace (vl.c:2715)
==42117==    by 0x4145569: g_malloc (in /usr/lib64/libglib-2.0.so.0.3400.2)
==42117==    by 0x800F696D: qemu_extend_irqs (irq.c:51)
==42117==    by 0x800F6AF7: qemu_allocate_irqs (irq.c:68)
==42117==    by 0x800F5685: console_init (sclpconsole.c:235)
==42117==    by 0x80297C79: event_realize (event-facility.c:386)
==42117==    by 0x80105071: device_set_realized (qdev.c:693)
==42117==    by 0x801CDC4B: property_set_bool (object.c:1337)
==42117==    by 0x801CBD7F: object_property_set (object.c:819)
[...]

Turns out that we actually dont need the indirection, so trigger the
sclp interrupt directly.

Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Acked-by: default avatarHeinz Graalfs <graalfs@linux.vnet.ibm.com>
parent 7b53f294
Loading
Loading
Loading
Loading
+6 −24
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ typedef struct SCLPConsole {
    uint32_t iov_bs;        /* offset in buf for char layer read operation */
    uint32_t iov_data_len;  /* length of byte stream in buffer             */
    uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP     */
    qemu_irq irq_read_vt220;
} SCLPConsole;

/* character layer call-back functions */
@@ -49,11 +48,12 @@ static int chr_can_read(void *opaque)
    return SIZE_BUFFER_VT220 - scon->iov_data_len;
}

/* Receive n bytes from character layer, save in iov buffer,
 * and set event pending */
static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
                                   int size)
/* Send data from a char device over to the guest */
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    SCLPConsole *scon = opaque;

    assert(scon);
    /* read data must fit into current buffer */
    assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len);

@@ -63,18 +63,7 @@ static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
    scon->iov_sclp_rest += size;
    scon->iov_bs += size;
    scon->event.event_pending = true;
}

/* Send data from a char device over to the guest */
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    SCLPConsole *scon = opaque;

    assert(scon);

    receive_from_chr_layer(scon, buf, size);
    /* trigger SCLP read operation */
    qemu_irq_raise(scon->irq_read_vt220);
    sclp_service_interrupt(0);
}

/* functions to be called by event facility */
@@ -192,11 +181,6 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
    return rc;
}

static void trigger_ascii_console_data(void *opaque, int n, int level)
{
    sclp_service_interrupt(0);
}

static const VMStateDescription vmstate_sclpconsole = {
    .name = "sclpconsole",
    .version_id = 0,
@@ -232,8 +216,6 @@ static int console_init(SCLPEvent *event)
        qemu_chr_add_handlers(scon->chr, chr_can_read,
                              chr_read, NULL, scon);
    }
    scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data,
                                               NULL, 1);

    return 0;
}