On Wed, Dec 10, 2025 at 01:37:32PM +0000, Shameer Kolothum wrote:
> +static void tegra241_cmdqv_event_read(void *opaque)
> +{
> +    Tegra241CMDQV *cmdqv = opaque;
> +    struct {
> +        struct iommufd_vevent_header hdr;
> +        struct iommu_vevent_tegra241_cmdqv vevent;
> +    } buf;
> +    ssize_t readsz = sizeof(buf);
> +    uint32_t last_seq = cmdqv->last_event_seq;
> +    ssize_t bytes;
> +
> +    bytes = read(cmdqv->veventq->veventq_fd, &buf, readsz);
> +    if (bytes <= 0) {
> +        if (errno == EAGAIN || errno == EINTR) {
> +            return;
> +        }
> +        error_report("Tegra241 CMDQV: vEVENTQ: read failed (%s)",
> +                     strerror(errno));
> +        return;
> +    }
> +
> +    if (bytes < readsz) {
> +        error_report("Tegra241 CMDQV: vEVENTQ: incomplete read (%zd/%zd 
> bytes)",
> +                     bytes, readsz);
> +        return;
> +    }
> +
> +    if (buf.hdr.flags & IOMMU_VEVENTQ_FLAG_LOST_EVENTS) {
> +        error_report("Tegra241 CMDQV: vEVENTQ has lost events");
> +        return;
> +    }
> +
> +    /* Check sequence in hdr for lost events if any */
> +    if (cmdqv->event_start) {
> +        uint32_t expected = (last_seq == INT_MAX) ? 0 : last_seq + 1;
> +
> +        if (buf.hdr.sequence != expected) {
> +            uint32_t delta;
> +
> +            if (buf.hdr.sequence >= last_seq) {
> +                delta = buf.hdr.sequence - last_seq;
> +            } else {
> +                /* Handle wraparound from INT_MAX */
> +                delta = (INT_MAX - last_seq) + buf.hdr.sequence + 1;
> +            }
> +            error_report("Tegra241 CMDQV: vEVENTQ: detected lost %u 
> event(s)",
> +                         delta - 1);
> +        }
> +    }

This part looks quite similar to SMMUv3's vEVENTQ function. Maybe
add a vEVENTQ helper in the iommufd backend?

Nicolin

Reply via email to