|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XEN v5 08/10] xen/arm: domain_build: Check if the address fits the range of physical address
Hi Ayan,
On 13/04/2023 19:37, Ayan Kumar Halder wrote:
>
>
> handle_pci_range() and map_range_to_domain() take addr and len as uint64_t
> parameters. Then frame numbers are obtained from addr and len by right
> shifting
> with PAGE_SHIFT. The page frame numbers are saved using unsigned long.
Maybe better to say "expressed" rather than "saved"
>
> Now if 64-bit >> PAGE_SHIFT, the result will have 52-bits as valid. On a
> 32-bit
> system, 'unsigned long' is 32-bits. Thus, there is a potential loss of value
> when the result is stored as 'unsigned long'.
>
> To mitigate this issue, we check if the starting and end address can be
> contained within the range of physical address supported on the system. If
> not,
> then an appropriate error is returned.
>
> Also, the end address is computed once and used when required. And replaced
> u64
> with uint64_t.
>
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx>
> ---
>
> Changes from :-
> v1...v4 - NA. New patch introduced in v5.
>
> xen/arch/arm/domain_build.c | 30 +++++++++++++++++++++++-------
> 1 file changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 7d28b75517..b98ee506a8 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1637,15 +1637,23 @@ out:
> }
>
> static int __init handle_pci_range(const struct dt_device_node *dev,
> - u64 addr, u64 len, void *data)
> + uint64_t addr, uint64_t len, void *data)
> {
> struct rangeset *mem_holes = data;
> paddr_t start, end;
> int res;
> + uint64_t end_addr = addr + len - 1;
> +
> + if ( addr != (paddr_t)addr || end_addr != (paddr_t)end_addr )
> + {
> + printk(XENLOG_ERR "addr (0x%"PRIx64") or end_addr (0x%"PRIx64")
> exceeds the maximum allowed width (%d bits) for physical address\n",
I don't think it is wise to print variable names (end_addr) to the user. Better
would be to say explicitly: start, end address.
Also to make the message shorter you could write: ... exceeds the maximum
allowed PA width (%u bits)
> + addr, end_addr, CONFIG_PADDR_BITS);
Why CONFIG_PADDR_BITS if you already introduced PADDR_BITS macro
> + return -ERANGE;
> + }
>
> start = addr & PAGE_MASK;
> - end = PAGE_ALIGN(addr + len);
> - res = rangeset_remove_range(mem_holes, PFN_DOWN(start), PFN_DOWN(end -
> 1));
> + end = PAGE_ALIGN(end_addr);
> + res = rangeset_remove_range(mem_holes, PFN_DOWN(start), PFN_DOWN(end));
I doubt PFN_DOWN(end) is the same as PFN_DOWN(end - 1), so I think you should
keep the behavior as it was
> if ( res )
> {
> printk(XENLOG_ERR "Failed to remove: %#"PRIpaddr"->%#"PRIpaddr"\n",
> @@ -2330,11 +2338,19 @@ static int __init map_dt_irq_to_domain(const struct
> dt_device_node *dev,
> }
>
> int __init map_range_to_domain(const struct dt_device_node *dev,
> - u64 addr, u64 len, void *data)
> + uint64_t addr, uint64_t len, void *data)
You changed u64 to uint64_t in a definition but not in a prototype. Please fix.
> {
> struct map_range_data *mr_data = data;
> struct domain *d = mr_data->d;
> int res;
> + uint64_t end_addr = addr + len - 1;
> +
> + if ( addr != (paddr_t)addr || end_addr != (paddr_t)end_addr )
> + {
> + printk(XENLOG_ERR "addr (0x%"PRIx64") or end_addr (0x%"PRIx64")
> exceeds the maximum allowed width (%d bits) for physical address\n",
> + addr, end_addr, CONFIG_PADDR_BITS);
please see the remarks above about this code
> + return -ERANGE;
> + }
>
> /*
> * reserved-memory regions are RAM carved out for a special purpose.
> @@ -2345,13 +2361,13 @@ int __init map_range_to_domain(const struct
> dt_device_node *dev,
> strlen("/reserved-memory/")) != 0 )
> {
> res = iomem_permit_access(d, paddr_to_pfn(addr),
> - paddr_to_pfn(PAGE_ALIGN(addr + len - 1)));
> + paddr_to_pfn(PAGE_ALIGN(end_addr)));
> if ( res )
> {
> printk(XENLOG_ERR "Unable to permit to dom%d access to"
> " 0x%"PRIx64" - 0x%"PRIx64"\n",
> d->domain_id,
> - addr & PAGE_MASK, PAGE_ALIGN(addr + len) - 1);
> + addr & PAGE_MASK, PAGE_ALIGN(end_addr) - 1);
> return res;
> }
> }
> @@ -2368,7 +2384,7 @@ int __init map_range_to_domain(const struct
> dt_device_node *dev,
> {
> printk(XENLOG_ERR "Unable to map 0x%"PRIx64
> " - 0x%"PRIx64" in domain %d\n",
> - addr & PAGE_MASK, PAGE_ALIGN(addr + len) - 1,
> + addr & PAGE_MASK, PAGE_ALIGN(end_addr) - 1,
> d->domain_id);
> return res;
> }
> --
> 2.17.1
>
>
~Michal
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |