@samitouri / QOSamiQemu / commits / f8015fe988

hw/arm/smmuv3-accel: Introduce common helper for veventq read

Move the vEVENTQ read and validation logic into a common helper smmuv3_accel_event_read_validate(). The helper performs the read(), checks for overflow and short reads, validates the sequence number, and updates the sequence state. This helper can be reused for Tegra241 CMDQV vEVENTQ support in a subsequent patch. Error handling is slightly adjusted: instead of reporting errors directly in the read handler, the helper now returns errors via Error **. Sequence gaps are reported as warnings. Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com> Tested-by: Eric Auger <eric.auger@redhat.com> Message-id: 20260609112552.378999-23-skolothumtho@nvidia.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Shameer Kolothum committed Jun 9, 2026 at 12:25 UTC f8015fe988df09448ea67458dd31f04d704388c3
3 files changed +49 -27
hw/arm/smmuv3-accel-stubs.c
+7
@@ -47,6 +47,13 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp)
47 return true;
48 }
49
50 +bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
51 + void *buf, size_t size, Error **errp)
52 +{
53 + return true;
54 +}
55 +
56 +
57 void smmuv3_accel_reset(SMMUv3State *s)
58 {
59 }
hw/arm/smmuv3-accel.c
+40 -27
@@ -440,47 +440,60 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sdev,
440 sizeof(Cmd), &entry_num, cmd, errp);
441 }
442
443 -static void smmuv3_accel_event_read(void *opaque)
443 +bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
444 + void *buf, size_t size, Error **errp)
445 {
445 - SMMUv3State *s = opaque;
446 - IOMMUFDVeventq *veventq = s->s_accel->veventq;
447 - struct {
448 - struct iommufd_vevent_header hdr;
449 - struct iommu_vevent_arm_smmuv3 vevent;
450 - } buf;
451 - enum iommu_veventq_type type = IOMMU_VEVENTQ_TYPE_ARM_SMMUV3;
452 - uint32_t id = veventq->veventq_id;
446 uint32_t last_seq = veventq->last_event_seq;
447 + uint32_t id = veventq->veventq_id;
448 + struct iommufd_vevent_header *hdr;
449 ssize_t bytes;
450
456 - bytes = read(veventq->veventq_fd, &buf, sizeof(buf));
451 + bytes = read(veventq->veventq_fd, buf, size);
452 if (bytes <= 0) {
453 if (errno == EAGAIN || errno == EINTR) {
459 - return;
454 + return true;
455 }
461 - error_report_once("vEVENTQ(type %u id %u): read failed (%m)", type, id);
462 - return;
456 + error_setg(errp, "vEVENTQ(type %u id %u): read failed (%m)", type, id);
457 + return false;
458 }
464 -
465 - if (bytes == sizeof(buf.hdr) &&
466 - (buf.hdr.flags & IOMMU_VEVENTQ_FLAG_LOST_EVENTS)) {
467 - error_report_once("vEVENTQ(type %u id %u): overflowed", type, id);
459 + hdr = (struct iommufd_vevent_header *)buf;
460 + if (bytes == sizeof(*hdr) &&
461 + (hdr->flags & IOMMU_VEVENTQ_FLAG_LOST_EVENTS)) {
462 + error_setg(errp, "vEVENTQ(type %u id %u): overflowed", type, id);
463 veventq->event_start = false;
469 - return;
464 + return false;
465 }
471 - if (bytes < sizeof(buf)) {
472 - error_report_once("vEVENTQ(type %u id %u): short read(%zd/%zd bytes)",
473 - type, id, bytes, sizeof(buf));
474 - return;
466 + if (bytes < size) {
467 + error_setg(errp, "vEVENTQ(type %u id %u): short read(%zd/%zd bytes)",
468 + type, id, bytes, size);
469 + return false;
470 }
476 -
471 /* Check sequence in hdr for lost events if any */
478 - if (veventq->event_start && (buf.hdr.sequence - last_seq != 1)) {
479 - error_report_once("vEVENTQ(type %u id %u): lost %u event(s)",
480 - type, id, buf.hdr.sequence - last_seq - 1);
472 + if (veventq->event_start && (hdr->sequence - last_seq != 1)) {
473 + warn_report("vEVENTQ(type %u id %u): lost %u event(s)",
474 + type, id, hdr->sequence - last_seq - 1);
475 }
482 - veventq->last_event_seq = buf.hdr.sequence;
476 + veventq->last_event_seq = hdr->sequence;
477 veventq->event_start = true;
478 + return true;
479 +}
480 +
481 +static void smmuv3_accel_event_read(void *opaque)
482 +{
483 + SMMUv3State *s = opaque;
484 + IOMMUFDVeventq *veventq = s->s_accel->veventq;
485 + struct {
486 + struct iommufd_vevent_header hdr;
487 + struct iommu_vevent_arm_smmuv3 vevent;
488 + } buf;
489 + Error *local_err = NULL;
490 +
491 + if (!smmuv3_accel_event_read_validate(veventq,
492 + IOMMU_VEVENTQ_TYPE_ARM_SMMUV3, &buf,
493 + sizeof(buf), &local_err)) {
494 + warn_report_err_once(local_err);
495 + return;
496 + }
497 smmuv3_propagate_event(s, (Evt *)&buf.vevent);
498 }
499
hw/arm/smmuv3-accel.h
+2
@@ -87,6 +87,8 @@ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev,
87 Error **errp);
88 void smmuv3_accel_idr_override(SMMUv3State *s);
89 bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp);
90 +bool smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
91 + void *buf, size_t size, Error **errp);
92 void smmuv3_accel_reset(SMMUv3State *s);
93
94 #endif /* HW_ARM_SMMUV3_ACCEL_H */