I is subtle so there is a chance that I have read the code incorrectly. Risking that, I would like to ask if the orders that args_regs_reset() and vcpu_on() are called is different between primary vs secondary VMs, and if they are, why they should be different.
I didn't read the code deeply so vaguely understand what args_regs_reset() and vcpu_on() do. My current understanding is as follows.
- arch_regs_reset() is clearing registers to a desired initiali state
- vcpu_on() calls arch_regs_set_pc_arg() then change vcpu's state to READY
By looking at the code, at least between arch_regs_reset() should be called before arch_regs_set_pc_arg(). Thus, the correct order between arch_regs_reset() and vcpu_on() appears arch_regs_reset() -> vcpu_on().
That is certainly the case for secondary VMs. For initializing vcPU registers, secondary VMs use vcpu_secondary_reset(). This function calls arch_regs_reset() and then vcpu_on() if vcpu was off before.
The situation is more complicated for primary VMs. For vCPU[0], vcpu_on() is called at the end of load_primary(). Then, arch_regs_reset() is called before returning from cpu_main(). For other vCPUs, vcpu_on() is called by cpu_on() when processing PSCI_CPU_ON in psci_primary_vm_handlder(). In later in the same code, an smc call is made, asking TrustZone to power on the cpu and start it at cpu_entry. Therefore, the cpu eventually calls args_regs_reset() for its corresponding vCPU at the end of cpu_main().
Effectively, for primary VMs, vcpu_on() is called before arch_regs_reset() is called. So, the orderings between primary and secondary VMs are different. I am wondering if (1) I read the code correctly and (2) if so, what's the reasoning behind it.