> On Mar 30, 2022, at 6:05 AM, Stefan Hajnoczi <stefa...@redhat.com> wrote: > > On Tue, Mar 29, 2022 at 03:51:17PM +0000, Jag Raman wrote: >> >> >>> On Mar 29, 2022, at 8:50 AM, Stefan Hajnoczi <stefa...@redhat.com> wrote: >>> >>> On Fri, Mar 25, 2022 at 03:19:43PM -0400, Jagannathan Raman wrote: >>>> @@ -324,6 +325,170 @@ static void dma_unregister(vfu_ctx_t *vfu_ctx, >>>> vfu_dma_info_t *info) >>>> trace_vfu_dma_unregister((uint64_t)info->iova.iov_base); >>>> } >>>> >>>> +static size_t vfu_object_bar_rw(PCIDevice *pci_dev, int pci_bar, >>>> + hwaddr offset, char * const buf, >>>> + hwaddr len, const bool is_write) >>>> +{ >>>> + uint8_t *ptr = (uint8_t *)buf; >>>> + uint8_t *ram_ptr = NULL; >>>> + bool release_lock = false; >>>> + MemoryRegionSection section = { 0 }; >>>> + MemoryRegion *mr = NULL; >>>> + int access_size; >>>> + hwaddr size = 0; >>>> + MemTxResult result; >>>> + uint64_t val; >>>> + >>>> + section = memory_region_find(pci_dev->io_regions[pci_bar].memory, >>>> + offset, len); >>>> + >>>> + if (!section.mr) { >>>> + return 0; >>>> + } >>>> + >>>> + mr = section.mr; >>>> + offset = section.offset_within_region; >>>> + >>>> + if (is_write && mr->readonly) { >>>> + warn_report("vfu: attempting to write to readonly region in " >>>> + "bar %d - [0x%"PRIx64" - 0x%"PRIx64"]", >>>> + pci_bar, offset, (offset + len)); >>>> + return 0; >>> >>> A mr reference is leaked. The return statement can be replaced with goto >>> exit. >> >> OK. >> >>> >>>> + } >>>> + >>>> + if (memory_access_is_direct(mr, is_write)) { >>>> + /** >>>> + * Some devices expose a PCI expansion ROM, which could be buffer >>>> + * based as compared to other regions which are primarily based on >>>> + * MemoryRegionOps. memory_region_find() would already check >>>> + * for buffer overflow, we don't need to repeat it here. >>>> + */ >>>> + ram_ptr = memory_region_get_ram_ptr(mr); >>>> + >>>> + size = len; >>> >>> This looks like it will access beyond the end of ram_ptr when >>> section.size < len after memory_region_find() returns. >> >> OK - will will handle shorter sections returned by memory_region_find(). >> >>> >>>> + >>>> + if (is_write) { >>>> + memcpy((ram_ptr + offset), buf, size); >>>> + } else { >>>> + memcpy(buf, (ram_ptr + offset), size); >>>> + } >>>> + >>>> + goto exit; >>> >>> What happens when the access spans two adjacent MemoryRegions? I think >>> the while (len > 0) loop is needed even in the memory_access_is_direct() >>> case so we perform the full access instead of truncating it. >> >> OK - this should be covered by the shorter section handling above. > > No, shorter section handling truncates that access. I think the caller > expects all len bytes to be accessed, not just the first few bytes?
Yes, I also think that the caller expects to access all len bytes. I should’ve provided more details - but by shorter section handling I meant iterating over all the sections that make up len bytes. Thank you! -- Jag > > Stefan