Skip to content
  • Peter Maydell's avatar
    817e2db8
    hw/arm/boot: Support setting psci-conduit based on guest EL · 817e2db8
    Peter Maydell authored
    
    
    Currently we expect board code to set the psci-conduit property on
    CPUs and ensure that secondary CPUs are created with the
    start-powered-off property set to false, if the board wishes to use
    QEMU's builtin PSCI emulation.  This worked OK for the virt board
    where we first wanted to use it, because the virt board directly
    creates its CPUs and is in a reasonable position to set those
    properties.  For other boards which model real hardware and use a
    separate SoC object, however, it is more awkward.  Most PSCI-using
    boards just set the psci-conduit board unconditionally.
    
    This was never strictly speaking correct (because you would not be
    able to run EL3 guest firmware that itself provided the PSCI
    interface, as the QEMU implementation would overrule it), but mostly
    worked in practice because for non-PSCI SMC calls QEMU would emulate
    the SMC instruction as normal (by trapping to guest EL3).  However,
    we would like to make our PSCI emulation follow the part of the SMCC
    specification that mandates that SMC calls with unknown function
    identifiers return a failure code, which means that all SMC calls
    will be handled by the PSCI code and the "emulate as normal" path
    will no longer be taken.
    
    We tried to implement that in commit 9fcd15b9
    ("arm: tcg: Adhere to SMCCC 1.3 section 5.2"), but this
    regressed attempts to run EL3 guest code on the affected boards:
     * mcimx6ul-evk, mcimx7d-sabre, orangepi, xlnx-zcu102
     * for the case only of EL3 code loaded via -kernel (and
       not via -bios or -pflash), virt and xlnx-versal-virt
    so for the 7.0 release we reverted it (in commit 4825eaae).
    
    This commit provides a mechanism that boards can use to arrange that
    psci-conduit is set if running guest code at a low enough EL but not
    if it would be running at the same EL that the conduit implies that
    the QEMU PSCI implementation is using.  (Later commits will convert
    individual board models to use this mechanism.)
    
    We do this by moving the setting of the psci-conduit and
    start-powered-off properties to arm_load_kernel().  Boards which want
    to potentially use emulated PSCI must set a psci_conduit field in the
    arm_boot_info struct to the type of conduit they want to use (SMC or
    HVC); arm_load_kernel() will then set the CPUs up accordingly if it
    is not going to start the guest code at the same or higher EL as the
    fake QEMU firmware would be at.
    
    Board/SoC code which uses this mechanism should no longer set the CPU
    psci-conduit property directly.  It should only set the
    start-powered-off property for secondaries if EL3 guest firmware
    running bare metal expects that rather than the alternative "all CPUs
    start executing the firmware at once".
    
    Note that when calculating whether we are going to run guest
    code at EL3, we ignore the setting of arm_boot_info::secure_board_setup,
    which might cause us to run a stub bit of guest code at EL3 which
    does some board-specific setup before dropping to EL2 or EL1 to
    run the guest kernel. This is OK because only one board that
    enables PSCI sets secure_board_setup (the highbank board), and
    the stub code it writes will behave the same way whether the
    one SMC call it makes is handled by "emulate the SMC" or by
    "PSCI default returns an error code". So we can leave that stub
    code in place until after we've changed the PSCI default behaviour;
    at that point we will remove it.
    
    Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
    Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
    Tested-by: default avatarEdgar E. Iglesias <edgar.iglesias@xilinx.com>
    Tested-by: default avatarCédric Le Goater <clg@kaod.org>
    Message-id: 20220127154639.2090164-4-peter.maydell@linaro.org
    817e2db8
    hw/arm/boot: Support setting psci-conduit based on guest EL
    Peter Maydell authored
    
    
    Currently we expect board code to set the psci-conduit property on
    CPUs and ensure that secondary CPUs are created with the
    start-powered-off property set to false, if the board wishes to use
    QEMU's builtin PSCI emulation.  This worked OK for the virt board
    where we first wanted to use it, because the virt board directly
    creates its CPUs and is in a reasonable position to set those
    properties.  For other boards which model real hardware and use a
    separate SoC object, however, it is more awkward.  Most PSCI-using
    boards just set the psci-conduit board unconditionally.
    
    This was never strictly speaking correct (because you would not be
    able to run EL3 guest firmware that itself provided the PSCI
    interface, as the QEMU implementation would overrule it), but mostly
    worked in practice because for non-PSCI SMC calls QEMU would emulate
    the SMC instruction as normal (by trapping to guest EL3).  However,
    we would like to make our PSCI emulation follow the part of the SMCC
    specification that mandates that SMC calls with unknown function
    identifiers return a failure code, which means that all SMC calls
    will be handled by the PSCI code and the "emulate as normal" path
    will no longer be taken.
    
    We tried to implement that in commit 9fcd15b9
    ("arm: tcg: Adhere to SMCCC 1.3 section 5.2"), but this
    regressed attempts to run EL3 guest code on the affected boards:
     * mcimx6ul-evk, mcimx7d-sabre, orangepi, xlnx-zcu102
     * for the case only of EL3 code loaded via -kernel (and
       not via -bios or -pflash), virt and xlnx-versal-virt
    so for the 7.0 release we reverted it (in commit 4825eaae).
    
    This commit provides a mechanism that boards can use to arrange that
    psci-conduit is set if running guest code at a low enough EL but not
    if it would be running at the same EL that the conduit implies that
    the QEMU PSCI implementation is using.  (Later commits will convert
    individual board models to use this mechanism.)
    
    We do this by moving the setting of the psci-conduit and
    start-powered-off properties to arm_load_kernel().  Boards which want
    to potentially use emulated PSCI must set a psci_conduit field in the
    arm_boot_info struct to the type of conduit they want to use (SMC or
    HVC); arm_load_kernel() will then set the CPUs up accordingly if it
    is not going to start the guest code at the same or higher EL as the
    fake QEMU firmware would be at.
    
    Board/SoC code which uses this mechanism should no longer set the CPU
    psci-conduit property directly.  It should only set the
    start-powered-off property for secondaries if EL3 guest firmware
    running bare metal expects that rather than the alternative "all CPUs
    start executing the firmware at once".
    
    Note that when calculating whether we are going to run guest
    code at EL3, we ignore the setting of arm_boot_info::secure_board_setup,
    which might cause us to run a stub bit of guest code at EL3 which
    does some board-specific setup before dropping to EL2 or EL1 to
    run the guest kernel. This is OK because only one board that
    enables PSCI sets secure_board_setup (the highbank board), and
    the stub code it writes will behave the same way whether the
    one SMC call it makes is handled by "emulate the SMC" or by
    "PSCI default returns an error code". So we can leave that stub
    code in place until after we've changed the PSCI default behaviour;
    at that point we will remove it.
    
    Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
    Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
    Tested-by: default avatarEdgar E. Iglesias <edgar.iglesias@xilinx.com>
    Tested-by: default avatarCédric Le Goater <clg@kaod.org>
    Message-id: 20220127154639.2090164-4-peter.maydell@linaro.org
Loading