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