• G
    riscv: fix the IPI missing issue in nommu mode · 3384b043
    Greentime Hu 提交于
    This patch fixes the IPI(inner processor interrupt) missing issue. It
    failed because it used hartid_mask to iterate for_each_cpu(), however the
    cpu_mask and hartid_mask may not be always the same. It will never send the
    IPI to hartid 4 because it will be skipped in for_each_cpu loop in my case.
    
    We can reproduce this case in Qemu sifive_u machine by this command.
    qemu-system-riscv64 -nographic -smp 5 -m 1G -M sifive_u -kernel \
    arch/riscv/boot/loader
    
    It will hang in csd_lock_wait(csd) because the csd_unlock(csd) is not
    called. It is not called because hartid 4 doesn't receive the IPI to
    release this lock. The caller hart doesn't send the IPI to hartid 4 is
    because of hartid 4 is skipped in for_each_cpu(). It will be skipped is
    because "(cpu) < nr_cpu_ids" is not true. The hartid is 4 and nr_cpu_ids
    is 4. Therefore it should use cpumask in for_each_cpu() instead of
    hartid_mask.
    
            /* Send a message to all CPUs in the map */
            arch_send_call_function_ipi_mask(cfd->cpumask_ipi);
    
            if (wait) {
                    for_each_cpu(cpu, cfd->cpumask) {
                            call_single_data_t *csd;
    			csd = per_cpu_ptr(cfd->csd, cpu);
                            csd_lock_wait(csd);
                    }
            }
    
            for ((cpu) = -1;                                \
                    (cpu) = cpumask_next((cpu), (mask)),    \
                    (cpu) < nr_cpu_ids;)
    
    It could boot to login console after this patch applied.
    
    Fixes: b2d36b5668f6 ("riscv: provide native clint access for M-mode")
    Signed-off-by: NGreentime Hu <greentime.hu@sifive.com>
    Reviewed-by: NPalmer Dabbelt <palmerdabbelt@google.com>
    Signed-off-by: NPalmer Dabbelt <palmerdabbelt@google.com>
    3384b043
clint.h 983 字节