On Tue Aug 11, 2026 at 6:16 PM CDT, Jonas Karlman wrote:
> lmb_alloc_addr() is documented to return -EINVAL when the requested
> memory region is not part of the LMB memory map. However, -EINVAL is
> also used to e.g. indicate that a NULL pointer is passed as the addr
> parameter or when the requested memory region partially overlaps an
> existing region.
>
> Change lmb_alloc_addr() to return -EFAULT when the requested memory
> region is not part of the LMB memory map to make the type of error known
> to callers. Also extend unit tests to validate that the return code has
> stay the same when the requested memory region partially overlaps.
>
> No caller of lmb_alloc_addr() is checking what type of error code is
> returned, so this change has no intended behavior change.
>
> Signed-off-by: Jonas Karlman <[email protected]>
> ---
>  include/lmb.h  |  2 +-
>  lib/lmb.c      |  4 +++-
>  test/lib/lmb.c | 10 +++++++++-
>  3 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/include/lmb.h b/include/lmb.h
> index ed472e9ef2e1..028dabb19e86 100644
> --- a/include/lmb.h
> +++ b/include/lmb.h
> @@ -124,7 +124,7 @@ struct lmb {
>   * Return: 0 on success, -ve value on failure
>   *
>   * When the allocation is of type @LMB_MEM_ALLOC_ADDR, the return value can
> - * be -EINVAL if the requested memory region is not part of the LMB memory
> + * be -EFAULT if the requested memory region is not part of the LMB memory
>   * map, and -EEXIST if the requested region is already allocated.
>   */

This doc string may need to be updated a little more to indicate that -EINVAL is
now used to report partial overlaps.

Reviewed-by: Randolph Sapp <[email protected]>

>  int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr,
> diff --git a/lib/lmb.c b/lib/lmb.c
> index 77440a48486c..f7c2e826d067 100644
> --- a/lib/lmb.c
> +++ b/lib/lmb.c
> @@ -752,9 +752,11 @@ static int _lmb_alloc_addr(phys_addr_t base, phys_size_t 
> size, u32 flags)
>                                     base + size - 1, 1))
>                       /* ok, reserve the memory */
>                       return lmb_reserve(base, size, flags);
> +
> +             return -EINVAL;
>       }
>  
> -     return -EINVAL;
> +     return -EFAULT;
>  }
>  
>  int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr,
> diff --git a/test/lib/lmb.c b/test/lib/lmb.c
> index b6259bef4426..b93b903f99f9 100644
> --- a/test/lib/lmb.c
> +++ b/test/lib/lmb.c
> @@ -779,11 +779,19 @@ static int test_alloc_addr(struct unit_test_state *uts, 
> const phys_addr_t ram)
>       /* check that allocating outside memory fails */
>       if (ram_end != 0) {
>               ret = lmb_alloc_addr(ram_end, 1, LMB_NONE);
> +             ut_asserteq(ret, -EFAULT);
> +             ret = lmb_alloc_addr(ram_end - 1, 2, LMB_NOMAP);
> +             ut_asserteq(ret, -EINVAL);
> +             ret = lmb_alloc_addr(ram_end - 1, 2, LMB_NOOVERWRITE);
>               ut_asserteq(ret, -EINVAL);
>       }
>       if (ram != 0) {
>               ret = lmb_alloc_addr(ram - 1, 1, LMB_NONE);
> -             ut_asserteq(ret, -EINVAL);
> +             ut_asserteq(ret, -EFAULT);
> +             ret = lmb_alloc_addr(ram - 1, 2, LMB_NOMAP);
> +             ut_asserteq(ret, -EEXIST);
> +             ret = lmb_alloc_addr(ram - 1, 2, LMB_NOOVERWRITE);
> +             ut_asserteq(ret, -EEXIST);
>       }
>  
>       lmb_pop(&store);

Reply via email to