Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * Copyright (C) 2016 - ARM Ltd
3 * Author: Marc Zyngier <marc.zyngier@arm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <linux/linkage.h>
19#include <asm/asm-offsets.h>
20#include <asm/kvm_arm.h>
21
22 .arch_extension virt
23
24 .text
25 .pushsection .hyp.text, "ax"
26
27#define USR_REGS_OFFSET (CPU_CTXT_GP_REGS + GP_REGS_USR)
28
29/* int __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host) */
30ENTRY(__guest_enter)
31 @ Save host registers
32 add r1, r1, #(USR_REGS_OFFSET + S_R4)
33 stm r1!, {r4-r12}
34 str lr, [r1, #4] @ Skip SP_usr (already saved)
35
36 @ Restore guest registers
37 add r0, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R0)
38 ldr lr, [r0, #S_LR]
39 ldm r0, {r0-r12}
40
41 clrex
42 eret
43ENDPROC(__guest_enter)
44
45ENTRY(__guest_exit)
46 /*
47 * return convention:
48 * guest r0, r1, r2 saved on the stack
49 * r0: vcpu pointer
50 * r1: exception code
51 */
52
53 add r2, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R3)
54 stm r2!, {r3-r12}
55 str lr, [r2, #4]
56 add r2, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R0)
57 pop {r3, r4, r5} @ r0, r1, r2
58 stm r2, {r3-r5}
59
60 ldr r0, [r0, #VCPU_HOST_CTXT]
61 add r0, r0, #(USR_REGS_OFFSET + S_R4)
62 ldm r0!, {r4-r12}
63 ldr lr, [r0, #4]
64
65 mov r0, r1
66 bx lr
67ENDPROC(__guest_exit)
68
69/*
70 * If VFPv3 support is not available, then we will not switch the VFP
71 * registers; however cp10 and cp11 accesses will still trap and fallback
72 * to the regular coprocessor emulation code, which currently will
73 * inject an undefined exception to the guest.
74 */
75#ifdef CONFIG_VFPv3
76ENTRY(__vfp_guest_restore)
77 push {r3, r4, lr}
78
79 @ NEON/VFP used. Turn on VFP access.
80 mrc p15, 4, r1, c1, c1, 2 @ HCPTR
81 bic r1, r1, #(HCPTR_TCP(10) | HCPTR_TCP(11))
82 mcr p15, 4, r1, c1, c1, 2 @ HCPTR
83 isb
84
85 @ Switch VFP/NEON hardware state to the guest's
86 mov r4, r0
87 ldr r0, [r0, #VCPU_HOST_CTXT]
88 add r0, r0, #CPU_CTXT_VFP
89 bl __vfp_save_state
90 add r0, r4, #(VCPU_GUEST_CTXT + CPU_CTXT_VFP)
91 bl __vfp_restore_state
92
93 pop {r3, r4, lr}
94 pop {r0, r1, r2}
95 clrex
96 eret
97ENDPROC(__vfp_guest_restore)
98#endif
99
100 .popsection
101