mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-19 05:32:22 -05:00
KVM: LoongArch: selftests: Add system registers save/restore on exception
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>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user