From 3b4904d52f279b267c1daf19fd653667be33e40c Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Mon, 8 Jul 2024 11:34:23 -0700 Subject: [PATCH] ANDROID: virt: gunyah: Correct n_mem_entries calculation in gunyah_gup_share_parcel gunyah_gup_share_parcel incorrectly calculates n_mem_entries and places items into the mem_entries array. To save number of bytes sent to RM, we describe only folios -- not individual pages. We incorrectly filled the mem_entries array with some entries as 0's. Track insertion into the mem_entries array with new indexer: entries. Bug: 358605784 Fixes: 296cceed0844 ("ANDROID: virt: gunyah: Add gup based demand paging support") Change-Id: I4738874579136a834bed86daba6d70e469512656 Signed-off-by: Elliot Berman Signed-off-by: Elliot Berman --- drivers/virt/gunyah/vm_mgr_mem.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) 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;