diff --git a/drivers/virt/gunyah/vm_mgr_mem.c b/drivers/virt/gunyah/vm_mgr_mem.c index a19c5c98065f..a3d31385715e 100644 --- a/drivers/virt/gunyah/vm_mgr_mem.c +++ b/drivers/virt/gunyah/vm_mgr_mem.c @@ -473,7 +473,7 @@ int gunyah_gup_share_parcel(struct gunyah_vm *ghvm, struct gunyah_rm_mem_parcel u16 vmid; struct folio *folio; unsigned int gup_flags; - unsigned long i, offset; + unsigned long i, offset, entries; parcel->mem_handle = GUNYAH_MEM_HANDLE_INVAL; @@ -548,6 +548,7 @@ int gunyah_gup_share_parcel(struct gunyah_vm *ghvm, struct gunyah_rm_mem_parcel parcel->acl_entries[1].perms = GUNYAH_RM_ACL_R | GUNYAH_RM_ACL_W | GUNYAH_RM_ACL_X; } + /* overallocate & assume no large folios */ parcel->mem_entries = kcalloc(pinned, sizeof(parcel->mem_entries[0]), GFP_KERNEL_ACCOUNT); if (!parcel->mem_entries) { @@ -559,17 +560,20 @@ int gunyah_gup_share_parcel(struct gunyah_vm *ghvm, struct gunyah_rm_mem_parcel parcel->mem_entries[0].size = cpu_to_le64(folio_size(folio)); parcel->mem_entries[0].phys_addr = cpu_to_le64(PFN_PHYS(folio_pfn(folio))); - for (i = 1; i < pinned; i++) { + for (i = 1, entries = 1; i < pinned; i++) { folio = page_folio(pages[i]); if (pages[i] == folio_page(folio, 0)) { - parcel->mem_entries[i].size = cpu_to_le64(folio_size(folio)); - parcel->mem_entries[i].phys_addr = cpu_to_le64(PFN_PHYS(folio_pfn(folio))); + parcel->mem_entries[entries].size = + cpu_to_le64(folio_size(folio)); + parcel->mem_entries[entries].phys_addr = + cpu_to_le64(PFN_PHYS(folio_pfn(folio))); + entries++; } else { unpin_user_page(pages[i]); account_locked_vm(current->mm, 1, false); } } - parcel->n_mem_entries = i; + parcel->n_mem_entries = entries; ret = gunyah_rm_mem_share(ghvm->rm, parcel); goto free_pages;