|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 11/16] xen/riscv: aplic_init() implementation
On 19.05.2025 18:09, Oleksii Kurochko wrote:
> On 5/15/25 11:06 AM, Jan Beulich wrote:
>>> + /* Set interrupt type and default priority for all interrupts */
>>> + for ( i = 1; i <= aplic_info.num_irqs; i++ )
>>> + {
>>> + writel(0, &aplic.regs->sourcecfg[i - 1]);
>> What guarantees the loop to not run past the array's size?
>
> riscv,aplic binding:
>
> https://github.com/torvalds/linux/blob/a5806cd506af5a7c19bcd596e4708b5c464bfd21/Documentation/devicetree/bindings/interrupt-controller/riscv%2Caplic.yaml#L57
> Should I add an ASSERT() or panic() at the moment where num_irqs are
> initialized to double check a binding?
I may be paranoid, but I don't really trust anything coming from DT. Hence
yes, just like you do in various other situations, perhaps best to panic()
if too large a value is read. Or, if that's feasible, simply cap at the
compiled-in count.
>>> +static int __init cf_check aplic_init(void)
>>> +{
>>> + int rc;
>>> + dt_phandle imsic_phandle;
>>> + uint32_t irq_range[num_possible_cpus() * 2];
>> Are you going to have enough stack space when num_possible_cpus() is pretty
>> large?
>
> When num_possible_cpus() will be pretty large then it will better to allocate
> irq_range[]
> dynamically.
>
> Does it make sense to re-write now?
Well, this kind of runtime-sized stack allocation should go away anyway.
Plus you don't want to leave a trap like this in the code. Whether using
dynamic allocation is the choice to address those concerns you'll need
to judge.
>>> + const struct dt_device_node *node = aplic_info.node;
>>> +
>>> + /* Check for associated imsic node */
>>> + rc = dt_property_read_u32(node, "msi-parent", &imsic_phandle);
>>> + if ( !rc )
>>> + panic("%s: IDC mode not supported\n", node->full_name);
>>> +
>>> + imsic_node = dt_find_node_by_phandle(imsic_phandle);
>>> + if ( !imsic_node )
>>> + panic("%s: unable to find IMSIC node\n", node->full_name);
>>> +
>>> + rc = dt_property_read_u32_array(imsic_node, "interrupts-extended",
>>> + irq_range, ARRAY_SIZE(irq_range));
>>> + if ( rc )
>>> + panic("%s: unable to find interrupt-extended in %s node\n",
>>> + __func__, imsic_node->full_name);
>>> +
>>> + if ( irq_range[1] == IRQ_M_EXT )
>> How do you know the array has had 2 or ...
>>
>>> + /* Machine mode imsic node, ignore this aplic node */
>>> + return 0;
>>> +
>>> + for ( unsigned int i = 0; i < ARRAY_SIZE(irq_range); i += 2 )
>>> + {
>>> + if ( irq_range[i + 1] != irq_range[1] )
>>> + panic("%s: mode[%d] != %d\n", __func__, i + 1, irq_range[1]);
>>> + }
>> ... or even all of the slots populated? Anything not populated by the DT
>> function will still have the stack contents that had been left by earlier
>> call chains. (The loop also makes little sense to start from 0.)
>
> Do you mean I asked allocated irq_range[8*2] but DT node has only
> irq_range[4*2]?
> Then it will be really an issue. And out-of-range access will occur in
> dt_property_read_variable_u32_array(). I need another way to check then...
I described the opposite situation (not the full array being populated),
but yes - both are a problem.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |