/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2018 - os kernal * Author: fire3 */ .text #include #include #include #include .set noat ENTRY(__sw64_vcpu_run) /* save host fpregs */ ldl $1, TI_TASK($8) ldi $1, TASK_THREAD($1) rfpcr $f0 fstd $f0, THREAD_FPCR($1) ldi $1, THREAD_CTX_FP($1) vstd $f2, CTX_FP_F2($1) vstd $f3, CTX_FP_F3($1) vstd $f4, CTX_FP_F4($1) vstd $f5, CTX_FP_F5($1) vstd $f6, CTX_FP_F6($1) vstd $f7, CTX_FP_F7($1) vstd $f8, CTX_FP_F8($1) vstd $f9, CTX_FP_F9($1) ldi sp, -VCPU_RET_SIZE(sp) /* r16 = guest kvm_vcpu_arch.vcb struct pointer */ /* r17 = guest kvm_vcpu_arch.kvm_regs struct pointer */ /* r18 = hcall args */ /* save host pt_regs to current kernel stack */ ldi sp, -PT_REGS_SIZE(sp) stl $8, PT_REGS_R8(sp) stl $26, PT_REGS_R26(sp) /* save host switch stack to current kernel stack */ ldi sp, -SWITCH_STACK_SIZE(sp) stl $9, SWITCH_STACK_R9(sp) stl $10, SWITCH_STACK_R10(sp) stl $11, SWITCH_STACK_R11(sp) stl $12, SWITCH_STACK_R12(sp) stl $13, SWITCH_STACK_R13(sp) stl $14, SWITCH_STACK_R14(sp) stl $15, SWITCH_STACK_R15(sp) /* restore guest switch stack from guest kvm_regs struct */ ldl $0, KVM_REGS_R0($17) ldl $1, KVM_REGS_R1($17) /* restore $2 later */ ldl $3, KVM_REGS_R3($17) ldl $4, KVM_REGS_R4($17) ldl $5, KVM_REGS_R5($17) ldl $6, KVM_REGS_R6($17) ldl $7, KVM_REGS_R7($17) ldl $8, KVM_REGS_R8($17) ldl $9, KVM_REGS_R9($17) ldl $10, KVM_REGS_R10($17) ldl $11, KVM_REGS_R11($17) ldl $12, KVM_REGS_R12($17) ldl $13, KVM_REGS_R13($17) ldl $14, KVM_REGS_R14($17) ldl $15, KVM_REGS_R15($17) ldl $19, KVM_REGS_R19($17) ldl $20, KVM_REGS_R20($17) ldl $21, KVM_REGS_R21($17) ldl $22, KVM_REGS_R22($17) ldl $23, KVM_REGS_R23($17) ldl $24, KVM_REGS_R24($17) ldl $25, KVM_REGS_R25($17) ldl $26, KVM_REGS_R26($17) ldl $27, KVM_REGS_R27($17) ldl $28, KVM_REGS_R28($17) fldd $f0, KVM_REGS_FPCR($17) wfpcr $f0 fimovd $f0, $2 and $2, 0x3, $2 beq $2, $g_setfpec_0 subl $2, 0x1, $2 beq $2, $g_setfpec_1 subl $2, 0x1, $2 beq $2, $g_setfpec_2 setfpec3 br $g_setfpec_over $g_setfpec_0: setfpec0 br $g_setfpec_over $g_setfpec_1: setfpec1 br $g_setfpec_over $g_setfpec_2: setfpec2 $g_setfpec_over: ldl $2, KVM_REGS_R2($17) vldd $f0, KVM_REGS_F0($17) vldd $f1, KVM_REGS_F1($17) vldd $f2, KVM_REGS_F2($17) vldd $f3, KVM_REGS_F3($17) vldd $f4, KVM_REGS_F4($17) vldd $f5, KVM_REGS_F5($17) vldd $f6, KVM_REGS_F6($17) vldd $f7, KVM_REGS_F7($17) vldd $f8, KVM_REGS_F8($17) vldd $f9, KVM_REGS_F9($17) vldd $f10, KVM_REGS_F10($17) vldd $f11, KVM_REGS_F11($17) vldd $f12, KVM_REGS_F12($17) vldd $f13, KVM_REGS_F13($17) vldd $f14, KVM_REGS_F14($17) vldd $f15, KVM_REGS_F15($17) vldd $f16, KVM_REGS_F16($17) vldd $f17, KVM_REGS_F17($17) vldd $f18, KVM_REGS_F18($17) vldd $f19, KVM_REGS_F19($17) vldd $f20, KVM_REGS_F20($17) vldd $f21, KVM_REGS_F21($17) vldd $f22, KVM_REGS_F22($17) vldd $f23, KVM_REGS_F23($17) vldd $f24, KVM_REGS_F24($17) vldd $f25, KVM_REGS_F25($17) vldd $f26, KVM_REGS_F26($17) vldd $f27, KVM_REGS_F27($17) vldd $f28, KVM_REGS_F28($17) vldd $f29, KVM_REGS_F29($17) vldd $f30, KVM_REGS_F30($17) ldi $17, KVM_REGS_PS($17) /* enter guest */ /* r16 = guest vcpucb pointer */ /* r17 = base of guest kvm_regs.ps, saved/restored by hmcode */ /* enter guest now */ sys_call 0x31 /* exit guest now */ ldi $17, -KVM_REGS_PS($17) /* r17: base of kvm_regs */ vstd $f0, KVM_REGS_F0($17) vstd $f1, KVM_REGS_F1($17) vstd $f2, KVM_REGS_F2($17) vstd $f3, KVM_REGS_F3($17) vstd $f4, KVM_REGS_F4($17) vstd $f5, KVM_REGS_F5($17) vstd $f6, KVM_REGS_F6($17) vstd $f7, KVM_REGS_F7($17) vstd $f8, KVM_REGS_F8($17) vstd $f9, KVM_REGS_F9($17) vstd $f10, KVM_REGS_F10($17) vstd $f11, KVM_REGS_F11($17) vstd $f12, KVM_REGS_F12($17) vstd $f13, KVM_REGS_F13($17) vstd $f14, KVM_REGS_F14($17) vstd $f15, KVM_REGS_F15($17) vstd $f16, KVM_REGS_F16($17) vstd $f17, KVM_REGS_F17($17) vstd $f18, KVM_REGS_F18($17) vstd $f19, KVM_REGS_F19($17) vstd $f20, KVM_REGS_F20($17) vstd $f21, KVM_REGS_F21($17) vstd $f22, KVM_REGS_F22($17) vstd $f23, KVM_REGS_F23($17) vstd $f24, KVM_REGS_F24($17) vstd $f25, KVM_REGS_F25($17) vstd $f26, KVM_REGS_F26($17) vstd $f27, KVM_REGS_F27($17) vstd $f28, KVM_REGS_F28($17) vstd $f29, KVM_REGS_F29($17) vstd $f30, KVM_REGS_F30($17) rfpcr $f0 fstd $f0, KVM_REGS_FPCR($17) /* don't save r0 Hmcode have saved r0 for us */ stl $1, KVM_REGS_R1($17) stl $2, KVM_REGS_R2($17) stl $3, KVM_REGS_R3($17) stl $4, KVM_REGS_R4($17) stl $5, KVM_REGS_R5($17) stl $6, KVM_REGS_R6($17) stl $7, KVM_REGS_R7($17) stl $8, KVM_REGS_R8($17) stl $9, KVM_REGS_R9($17) stl $10, KVM_REGS_R10($17) stl $11, KVM_REGS_R11($17) stl $12, KVM_REGS_R12($17) stl $13, KVM_REGS_R13($17) stl $14, KVM_REGS_R14($17) stl $15, KVM_REGS_R15($17) stl $19, KVM_REGS_R19($17) stl $20, KVM_REGS_R20($17) stl $21, KVM_REGS_R21($17) stl $22, KVM_REGS_R22($17) stl $23, KVM_REGS_R23($17) stl $24, KVM_REGS_R24($17) stl $25, KVM_REGS_R25($17) stl $26, KVM_REGS_R26($17) stl $27, KVM_REGS_R27($17) stl $28, KVM_REGS_R28($17) /* restore host switch stack from host sp */ ldl $9, SWITCH_STACK_R9(sp) ldl $10, SWITCH_STACK_R10(sp) ldl $11, SWITCH_STACK_R11(sp) ldl $12, SWITCH_STACK_R12(sp) ldl $13, SWITCH_STACK_R13(sp) ldl $14, SWITCH_STACK_R14(sp) ldl $15, SWITCH_STACK_R15(sp) ldi sp, SWITCH_STACK_SIZE(sp) /* restore host regs from host sp */ ldl $8, PT_REGS_R8(sp) ldl $26, PT_REGS_R26(sp) ldi sp, PT_REGS_SIZE(sp) /* restore host fpregs */ ldl $1, TI_TASK($8) ldi $1, TASK_THREAD($1) fldd $f0, THREAD_FPCR($1) wfpcr $f0 fimovd $f0, $2 and $2, 0x3, $2 beq $2, $setfpec_0 subl $2, 0x1, $2 beq $2, $setfpec_1 subl $2, 0x1, $2 beq $2, $setfpec_2 setfpec3 br $setfpec_over $setfpec_0: setfpec0 br $setfpec_over $setfpec_1: setfpec1 br $setfpec_over $setfpec_2: setfpec2 $setfpec_over: ldi $1, THREAD_CTX_FP($1) vldd $f2, CTX_FP_F2($1) vldd $f3, CTX_FP_F3($1) vldd $f4, CTX_FP_F4($1) vldd $f5, CTX_FP_F5($1) vldd $f6, CTX_FP_F6($1) vldd $f7, CTX_FP_F7($1) vldd $f8, CTX_FP_F8($1) vldd $f9, CTX_FP_F9($1) /* if $0 > 0, handle hcall */ bgt $0, $ret_to stl $26, VCPU_RET_RA(sp) stl $0, VCPU_RET_R0(sp) /* Hmcode will setup in */ /* restore $16 $17 $18, do interrupt trick */ ldi sp, -(HOST_INT_SIZE + PT_REGS_SIZE + SWITCH_STACK_SIZE)(sp) ldl $16, HOST_INT_R16(sp) ldl $17, HOST_INT_R17(sp) ldl $18, HOST_INT_R18(sp) ldi sp, (HOST_INT_SIZE + PT_REGS_SIZE + SWITCH_STACK_SIZE)(sp) ldi $8, 0x3fff bic sp, $8, $8 ldi $19, -PT_REGS_SIZE(sp) ldi $26, ret_from_do_entInt_noregs call $31, do_entInt /* ret($0) indicate hcall number */ ret_from_do_entInt_noregs: ldl $26, VCPU_RET_RA(sp) ldl $0, VCPU_RET_R0(sp) /* restore r16 - r19 */ $ret_to: ldi sp, VCPU_RET_SIZE(sp) /* pop stack */ ret