[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH V6 19/27] vfio-pci: cpr part 1 (fd and dma)
From: |
Steven Sistare |
Subject: |
Re: [PATCH V6 19/27] vfio-pci: cpr part 1 (fd and dma) |
Date: |
Tue, 30 Nov 2021 11:11:55 -0500 |
User-agent: |
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.3.2 |
On 11/10/2021 2:48 AM, Zheng Chuan wrote:
>
> Hi, steve
>
> On 2021/8/11 1:06, Alex Williamson wrote:
>> On Fri, 6 Aug 2021 14:43:53 -0700
>> Steve Sistare <steven.sistare@oracle.com> wrote:
>> [...]
>>> +static int
>>> +vfio_region_remap(MemoryRegionSection *section, void *handle, Error **errp)
>>> +{
>>> + MemoryRegion *mr = section->mr;
>>> + VFIOContainer *container = handle;
>>> + const char *name = memory_region_name(mr);
>>> + ram_addr_t size = int128_get64(section->size);
>>> + hwaddr offset, iova, roundup;
>>> + void *vaddr;
>>> +
>>> + if (vfio_listener_skipped_section(section) ||
>>> memory_region_is_iommu(mr)) {
>>> + return 0;
>>> + }
>>> +
>>> + offset = section->offset_within_address_space;
>>> + iova = REAL_HOST_PAGE_ALIGN(offset);
> We should not do remap if it shares on host page with other structures.
> I think a judgement like int128_ge((int128_make64(iova), llend)) in
> vfio_listener_region_add() should be also added here to check it,
> otherwise it will remap no-exit dma which causes the live update failure.
> diff --git a/hw/vfio/cpr.c b/hw/vfio/cpr.c
> index 0981d31..d231841 100644
> --- a/hw/vfio/cpr.c
> +++ b/hw/vfio/cpr.c
> @@ -58,13 +58,21 @@ vfio_region_remap(MemoryRegionSection *section, void
> *handle, Error **errp)
> ram_addr_t size = int128_get64(section->size);
> hwaddr offset, iova, roundup;
> void *vaddr;
> -
> + Int128 llend;
> +
> if (vfio_listener_skipped_section(section) ||
> memory_region_is_iommu(mr)) {
> return 0;
> }
>
> offset = section->offset_within_address_space;
> iova = REAL_HOST_PAGE_ALIGN(offset);
> + llend = int128_make64(section->offset_within_address_space);
> + llend = int128_add(llend, section->size);
> + llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask));
> + if (int128_ge(int128_make64(iova), llend)) {
> + return 0;
> + }
> +
> roundup = iova - offset;
> size -= roundup;
> size = REAL_HOST_PAGE_ALIGN(size);
>
>>> + roundup = iova - offset;
>>> + size -= roundup;
>>> + size = REAL_HOST_PAGE_ALIGN(size);
>>> + vaddr = memory_region_get_ram_ptr(mr) +
>>> + section->offset_within_region + roundup;
>>> +
>>> + trace_vfio_region_remap(name, container->fd, iova, iova + size - 1,
>>> vaddr);
>>> + return vfio_dma_map_vaddr(container, iova, size, vaddr, errp);
>>> +}
Thank you Zheng. I intended to implement the logic you suggest, using 64-bit
arithmetic,
but I botched it. This should do the trick:
diff --git a/hw/vfio/cpr.c b/hw/vfio/cpr.c
index df334d9..bbdeaea 100644
--- a/hw/vfio/cpr.c
+++ b/hw/vfio/cpr.c
@@ -66,8 +66,8 @@ vfio_region_remap(MemoryRegionSection *section, void *handle,
offset = section->offset_within_address_space;
iova = REAL_HOST_PAGE_ALIGN(offset);
roundup = iova - offset;
- size -= roundup;
- size = REAL_HOST_PAGE_ALIGN(size);
+ size -= roundup; /* adjust for starting alignment */
+ size &= qemu_real_host_page_mask; /* adjust for ending alignment */
end = iova + size;
if (iova >= end) {
return 0;
- Steve