On 2017-08-30 12:34, Lokesh Vutla wrote:
> Even though 'struct sgi' already supports for passing affinity levels,
> gic_handle_sgir_write() looks only for target fields and triggers sgis
> to its respective targets. This will fail in case of armv8 with affinity
> routing enabled. So parse all the affinity levels in sgi before sending
> sgi.
> 
> Suggested-by: Nikhil Devshatwar <[email protected]>
> Signed-off-by: Nikhil Devshatwar <[email protected]>
> Signed-off-by: Lokesh Vutla <[email protected]>
> ---
>  hypervisor/arch/arm-common/irqchip.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/hypervisor/arch/arm-common/irqchip.c 
> b/hypervisor/arch/arm-common/irqchip.c
> index 2019342..64c081d 100644
> --- a/hypervisor/arch/arm-common/irqchip.c
> +++ b/hypervisor/arch/arm-common/irqchip.c
> @@ -132,6 +132,7 @@ void gic_handle_sgir_write(struct sgi *sgi, bool 
> virt_input)
>       struct per_cpu *cpu_data = this_cpu_data();
>       unsigned long targets = sgi->targets;
>       unsigned int cpu;
> +     u64 mpidr, clst, sgi_clst, core;

I prefer to sort the variables declaration lines in descending length,
ie. this one should be added one line earlier.

>  
>       if (sgi->routing_mode == 2) {
>               /* Route to the caller itself */
> @@ -139,14 +140,23 @@ void gic_handle_sgir_write(struct sgi *sgi, bool 
> virt_input)
>               sgi->targets = (1 << cpu_data->cpu_id);
>       } else {
>               sgi->targets = 0;
> +             sgi_clst = (u64)sgi->aff3 << MPIDR_LEVEL_SHIFT(3) |
> +                             (u64)sgi->aff2 << MPIDR_LEVEL_SHIFT(2) |
> +                             (u64)sgi->aff1 << MPIDR_LEVEL_SHIFT(1);

Should be aligned on the "(u64)" of the first line.

>  
>               for_each_cpu(cpu, cpu_data->cell->cpu_set) {
> +                     mpidr = per_cpu(cpu)->mpidr;
> +                     clst = mpidr & ~0xffUL;
> +                     core = MPIDR_AFFINITY_LEVEL(mpidr, 0);
> +
> +

One blank line is enough.

>                       if (sgi->routing_mode == 1) {
>                               /* Route to all (cell) CPUs but the caller. */
>                               if (cpu == cpu_data->cpu_id)
>                                       continue;
>                       } else if (virt_input) {
> -                             if (!test_bit(cpu, &targets))
> +                             if (sgi_clst != clst ||
> +                                 !test_bit(core, &targets))
>                                       continue;
>                       } else {
>                               /*
> @@ -161,7 +171,7 @@ void gic_handle_sgir_write(struct sgi *sgi, bool 
> virt_input)
>                       }
>  
>                       irqchip_set_pending(per_cpu(cpu), sgi->id);
> -                     sgi->targets |= (1 << cpu);
> +                     sgi->targets |= (1 << core);
>               }
>       }
>  
> 

Looks much better. Will try to test this on both v7 and v8 soon.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to