On 2017-09-04 12:10, Jan Kiszka wrote:
> On 2017-09-04 11:53, Lokesh Vutla wrote:
>>
>>
>> On Monday 04 September 2017 03:12 PM, Jan Kiszka wrote:
>>> On 2017-09-04 11:34, Lokesh Vutla wrote:
>>>>
>>>>
>>>> On Monday 04 September 2017 02:30 PM, Jan Kiszka wrote:
>>>>> On 2017-08-30 21:00, 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 | 13 +++++++++++--
>>>>>>  1 file changed, 11 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/hypervisor/arch/arm-common/irqchip.c 
>>>>>> b/hypervisor/arch/arm-common/irqchip.c
>>>>>> index 2019342..dc892ea 100644
>>>>>> --- a/hypervisor/arch/arm-common/irqchip.c
>>>>>> +++ b/hypervisor/arch/arm-common/irqchip.c
>>>>>> @@ -131,6 +131,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;
>>>>>> +        u64 mpidr, clst, sgi_clst, core;
>>>>>>          unsigned int cpu;
>>>>>>  
>>>>>>          if (sgi->routing_mode == 2) {
>>>>>> @@ -139,14 +140,22 @@ 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);
>>>>>>  
>>>>>>                  for_each_cpu(cpu, cpu_data->cell->cpu_set) {
>>>>>> +                        mpidr = per_cpu(cpu)->mpidr;
>>>>>> +                        clst = mpidr & ~0xffUL;
>>>>>> +                        core = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>>>>>> +
>>>>>>                          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))
>>>>>
>>>>> What if core >= 16? core can be up to 255, and that's > bitsof(targets).
>>>>
>>>> With affinity routing, core cannot be > 16, as ICC_SGI1R_EL1 register
>>>> has target list bits [0:15].
>>>
>>> That alone doesn't restrict the value of Aff0 in MPIDR, does it?
>>
>> hmm..not sure. But even if a value > 16 comes, then how can an SGI be
>> triggered?
> 
> That's indeed what I was wondering as well. However, the spec just says:
> "This restricts a system to sending targeted SGIs to PEs with an
> affinity 0 number that is less than 16."

Actually, to make our life both simple and safe, we could detect such
cases during init and reject to start Jailhouse on platforms with more
than 16 cores. Then we don't need to test during runtime.

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