qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v7 14/17] vfio-user: handle PCI BAR accesses


From: Stefan Hajnoczi
Subject: Re: [PATCH v7 14/17] vfio-user: handle PCI BAR accesses
Date: Wed, 30 Mar 2022 17:06:05 +0100

On Wed, Mar 30, 2022 at 02:46:20PM +0000, Jag Raman wrote:
> 
> 
> > On Mar 30, 2022, at 6:05 AM, Stefan Hajnoczi <stefanha@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 <stefanha@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.

Okay, I think we're on the same page. I wanted to be make sure that if
(memory_access_is_direct()) will be moved inside the loop.

Stefan

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]