]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
LoongArch: Save and restore CSR.CNTC for hibernation
authorHuacai Chen <chenhuacai@loongson.cn>
Wed, 14 May 2025 14:17:52 +0000 (22:17 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 May 2025 12:12:19 +0000 (14:12 +0200)
commit ceb9155d058a11242aa0572875c44e9713b1a2be upstream.

Save and restore CSR.CNTC for hibernation which is similar to suspend.

For host this is unnecessary because sched clock is ensured continuous,
but for kvm guest sched clock isn't enough because rdtime.d should also
be continuous.

Host::rdtime.d = Host::CSR.CNTC + counter
Guest::rdtime.d = Host::CSR.CNTC + Host::CSR.GCNTC + Guest::CSR.CNTC + counter

so,

Guest::rdtime.d = Host::rdtime.d + Host::CSR.GCNTC + Guest::CSR.CNTC

To ensure Guest::rdtime.d continuous, Host::rdtime.d should be at first
continuous, while Host::CSR.GCNTC / Guest::CSR.CNTC is maintained by KVM.

Cc: stable@vger.kernel.org
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/loongarch/kernel/time.c
arch/loongarch/power/hibernate.c

index e7015f7b70e37c4cabf736512c50a998455bbdf9..a3732f754b5d8f6a80a85e96a8d8c263aa873cf6 100644 (file)
@@ -110,7 +110,7 @@ static unsigned long __init get_loops_per_jiffy(void)
        return lpj;
 }
 
-static long init_offset __nosavedata;
+static long init_offset;
 
 void save_counter(void)
 {
index 1e0590542f987cd59c0bad22f938b51ad0e4f2a5..e7b7346592cb2a335c64ff23a5b2389cf63f6bf7 100644 (file)
@@ -2,6 +2,7 @@
 #include <asm/fpu.h>
 #include <asm/loongson.h>
 #include <asm/sections.h>
+#include <asm/time.h>
 #include <asm/tlbflush.h>
 #include <linux/suspend.h>
 
@@ -14,6 +15,7 @@ struct pt_regs saved_regs;
 
 void save_processor_state(void)
 {
+       save_counter();
        saved_crmd = csr_read32(LOONGARCH_CSR_CRMD);
        saved_prmd = csr_read32(LOONGARCH_CSR_PRMD);
        saved_euen = csr_read32(LOONGARCH_CSR_EUEN);
@@ -26,6 +28,7 @@ void save_processor_state(void)
 
 void restore_processor_state(void)
 {
+       sync_counter();
        csr_write32(saved_crmd, LOONGARCH_CSR_CRMD);
        csr_write32(saved_prmd, LOONGARCH_CSR_PRMD);
        csr_write32(saved_euen, LOONGARCH_CSR_EUEN);