arm64 kvm: add the processing functions for all el0/el1 exceptions

I added 2 unified processing functions for all exceptions of el/el0

Signed-off-by: Robin Luk <lubin.lu@antgroup.com>
This commit is contained in:
Robin Luk
2020-11-17 14:54:33 +08:00
parent 938aabeecb
commit 170b584222
5 changed files with 39 additions and 48 deletions
@@ -263,13 +263,6 @@ func (c *vCPU) SwitchToUser(switchOpts ring0.SwitchOpts, info *arch.SignalInfo)
return usermem.NoAccess, platform.ErrContextInterrupt
case ring0.El0SyncUndef:
return c.fault(int32(syscall.SIGILL), info)
case ring0.El1SyncUndef:
*info = arch.SignalInfo{
Signo: int32(syscall.SIGILL),
Code: 1, // ILL_ILLOPC (illegal opcode).
}
info.SetAddr(switchOpts.Registers.Pc) // Include address.
return usermem.AccessType{}, platform.ErrContextSignal
default:
panic(fmt.Sprintf("unexpected vector: 0x%x", vector))
}
+1
View File
@@ -90,6 +90,7 @@ const (
El0SyncIa
El0SyncFpsimdAcc
El0SyncSveAcc
El0SyncFpsimdExc
El0SyncSys
El0SyncSpPc
El0SyncUndef
+33 -41
View File
@@ -370,12 +370,12 @@
MOVD R4, CPU_REGISTERS+PTRACE_SP(RSV_REG); \
LOAD_KERNEL_STACK(RSV_REG); // Load the temporary stack.
// EXCEPTION_WITH_ERROR is a common exception handler function.
#define EXCEPTION_WITH_ERROR(user, vector) \
// EXCEPTION_EL0 is a common el0 exception handler function.
#define EXCEPTION_EL0(vector) \
WORD $0xd538d092; \ //MRS TPIDR_EL1, R18
WORD $0xd538601a; \ //MRS FAR_EL1, R26
MOVD R26, CPU_FAULT_ADDR(RSV_REG); \
MOVD $user, R3; \
MOVD $1, R3; \
MOVD R3, CPU_ERROR_TYPE(RSV_REG); \ // Set error type to user.
MOVD $vector, R3; \
MOVD R3, CPU_VECTOR_CODE(RSV_REG); \
@@ -383,6 +383,12 @@
MOVD R3, CPU_ERROR_CODE(RSV_REG); \
B ·kernelExitToEl1(SB);
// EXCEPTION_EL1 is a common el1 exception handler function.
#define EXCEPTION_EL1(vector) \
MOVD $vector, R3; \
MOVD R3, 8(RSP); \
B ·HaltEl1ExceptionAndResume(SB);
// storeAppASID writes the application's asid value.
TEXT ·storeAppASID(SB),NOSPLIT,$0-8
MOVD asid+0(FP), R1
@@ -430,6 +436,16 @@ TEXT ·HaltEl1SvcAndResume(SB),NOSPLIT,$0
CALL ·kernelSyscall(SB) // Call the trampoline.
B ·kernelExitToEl1(SB) // Resume.
// HaltEl1ExceptionAndResume calls Hooks.KernelException and resume.
TEXT ·HaltEl1ExceptionAndResume(SB),NOSPLIT,$0-8
WORD $0xd538d092 // MRS TPIDR_EL1, R18
MOVD CPU_SELF(RSV_REG), R3 // Load vCPU.
MOVD R3, 8(RSP) // First argument (vCPU).
MOVD vector+0(FP), R3
MOVD R3, 16(RSP) // Second argument (vector).
CALL ·kernelException(SB) // Call the trampoline.
B ·kernelExitToEl1(SB) // Resume.
// Shutdown stops the guest.
TEXT ·Shutdown(SB),NOSPLIT,$0
// PSCI EVENT.
@@ -592,39 +608,22 @@ TEXT ·El1_sync(SB),NOSPLIT,$0
B el1_invalid
el1_da:
EXCEPTION_EL1(El1SyncDa)
el1_ia:
WORD $0xd538d092 //MRS TPIDR_EL1, R18
WORD $0xd538601a //MRS FAR_EL1, R26
MOVD R26, CPU_FAULT_ADDR(RSV_REG)
MOVD $0, CPU_ERROR_TYPE(RSV_REG)
MOVD $PageFault, R3
MOVD R3, CPU_VECTOR_CODE(RSV_REG)
B ·HaltAndResume(SB)
EXCEPTION_EL1(El1SyncIa)
el1_sp_pc:
B ·Shutdown(SB)
EXCEPTION_EL1(El1SyncSpPc)
el1_undef:
B ·Shutdown(SB)
EXCEPTION_EL1(El1SyncUndef)
el1_svc:
MOVD $0, CPU_ERROR_CODE(RSV_REG)
MOVD $0, CPU_ERROR_TYPE(RSV_REG)
B ·HaltEl1SvcAndResume(SB)
el1_dbg:
B ·Shutdown(SB)
EXCEPTION_EL1(El1SyncDbg)
el1_fpsimd_acc:
VFP_ENABLE
B ·kernelExitToEl1(SB) // Resume.
el1_invalid:
B ·Shutdown(SB)
EXCEPTION_EL1(El1SyncInv)
// El1_irq is the handler for El1_irq.
TEXT ·El1_irq(SB),NOSPLIT,$0
@@ -680,28 +679,21 @@ el0_svc:
el0_da:
el0_ia:
EXCEPTION_WITH_ERROR(1, PageFault)
EXCEPTION_EL0(PageFault)
el0_fpsimd_acc:
B ·Shutdown(SB)
EXCEPTION_EL0(El0SyncFpsimdAcc)
el0_sve_acc:
B ·Shutdown(SB)
EXCEPTION_EL0(El0SyncSveAcc)
el0_fpsimd_exc:
B ·Shutdown(SB)
EXCEPTION_EL0(El0SyncFpsimdExc)
el0_sp_pc:
B ·Shutdown(SB)
EXCEPTION_EL0(El0SyncSpPc)
el0_undef:
EXCEPTION_WITH_ERROR(1, El0SyncUndef)
EXCEPTION_EL0(El0SyncUndef)
el0_dbg:
B ·Shutdown(SB)
EXCEPTION_EL0(El0SyncDbg)
el0_invalid:
B ·Shutdown(SB)
EXCEPTION_EL0(El0SyncInv)
TEXT ·El0_irq(SB),NOSPLIT,$0
B ·Shutdown(SB)
@@ -24,6 +24,10 @@ func HaltAndResume()
//go:nosplit
func HaltEl1SvcAndResume()
// HaltEl1ExceptionAndResume calls Hooks.KernelException and resume.
//go:nosplit
func HaltEl1ExceptionAndResume()
// init initializes architecture-specific state.
func (k *Kernel) init(maxCPUs int) {
}
@@ -70,6 +70,7 @@ func Emit(w io.Writer) {
fmt.Fprintf(w, "#define El0SyncIa 0x%02x\n", El0SyncIa)
fmt.Fprintf(w, "#define El0SyncFpsimdAcc 0x%02x\n", El0SyncFpsimdAcc)
fmt.Fprintf(w, "#define El0SyncSveAcc 0x%02x\n", El0SyncSveAcc)
fmt.Fprintf(w, "#define El0SyncFpsimdExc 0x%02x\n", El0SyncFpsimdExc)
fmt.Fprintf(w, "#define El0SyncSys 0x%02x\n", El0SyncSys)
fmt.Fprintf(w, "#define El0SyncSpPc 0x%02x\n", El0SyncSpPc)
fmt.Fprintf(w, "#define El0SyncUndef 0x%02x\n", El0SyncUndef)