mirror of
https://github.com/qemu/qemu.git
synced 2026-09-21 14:04:09 +00:00
target/arm/whpx: fix whpx-arm post-reset CPU state
Reset should leave CPU 0 running, and should leave all other CPUs
suspended. Instead, no CPUs are suspended and CPUs may be left in
low-power states.
Fix by updating state in whpx_set_registers WHPX_LEVEL_RESET_STATE.
Signed-off-by: Doug Cook <dcook@microsoft.com>
Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 57197bf183)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
committed by
Michael Tokarev
parent
4908ac02c7
commit
a4f83debce
@@ -617,6 +617,37 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
|
||||
whpx_set_reg(cpu, whpx_sreg_match[i].reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
if (level == WHPX_LEVEL_RESET_STATE) {
|
||||
/*
|
||||
* WHPX keeps the "vCPU is in a low-power wait" state (entered when the
|
||||
* guest executes WFI/WFE) in WHvRegisterInternalActivityState, and that
|
||||
* state is not affected by writing the architectural registers above.
|
||||
* If the guest happened to be idle when the reset was requested, the
|
||||
* vCPU would stay suspended forever.
|
||||
*
|
||||
* StartupSuspend is the bit WHP uses to hold a vCPU that has not been
|
||||
* started yet, and it is how secondary vCPUs are parked until PSCI
|
||||
* CPU_ON releases them.
|
||||
*/
|
||||
WHV_REGISTER_NAME name = WHvRegisterInternalActivityState;
|
||||
bool powered_off = arm_cpu->power_state == PSCI_OFF;
|
||||
WHV_REGISTER_VALUE ia;
|
||||
HRESULT hr;
|
||||
|
||||
clean_whv_register_value(&ia);
|
||||
hr = whp_dispatch.WHvGetVirtualProcessorRegisters(
|
||||
whpx_global.partition, cpu->cpu_index, &name, 1, &ia);
|
||||
if (SUCCEEDED(hr) &&
|
||||
(ia.InternalActivity.IdleSuspend ||
|
||||
ia.InternalActivity.HaltSuspend ||
|
||||
ia.InternalActivity.StartupSuspend != powered_off)) {
|
||||
ia.InternalActivity.IdleSuspend = 0;
|
||||
ia.InternalActivity.HaltSuspend = 0;
|
||||
ia.InternalActivity.StartupSuspend = powered_off;
|
||||
whpx_set_reg(cpu, WHvRegisterInternalActivityState, ia);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t max_vcpu_index;
|
||||
|
||||
Reference in New Issue
Block a user