1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
5 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
7 * Mostly rewritten in C by Marc Zyngier <marc.zyngier@arm.com>
10 #include <asm/kvm_hyp.h>
13 * gcc before 4.9 doesn't understand -march=armv7ve, so we have to
14 * trick the assembler.
16 __asm__(".arch_extension virt");
18 void __hyp_text
__banked_save_state(struct kvm_cpu_context
*ctxt
)
20 ctxt
->gp_regs
.usr_regs
.ARM_sp
= read_special(SP_usr
);
21 ctxt
->gp_regs
.usr_regs
.ARM_pc
= read_special(ELR_hyp
);
22 ctxt
->gp_regs
.usr_regs
.ARM_cpsr
= read_special(SPSR
);
23 ctxt
->gp_regs
.KVM_ARM_SVC_sp
= read_special(SP_svc
);
24 ctxt
->gp_regs
.KVM_ARM_SVC_lr
= read_special(LR_svc
);
25 ctxt
->gp_regs
.KVM_ARM_SVC_spsr
= read_special(SPSR_svc
);
26 ctxt
->gp_regs
.KVM_ARM_ABT_sp
= read_special(SP_abt
);
27 ctxt
->gp_regs
.KVM_ARM_ABT_lr
= read_special(LR_abt
);
28 ctxt
->gp_regs
.KVM_ARM_ABT_spsr
= read_special(SPSR_abt
);
29 ctxt
->gp_regs
.KVM_ARM_UND_sp
= read_special(SP_und
);
30 ctxt
->gp_regs
.KVM_ARM_UND_lr
= read_special(LR_und
);
31 ctxt
->gp_regs
.KVM_ARM_UND_spsr
= read_special(SPSR_und
);
32 ctxt
->gp_regs
.KVM_ARM_IRQ_sp
= read_special(SP_irq
);
33 ctxt
->gp_regs
.KVM_ARM_IRQ_lr
= read_special(LR_irq
);
34 ctxt
->gp_regs
.KVM_ARM_IRQ_spsr
= read_special(SPSR_irq
);
35 ctxt
->gp_regs
.KVM_ARM_FIQ_r8
= read_special(R8_fiq
);
36 ctxt
->gp_regs
.KVM_ARM_FIQ_r9
= read_special(R9_fiq
);
37 ctxt
->gp_regs
.KVM_ARM_FIQ_r10
= read_special(R10_fiq
);
38 ctxt
->gp_regs
.KVM_ARM_FIQ_fp
= read_special(R11_fiq
);
39 ctxt
->gp_regs
.KVM_ARM_FIQ_ip
= read_special(R12_fiq
);
40 ctxt
->gp_regs
.KVM_ARM_FIQ_sp
= read_special(SP_fiq
);
41 ctxt
->gp_regs
.KVM_ARM_FIQ_lr
= read_special(LR_fiq
);
42 ctxt
->gp_regs
.KVM_ARM_FIQ_spsr
= read_special(SPSR_fiq
);
45 void __hyp_text
__banked_restore_state(struct kvm_cpu_context
*ctxt
)
47 write_special(ctxt
->gp_regs
.usr_regs
.ARM_sp
, SP_usr
);
48 write_special(ctxt
->gp_regs
.usr_regs
.ARM_pc
, ELR_hyp
);
49 write_special(ctxt
->gp_regs
.usr_regs
.ARM_cpsr
, SPSR_cxsf
);
50 write_special(ctxt
->gp_regs
.KVM_ARM_SVC_sp
, SP_svc
);
51 write_special(ctxt
->gp_regs
.KVM_ARM_SVC_lr
, LR_svc
);
52 write_special(ctxt
->gp_regs
.KVM_ARM_SVC_spsr
, SPSR_svc
);
53 write_special(ctxt
->gp_regs
.KVM_ARM_ABT_sp
, SP_abt
);
54 write_special(ctxt
->gp_regs
.KVM_ARM_ABT_lr
, LR_abt
);
55 write_special(ctxt
->gp_regs
.KVM_ARM_ABT_spsr
, SPSR_abt
);
56 write_special(ctxt
->gp_regs
.KVM_ARM_UND_sp
, SP_und
);
57 write_special(ctxt
->gp_regs
.KVM_ARM_UND_lr
, LR_und
);
58 write_special(ctxt
->gp_regs
.KVM_ARM_UND_spsr
, SPSR_und
);
59 write_special(ctxt
->gp_regs
.KVM_ARM_IRQ_sp
, SP_irq
);
60 write_special(ctxt
->gp_regs
.KVM_ARM_IRQ_lr
, LR_irq
);
61 write_special(ctxt
->gp_regs
.KVM_ARM_IRQ_spsr
, SPSR_irq
);
62 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_r8
, R8_fiq
);
63 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_r9
, R9_fiq
);
64 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_r10
, R10_fiq
);
65 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_fp
, R11_fiq
);
66 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_ip
, R12_fiq
);
67 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_sp
, SP_fiq
);
68 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_lr
, LR_fiq
);
69 write_special(ctxt
->gp_regs
.KVM_ARM_FIQ_spsr
, SPSR_fiq
);