Quoting Kalesh Singh (2022-03-07 10:48:59) > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c > index bc2aba953299..ccb2847ee2f4 100644 > --- a/arch/arm64/kvm/mmu.c > +++ b/arch/arm64/kvm/mmu.c > @@ -457,22 +457,17 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot) > return 0; > } > > -static int __create_hyp_private_mapping(phys_addr_t phys_addr, size_t size, > - unsigned long *haddr, > - enum kvm_pgtable_prot prot) > + > +/** > + * hyp_alloc_private_va_range - Allocates a private VA range. > + * @size: The size of the VA range to reserve. > + * > + * The private VA range is allocated below io_map_base and > + * aligned based on the order of @size. Add what it returns? Return: Start address of allocated VA range or some error value... (I don't understand this part). It may also be a good idea to write out what VA is in the description: The private virtual address (VA) range is allocated below io_map_base > + */ > +unsigned long hyp_alloc_private_va_range(size_t size) > { > unsigned long base; > - int ret = 0; > - > - if (!kvm_host_owns_hyp_mappings()) { > - base = kvm_call_hyp_nvhe(__pkvm_create_private_mapping, > - phys_addr, size, prot); > - if (IS_ERR_OR_NULL((void *)base)) > - return PTR_ERR((void *)base); > - *haddr = base; > - > - return 0; > - } > > mutex_lock(&kvm_hyp_pgd_mutex); > > @@ -484,29 +479,53 @@ static int __create_hyp_private_mapping(phys_addr_t phys_addr, size_t size, > * > * The allocated size is always a multiple of PAGE_SIZE. > */ > - size = PAGE_ALIGN(size + offset_in_page(phys_addr)); > - base = io_map_base - size; > + base = io_map_base - PAGE_ALIGN(size); > + > + /* Align the allocation based on the order of its size */ > + base = ALIGN_DOWN(base, PAGE_SIZE << get_order(size)); > > /* > * Verify that BIT(VA_BITS - 1) hasn't been flipped by > * allocating the new area, as it would indicate we've > * overflowed the idmap/IO address range. > */ > - if ((base ^ io_map_base) & BIT(VA_BITS - 1)) > - ret = -ENOMEM; > + if (!base || (base ^ io_map_base) & BIT(VA_BITS - 1)) > + base = (unsigned long)ERR_PTR(-ENOMEM); It looks odd to use an error pointer casted to unsigned long to return from an address allocation function. Why not pass a pointer for base like the function was written before and return an int from this function with 0 for success and negative error value? Otherwise some sort of define should made like DMA_MAPPING_ERROR and that can be used to indicate to the caller that the allocation failed, or a simple zero may work? > else > io_map_base = base; > > mutex_unlock(&kvm_hyp_pgd_mutex); > > - if (ret) > - goto out; > + return base; > +} > + > +static int __create_hyp_private_mapping(phys_addr_t phys_addr, size_t size, > + unsigned long *haddr, > + enum kvm_pgtable_prot prot) > +{ > + unsigned long addr; > + int ret = 0; > + > + if (!kvm_host_owns_hyp_mappings()) { > + addr = kvm_call_hyp_nvhe(__pkvm_create_private_mapping, > + phys_addr, size, prot); > + if (IS_ERR((void *)addr)) IS_ERR_VALUE()? > + return PTR_ERR((void *)addr); > + *haddr = addr; > + > + return 0; > + } > + > + size += offset_in_page(phys_addr); > + addr = hyp_alloc_private_va_range(size); > + if (IS_ERR((void *)addr)) IS_ERR_VALUE()? > + return PTR_ERR((void *)addr); > > - ret = __create_hyp_mappings(base, size, phys_addr, prot); > + ret = __create_hyp_mappings(addr, size, phys_addr, prot); > if (ret) > goto out; > > - *haddr = base + offset_in_page(phys_addr); > + *haddr = addr + offset_in_page(phys_addr); > out: > return ret; Would be simpler to remove the goto, or return early. if (!ret) *haddr = addr + offset_in_page(phys_addr); return ret; > } _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm