On Tue, 29 Aug 2023, Anthony Chan wrote:
> Hi all,
> 
> My name is Tony and I've been researching/developing using Xen for potential 
> upcoming uses in our embedded systems.  I started with Xen using Xilinx tools 
> about a year ago and still have lots to learn about what it can to do in the 
> embedded space.  So far, I've managed to integrate Xen and Linux into an 
> existing product that exclusively runs bare-metal code on a ZynqMP SoC and 
> migrate some of the functionality into custom Linux driver/userspace.
> 
> I'm now looking at low power support, for now at least between Xen (4.16) and 
> Linux (5.15) dom0.  I've tried a few different Linux kernel configs around 
> power management and each time I try to suspend from linux dom0 (via sysfs or 
> systemctl), Xen will watchdog on dom0 guest.  AFAIK, Xen should trap on a 
> 'WFI' from guests, but from what I can tell debugging through the linux 
> suspend process is it's spinning in a 'suspend-to-idle' loop before it can 
> get to issuing a 'WFI' or using PSCI interface to notify Xen.  I'm beginning 
> to suspect that 'low power' support for embedded arm64 just isn't quite there 
> yet, or am I missing something in the configs?
> 
> I realize this could very well be a Linux 'issue' but checking here first.  I 
> know Xen presents a flattened device tree to Linux without CPU idle-state 
> nodes and maybe this is causing the linux guest to only do the 
> suspend-to-idle mode?  I should mention that I'm booting up using dom0less 
> feature if that matters.


Hi Anthony,

Assuming you are using the default Xen command line parameters for
Xilinx boards: sched=null vwfi=native, then if the guest uses WFI, the
CPU will execute WFI directly and go into low power mode.

Given the issue you are describing, I am suspecting the guest is not
issuing WFI: that is simple and known to work. Instead, I suspect that
Linux might be trying to use PSCI_suspend in a way that is not supported
or well-implemented by Xen.

Can you check? You can add a printk in Linux
drivers/firmware/psci/psci.c:__psci_cpu_suspend or in Xen
xen/arch/arm/vpsci.c:do_psci_0_2_cpu_suspend

If that is the case, the attached patch might work because it disables
PSCI_suspend support in Xen and Linux should fall back to WFI. (There is
no power saving in using PSCI_suspend versus WFI.)

Cheers,

Stefano
diff --git a/xen/arch/arm/vpsci.c b/xen/arch/arm/vpsci.c
index d1615be8a6..9f660b8ab4 100644
--- a/xen/arch/arm/vpsci.c
+++ b/xen/arch/arm/vpsci.c
@@ -116,21 +116,6 @@ static uint32_t do_psci_0_2_version(void)
     return PSCI_VERSION(1, 1);
 }
 
-static register_t do_psci_0_2_cpu_suspend(uint32_t power_state,
-                                          register_t entry_point,
-                                          register_t context_id)
-{
-    struct vcpu *v = current;
-
-    /*
-     * Power off requests are treated as performing standby
-     * as this simplifies Xen implementation.
-     */
-
-    vcpu_block_unless_event_pending(v);
-    return PSCI_SUCCESS;
-}
-
 static int32_t do_psci_0_2_cpu_off(void)
 {
     return do_psci_cpu_off(0);
@@ -203,8 +188,6 @@ static int32_t do_psci_1_0_features(uint32_t psci_func_id)
     switch ( psci_func_id )
     {
     case PSCI_0_2_FN32_PSCI_VERSION:
-    case PSCI_0_2_FN32_CPU_SUSPEND:
-    case PSCI_0_2_FN64_CPU_SUSPEND:
     case PSCI_0_2_FN32_CPU_OFF:
     case PSCI_0_2_FN32_CPU_ON:
     case PSCI_0_2_FN64_CPU_ON:
@@ -312,18 +295,6 @@ bool do_vpsci_0_2_call(struct cpu_user_regs *regs, uint32_t fid)
         return true;
     }
 
-    case PSCI_0_2_FN32_CPU_SUSPEND:
-    case PSCI_0_2_FN64_CPU_SUSPEND:
-    {
-        uint32_t pstate = PSCI_ARG32(regs, 1);
-        register_t epoint = PSCI_ARG(regs, 2);
-        register_t cid = PSCI_ARG(regs, 3);
-
-        perfc_incr(vpsci_cpu_suspend);
-        PSCI_SET_RESULT(regs, do_psci_0_2_cpu_suspend(pstate, epoint, cid));
-        return true;
-    }
-
     case PSCI_0_2_FN32_AFFINITY_INFO:
     case PSCI_0_2_FN64_AFFINITY_INFO:
     {

Reply via email to