virtio-snd: remove a redundant memory allocation
This change also makes its lifetime explicit and prevents NULL dereferences. Signed-off-by: Roman Kiryanov <rkir@google.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260305042523.335493-1-rkir@google.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Roman Kiryanov committed
Mar 5, 2026 at 04:25 UTC
2fd2f50e9b42362c8dc10bc38c21a1fb34eaa66b
2 files changed
+25
-30
hw/audio/virtio-snd.c
+24
-29
@@ -130,7 +130,7 @@ static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
130
uint32_t stream_id)
131
{
132
return stream_id >= s->snd_conf.streams ? NULL :
133
- s->pcm->streams[stream_id];
133
+ s->pcm.streams[stream_id];
134
}
135
136
/*
@@ -143,7 +143,7 @@ static virtio_snd_pcm_set_params *virtio_snd_pcm_get_params(VirtIOSound *s,
143
uint32_t stream_id)
144
{
145
return stream_id >= s->snd_conf.streams ? NULL
146
- : &s->pcm->pcm_params[stream_id];
146
+ : &s->pcm.pcm_params[stream_id];
147
}
148
149
/*
@@ -260,7 +260,7 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
260
{
261
virtio_snd_pcm_set_params *st_params;
262
263
- if (stream_id >= s->snd_conf.streams || s->pcm->pcm_params == NULL) {
263
+ if (stream_id >= s->snd_conf.streams || s->pcm.pcm_params == NULL) {
264
virtio_error(VIRTIO_DEVICE(s), "Streams have not been initialized.\n");
265
return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
266
}
@@ -424,8 +424,8 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
424
virtio_snd_pcm_set_params *params;
425
VirtIOSoundPCMStream *stream;
426
427
- if (s->pcm->streams == NULL ||
428
- s->pcm->pcm_params == NULL ||
427
+ if (s->pcm.streams == NULL ||
428
+ s->pcm.pcm_params == NULL ||
429
stream_id >= s->snd_conf.streams) {
430
return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
431
}
@@ -440,7 +440,7 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
440
stream = g_new0(VirtIOSoundPCMStream, 1);
441
stream->active = false;
442
stream->id = stream_id;
443
- stream->pcm = s->pcm;
443
+ stream->pcm = &s->pcm;
444
stream->s = s;
445
stream->latency_bytes = 0;
446
qemu_mutex_init(&stream->queue_mutex);
@@ -450,7 +450,7 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
450
* stream_id >= s->snd_conf.streams was checked before so this is
451
* in-bounds
452
*/
453
- s->pcm->streams[stream_id] = stream;
453
+ s->pcm.streams[stream_id] = stream;
454
}
455
456
virtio_snd_get_qemu_audsettings(&as, params);
@@ -884,11 +884,11 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
884
stream_id = le32_to_cpu(hdr.stream_id);
885
886
if (stream_id >= vsnd->snd_conf.streams
887
- || vsnd->pcm->streams[stream_id] == NULL) {
887
+ || vsnd->pcm.streams[stream_id] == NULL) {
888
goto tx_err;
889
}
890
891
- stream = vsnd->pcm->streams[stream_id];
891
+ stream = vsnd->pcm.streams[stream_id];
892
if (stream->info.direction != VIRTIO_SND_D_OUTPUT) {
893
goto tx_err;
894
}
@@ -966,11 +966,11 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
966
stream_id = le32_to_cpu(hdr.stream_id);
967
968
if (stream_id >= vsnd->snd_conf.streams
969
- || !vsnd->pcm->streams[stream_id]) {
969
+ || !vsnd->pcm.streams[stream_id]) {
970
goto rx_err;
971
}
972
973
- stream = vsnd->pcm->streams[stream_id];
973
+ stream = vsnd->pcm.streams[stream_id];
974
if (stream == NULL || stream->info.direction != VIRTIO_SND_D_INPUT) {
975
goto rx_err;
976
}
@@ -1064,11 +1064,10 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
1064
vsnd->vmstate =
1065
qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
1066
1067
- vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
1068
- vsnd->pcm->snd = vsnd;
1069
- vsnd->pcm->streams =
1067
+ vsnd->pcm.snd = vsnd;
1068
+ vsnd->pcm.streams =
1069
g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
1071
- vsnd->pcm->pcm_params =
1070
+ vsnd->pcm.pcm_params =
1071
g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
1072
1073
virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
@@ -1335,23 +1334,19 @@ static void virtio_snd_unrealize(DeviceState *dev)
1334
qemu_del_vm_change_state_handler(vsnd->vmstate);
1335
trace_virtio_snd_unrealize(vsnd);
1336
1338
- if (vsnd->pcm) {
1339
- if (vsnd->pcm->streams) {
1340
- for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
1341
- stream = vsnd->pcm->streams[i];
1342
- if (stream) {
1343
- virtio_snd_process_cmdq(stream->s);
1344
- virtio_snd_pcm_close(stream);
1345
- qemu_mutex_destroy(&stream->queue_mutex);
1346
- g_free(stream);
1347
- }
1337
+ if (vsnd->pcm.streams) {
1338
+ for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
1339
+ stream = vsnd->pcm.streams[i];
1340
+ if (stream) {
1341
+ virtio_snd_process_cmdq(stream->s);
1342
+ virtio_snd_pcm_close(stream);
1343
+ qemu_mutex_destroy(&stream->queue_mutex);
1344
+ g_free(stream);
1345
}
1349
- g_free(vsnd->pcm->streams);
1346
}
1351
- g_free(vsnd->pcm->pcm_params);
1352
- g_free(vsnd->pcm);
1353
- vsnd->pcm = NULL;
1347
+ g_free(vsnd->pcm.streams);
1348
}
1349
+ g_free(vsnd->pcm.pcm_params);
1350
qemu_mutex_destroy(&vsnd->cmdq_mutex);
1351
virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_CONTROL]);
1352
virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_EVENT]);
include/hw/audio/virtio-snd.h
+1
-1
@@ -216,7 +216,7 @@ struct VirtIOSound {
216
217
VirtQueue *queues[VIRTIO_SND_VQ_MAX];
218
uint64_t features;
219
- VirtIOSoundPCM *pcm;
219
+ VirtIOSoundPCM pcm;
220
AudioBackend *audio_be;
221
VMChangeStateEntry *vmstate;
222
virtio_snd_config snd_conf;