arm: tcg: Adhere to SMCCC 1.3 section 5.2

The SMCCC 1.3 spec section 5.2 says

  The Unknown SMC Function Identifier is a sign-extended value of (-1)
  that is returned in the R0, W0 or X0 registers. An implementation must
  return this error code when it receives:

    * An SMC or HVC call with an unknown Function Identifier
    * An SMC or HVC call for a removed Function Identifier
    * An SMC64/HVC64 call from AArch32 state

To comply with these statements, let's always return -1 when we encounter
an unknown HVC or SMC call.

Signed-off-by: Alexander Graf <agraf@csgraf.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Alexander Graf 2021-09-16 17:54:04 +02:00 committed by Peter Maydell
parent 01e75d8783
commit 9fcd15b919

View File

@ -27,15 +27,13 @@
bool arm_is_psci_call(ARMCPU *cpu, int excp_type) bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
{ {
/* Return true if the r0/x0 value indicates a PSCI call and /*
* the exception type matches the configured PSCI conduit. This is * Return true if the exception type matches the configured PSCI conduit.
* called before the SMC/HVC instruction is executed, to decide whether * This is called before the SMC/HVC instruction is executed, to decide
* we should treat it as a PSCI call or with the architecturally * whether we should treat it as a PSCI call or with the architecturally
* defined behaviour for an SMC or HVC (which might be UNDEF or trap * defined behaviour for an SMC or HVC (which might be UNDEF or trap
* to EL2 or to EL3). * to EL2 or to EL3).
*/ */
CPUARMState *env = &cpu->env;
uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
switch (excp_type) { switch (excp_type) {
case EXCP_HVC: case EXCP_HVC:
@ -52,27 +50,7 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
return false; return false;
} }
switch (param) {
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
case QEMU_PSCI_0_1_FN_CPU_ON:
case QEMU_PSCI_0_2_FN_CPU_ON:
case QEMU_PSCI_0_2_FN64_CPU_ON:
case QEMU_PSCI_0_1_FN_CPU_OFF:
case QEMU_PSCI_0_2_FN_CPU_OFF:
case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
case QEMU_PSCI_0_1_FN_MIGRATE:
case QEMU_PSCI_0_2_FN_MIGRATE:
return true; return true;
default:
return false;
}
} }
void arm_handle_psci_call(ARMCPU *cpu) void arm_handle_psci_call(ARMCPU *cpu)
@ -194,10 +172,9 @@ void arm_handle_psci_call(ARMCPU *cpu)
break; break;
case QEMU_PSCI_0_1_FN_MIGRATE: case QEMU_PSCI_0_1_FN_MIGRATE:
case QEMU_PSCI_0_2_FN_MIGRATE: case QEMU_PSCI_0_2_FN_MIGRATE:
default:
ret = QEMU_PSCI_RET_NOT_SUPPORTED; ret = QEMU_PSCI_RET_NOT_SUPPORTED;
break; break;
default:
g_assert_not_reached();
} }
err: err: