Commit ceb9155d authored by Huacai Chen's avatar Huacai Chen
Browse files

LoongArch: Save and restore CSR.CNTC for hibernation



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: default avatarXianglai Li <lixianglai@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 3e245b7b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,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)
{
+3 −0
Original line number Diff line number Diff line
@@ -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);