]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: LoongArch: selftests: Add system registers save/restore on exception
authorBibo Mao <maobibo@loongson.cn>
Thu, 27 Nov 2025 03:00:18 +0000 (11:00 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Thu, 27 Nov 2025 03:00:18 +0000 (11:00 +0800)
When system returns from exception with ertn instruction, PC comes from
LOONGARCH_CSR_ERA, and CSR.CRMD comes LOONGARCH_CSR_PRMD.

Here save CSR register CSR.ERA and CSR.PRMD into stack, and then restore
them from stack. So it can be modified by exception handlers in future.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
tools/testing/selftests/kvm/include/loongarch/processor.h
tools/testing/selftests/kvm/lib/loongarch/exception.S

index 6427a3275e6a80badceb2ae4f86ace6b5f976274..374caddfb0db783143b0fc4ed012d35baf2ed493 100644 (file)
@@ -124,18 +124,21 @@ struct ex_regs {
        unsigned long pc;
        unsigned long estat;
        unsigned long badv;
+       unsigned long prmd;
 };
 
 #define PC_OFFSET_EXREGS               offsetof(struct ex_regs, pc)
 #define ESTAT_OFFSET_EXREGS            offsetof(struct ex_regs, estat)
 #define BADV_OFFSET_EXREGS             offsetof(struct ex_regs, badv)
+#define PRMD_OFFSET_EXREGS             offsetof(struct ex_regs, prmd)
 #define EXREGS_SIZE                    sizeof(struct ex_regs)
 
 #else
 #define PC_OFFSET_EXREGS               ((EXREGS_GPRS + 0) * 8)
 #define ESTAT_OFFSET_EXREGS            ((EXREGS_GPRS + 1) * 8)
 #define BADV_OFFSET_EXREGS             ((EXREGS_GPRS + 2) * 8)
-#define EXREGS_SIZE                    ((EXREGS_GPRS + 3) * 8)
+#define PRMD_OFFSET_EXREGS             ((EXREGS_GPRS + 3) * 8)
+#define EXREGS_SIZE                    ((EXREGS_GPRS + 4) * 8)
 #endif
 
 #endif /* SELFTEST_KVM_PROCESSOR_H */
index 88bfa505c6f58942eb48e20b61169e76fc1ca809..3f1e4b67c5ae43bdc71831ff04d5b71570cf4f0f 100644 (file)
@@ -51,9 +51,15 @@ handle_exception:
        st.d   t0, sp, ESTAT_OFFSET_EXREGS
        csrrd  t0, LOONGARCH_CSR_BADV
        st.d   t0, sp, BADV_OFFSET_EXREGS
+       csrrd  t0, LOONGARCH_CSR_PRMD
+       st.d   t0, sp, PRMD_OFFSET_EXREGS
 
        or     a0, sp, zero
        bl route_exception
+       ld.d   t0, sp, PC_OFFSET_EXREGS
+       csrwr  t0, LOONGARCH_CSR_ERA
+       ld.d   t0, sp, PRMD_OFFSET_EXREGS
+       csrwr  t0, LOONGARCH_CSR_PRMD
        restore_gprs sp
        csrrd  sp, LOONGARCH_CSR_KS0
        ertn