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