[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.18] x86/suspend: unconditionally raise a timer softirq on resume



commit 51190865a4918c443c310c0478247d5f9caa5dad
Author:     Roger Pau Monné <roger.pau@xxxxxxxxxx>
AuthorDate: Wed Sep 3 14:09:11 2025 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Sep 3 14:09:11 2025 +0200

    x86/suspend: unconditionally raise a timer softirq on resume
    
    The current code to restore the timer state on resume is incomplete.  While
    the local APIC Initial Count Register is saved and restored across
    suspension (even if possibly no longer accurate since it's not adjusted to
    account for the time spent in suspension), the TSC deadline MSR is not
    saved and restored, hence hosts using the TSC deadline timer will likely
    get stuck when resuming from suspension.
    
    The lack of restoring of the TSC deadline MSR was mitigated by the raising
    of a timer softirq in mwait_idle_with_hints() if the timer had expired,
    previous to commit 3faf0866a33070b926ab78e6298290403f85e76c, which removed
    that logic.
    
    This patch fixes the usage of the TSC deadline timer with suspension, by
    unconditionally raising a timer softirq on resume, that will take care of
    rearming the hardware timer.  Given that a timer softirq will be
    unconditionally risen, there's no need to save and restore the APIC Initial
    Count Register anymore either.
    
    Note that secondary processors don't need this special treatment when
    resuming, since they are offlined before suspension and brought back up
    during resume, the first timer that gets setup will trigger a timer softirq
    unconditionally, for example from sched_migrate_timers() that gets called
    for each secondary processor.
    
    Link: https://github.com/QubesOS/qubes-issues/issues/10110
    Reported-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
    Fixes: fd1291a826e1 ('X86: Prefer TSC-deadline timer in Xen')
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    Tested-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
    master commit: 757abedabbb64f18a28ae61a7bd67a927bb03130
    master date: 2025-08-27 09:33:12 +0200
---
 xen/arch/x86/acpi/power.c | 2 ++
 xen/arch/x86/apic.c       | 3 ---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
index 783b4a2f2c..5fc7fef24f 100644
--- a/xen/arch/x86/acpi/power.c
+++ b/xen/arch/x86/acpi/power.c
@@ -22,6 +22,7 @@
 #include <xen/domain.h>
 #include <xen/console.h>
 #include <xen/iommu.h>
+#include <xen/softirq.h>
 #include <xen/watchdog.h>
 #include <xen/cpu.h>
 #include <public/platform.h>
@@ -330,6 +331,7 @@ static int enter_state(u32 state)
     thaw_domains();
     system_state = SYS_STATE_active;
     spin_unlock(&pm_lock);
+    raise_softirq(TIMER_SOFTIRQ);
     return error;
 }
 
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index 6acdd0ec14..ab1bb29ab0 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -63,7 +63,6 @@ static struct {
     unsigned int apic_lvt0;
     unsigned int apic_lvt1;
     unsigned int apic_lvterr;
-    unsigned int apic_tmict;
     unsigned int apic_tdcr;
     unsigned int apic_thmr;
 } apic_pm_state;
@@ -660,7 +659,6 @@ int lapic_suspend(void)
     apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
     apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
     apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
-    apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
     apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
     if (maxlvt >= 5)
         apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
@@ -720,7 +718,6 @@ int lapic_resume(void)
         apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
     apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
     apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
-    apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
     apic_write(APIC_ESR, 0);
     apic_read(APIC_ESR);
     apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.18



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.