[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4][PART 1 2/4] xen/arm: Implement PSCI SYSTEM_SUSPEND call for guests
On Tue, May 27, 2025 at 12:19 PM Mykola Kvach <xakep.amatop@xxxxxxxxx> wrote: > > From: Mykola Kvach <mykola_kvach@xxxxxxxx> > > This patch adds support for the PSCI SYSTEM_SUSPEND function in the vPSCI > (virtual PSCI) interface, allowing guests to request suspend via the PSCI > v1.0 SYSTEM_SUSPEND call (both 32-bit and 64-bit variants). > > The implementation: > - Adds SYSTEM_SUSPEND function IDs to PSCI definitions > - Implements trapping and handling of SYSTEM_SUSPEND in vPSCI > - Allows only non-hardware domains to invoke SYSTEM_SUSPEND; for the > hardware domain, PSCI_NOT_SUPPORTED is returned to avoid halting the > system in hwdom_shutdown() called from domain_shutdown > - Ensures all secondary VCPUs of the calling domain are offline before > allowing suspend due to PSCI spec > - Treats suspend as a "standby" operation: the domain is shut down with > SHUTDOWN_suspend, and resumes execution at the instruction following > the call > > Usage: > > For Linux-based guests, suspend can be initiated with: > echo mem > /sys/power/state > or via: > systemctl suspend > > Resuming the guest is performed from control domain using: > xl resume <domain> > > Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx> > --- > Changes in V3: > Dropped all domain flags and related code (which touched common functions like > vcpu_unblock), keeping only the necessary changes for Xen suspend/resume, i.e. > suspend/resume is now fully supported only for the hardware domain. > Proper support for domU suspend/resume will be added in a future patch. > This patch does not yet include VCPU context reset or domain context > restoration in VCPU. > > Changes in V4: > Dropped all changes related to watchdog, domain is marked as shutting > down in domain_shutdown and watchdog timeout handler won't trigger > because of it. > > Previous versions included code to manage Xen watchdog timers during suspend, > but this was removed. When a guest OS starts the Xen watchdog (either via the > kernel driver or xenwatchdogd), it is responsible for managing that state > across suspend/resume. On Linux, the Xen kernel driver properly stops the > watchdog during suspend. However, when xenwatchdogd is used instead, suspend > handling is incomplete, potentially leading to watchdog-triggered resets on > resume. Xen leaves watchdog handling to the guest OS and its services. > > Dropped all changes related to VCPU context, because instead domain_shutdown > is used, so we don't need any extra changes for suspending domain. > --- > xen/arch/arm/include/asm/perfc_defn.h | 1 + > xen/arch/arm/include/asm/psci.h | 2 + > xen/arch/arm/vpsci.c | 64 +++++++++++++++++++++++++++ > 3 files changed, 67 insertions(+) > > diff --git a/xen/arch/arm/include/asm/perfc_defn.h > b/xen/arch/arm/include/asm/perfc_defn.h > index effd25b69e..8dfcac7e3b 100644 > --- a/xen/arch/arm/include/asm/perfc_defn.h > +++ b/xen/arch/arm/include/asm/perfc_defn.h > @@ -33,6 +33,7 @@ PERFCOUNTER(vpsci_system_reset, "vpsci: > system_reset") > PERFCOUNTER(vpsci_cpu_suspend, "vpsci: cpu_suspend") > PERFCOUNTER(vpsci_cpu_affinity_info, "vpsci: cpu_affinity_info") > PERFCOUNTER(vpsci_features, "vpsci: features") > +PERFCOUNTER(vpsci_system_suspend, "vpsci: system_suspend") > > PERFCOUNTER(vcpu_kick, "vcpu: notify other vcpu") > > diff --git a/xen/arch/arm/include/asm/psci.h b/xen/arch/arm/include/asm/psci.h > index 4780972621..48a93e6b79 100644 > --- a/xen/arch/arm/include/asm/psci.h > +++ b/xen/arch/arm/include/asm/psci.h > @@ -47,10 +47,12 @@ void call_psci_system_reset(void); > #define PSCI_0_2_FN32_SYSTEM_OFF PSCI_0_2_FN32(8) > #define PSCI_0_2_FN32_SYSTEM_RESET PSCI_0_2_FN32(9) > #define PSCI_1_0_FN32_PSCI_FEATURES PSCI_0_2_FN32(10) > +#define PSCI_1_0_FN32_SYSTEM_SUSPEND PSCI_0_2_FN32(14) > > #define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) > #define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) > #define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) > +#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) > > /* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ > #define PSCI_0_2_AFFINITY_LEVEL_ON 0 > diff --git a/xen/arch/arm/vpsci.c b/xen/arch/arm/vpsci.c > index d1615be8a6..866bd3128b 100644 > --- a/xen/arch/arm/vpsci.c > +++ b/xen/arch/arm/vpsci.c > @@ -197,6 +197,57 @@ static void do_psci_0_2_system_reset(void) > domain_shutdown(d,SHUTDOWN_reboot); > } > > +static int32_t do_psci_1_0_system_suspend(register_t epoint, register_t cid) > +{ > + struct vcpu *v; > + struct domain *d = current->domain; > + > + /* Drop this check once SYSTEM_SUSPEND is supported in hardware domain */ > + if ( is_hardware_domain(d) ) > + return PSCI_NOT_SUPPORTED; > + > + /* Ensure that all CPUs other than the calling one are offline */ > + for_each_vcpu ( d, v ) > + { > + if ( v != current && is_vcpu_online(v) ) > + return PSCI_DENIED; > + } > + > + /* > + * System suspend requests are treated as performing standby > + * as this simplifies Xen implementation. > + * > + * Arm Power State Coordination Interface (DEN0022F.b) > + * > + * 5.20.2 Caller responsibilities > + * The call is equivalent to using the CPU_SUSPEND call for the deepest > + * possible platform powerdown state. Consequently, the caller must > observe > + * all the rules described for CPU_SUSPEND. See section 5.4. > + * > + * 5.4.5 Caller responsibilities > + * The caller must not assume that a powerdown request will return using > + * the specified entry point address. The powerdown request might not > + * complete due, for example, to pending interrupts. It is also possible > + * that, because of coordination with other cores, the actual state > entered > + * is shallower than the one requested. Because of this it is possible > for > + * an implementation to downgrade the powerdown state request to a > standby > + * state. In the case of a downgrade to standby, the implementation > returns > + * at the instruction following the PSCI call, at the Exception level of > + * the caller, instead of returning by the specified entry point address. > + * The return code in this case is SUCCESS. In the case of an early > return > + * due to a pending wakeup event, the implementation can return at the > next > + * instruction, with a return code of SUCCESS, or resume at the specified > + * entry point address. > + * > + * 5.4.9 Implementation responsibilities: State on return > + * When returning from a standby state, the caller must observe no > change in > + * core state, other than any timer changes expected because of the time > + * spent in the state, and changes in the CPU interface because of the > + * wakeup reason. > + */ > + return domain_shutdown(d, SHUTDOWN_suspend) ? PSCI_DENIED : PSCI_SUCCESS; > +} > + > static int32_t do_psci_1_0_features(uint32_t psci_func_id) > { > /* /!\ Ordered by function ID and not name */ > @@ -214,6 +265,8 @@ static int32_t do_psci_1_0_features(uint32_t psci_func_id) > case PSCI_0_2_FN32_SYSTEM_OFF: > case PSCI_0_2_FN32_SYSTEM_RESET: > case PSCI_1_0_FN32_PSCI_FEATURES: > + case PSCI_1_0_FN32_SYSTEM_SUSPEND: > + case PSCI_1_0_FN64_SYSTEM_SUSPEND: > case ARM_SMCCC_VERSION_FID: > return 0; > default: > @@ -344,6 +397,17 @@ bool do_vpsci_0_2_call(struct cpu_user_regs *regs, > uint32_t fid) > return true; > } > > + case PSCI_1_0_FN32_SYSTEM_SUSPEND: > + case PSCI_1_0_FN64_SYSTEM_SUSPEND: note to self: update VPSCI_NR_FUNCS > + { > + register_t epoint = PSCI_ARG(regs,1); > + register_t cid = PSCI_ARG(regs,2); > + > + perfc_incr(vpsci_system_suspend); > + PSCI_SET_RESULT(regs, do_psci_1_0_system_suspend(epoint, cid)); > + return true; > + } > + > default: > return false; > } > -- > 2.48.1 >
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |