> > @@ -419,17 +446,52 @@ static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi) > > struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel) > > { > > struct hv_ring_buffer_info *rbi = &channel->inbound; > > - struct vmpacket_descriptor *desc; > > + struct vmpacket_descriptor *desc, *desc_copy; > > + u32 bytes_avail, pkt_len, pkt_offset; > > > > - hv_debug_delay_test(channel, MESSAGE_DELAY); > > - if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor)) > > + desc = hv_pkt_iter_first_raw(channel); > > + if (!desc) > > return NULL; > > > > - desc = hv_get_ring_buffer(rbi) + rbi->priv_read_index; > > - if (desc) > > - prefetch((char *)desc + (desc->len8 << 3)); > > + bytes_avail = hv_pkt_iter_avail(rbi); > > + > > + /* > > + * Ensure the compiler does not use references to incoming Hyper-V values (which > > + * could change at any moment) when reading local variables later in the code > > + */ > > + pkt_len = READ_ONCE(desc->len8) << 3; > > + pkt_offset = READ_ONCE(desc->offset8) << 3; > > + > > + /* > > + * If pkt_len is invalid, set it to the smaller of hv_pkt_iter_avail() and > > + * rbi->pkt_buffer_size > > + */ > > + if (rbi->pkt_buffer_size < bytes_avail) > > + bytes_avail = rbi->pkt_buffer_size; > > I think the above could be combined with the earlier call to hv_pkt_iter_avail(), > and more logically expressed as: > > bytes_avail = min(rbi->pkt_buffer_size, hv_pkt_iter_avail(rbi)); > > > This is a minor nit. Everything else in this patch looks good to me. Thanks for the feedback, Michael; I'll send v3 to address it shortly. Andrea