summaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/kvm_hyp.h
blob: f0e86076138077fd4bf49409c5c4136e136b3bc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright (C) 2015 - ARM Ltd
 * Author: Marc Zyngier <marc.zyngier@arm.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __ARM_KVM_HYP_H__
#define __ARM_KVM_HYP_H__

#include <linux/compiler.h>
#include <linux/kvm_host.h>
#include <asm/kvm_mmu.h>
#include <asm/vfp.h>

#define __hyp_text __section(.hyp.text) notrace

#define kern_hyp_va(v) (v)
#define hyp_kern_va(v) (v)

#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
#define __ACCESS_CP15_64(Op1, CRm)		\
	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
#define __ACCESS_VFP(CRn)			\
	"mrc", "mcr", __stringify(p10, 7, %0, CRn, cr0, 0), u32

#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)

#define __read_sysreg(r, w, c, t) ({				\
	t __val;						\
	asm volatile(r " " c : "=r" (__val));			\
	__val;							\
})
#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)

#define write_special(v, r)					\
	asm volatile("msr " __stringify(r) ", %0" : : "r" (v))
#define read_special(r) ({					\
	u32 __val;						\
	asm volatile("mrs %0, " __stringify(r) : "=r" (__val));	\
	__val;							\
})

#define TTBR0		__ACCESS_CP15_64(0, c2)
#define TTBR1		__ACCESS_CP15_64(1, c2)
#define VTTBR		__ACCESS_CP15_64(6, c2)
#define PAR		__ACCESS_CP15_64(0, c7)
#define CNTV_CVAL	__ACCESS_CP15_64(3, c14)
#define CNTVOFF		__ACCESS_CP15_64(4, c14)

#define MIDR		__ACCESS_CP15(c0, 0, c0, 0)
#define CSSELR		__ACCESS_CP15(c0, 2, c0, 0)
#define VPIDR		__ACCESS_CP15(c0, 4, c0, 0)
#define VMPIDR		__ACCESS_CP15(c0, 4, c0, 5)
#define SCTLR		__ACCESS_CP15(c1, 0, c0, 0)
#define CPACR		__ACCESS_CP15(c1, 0, c0, 2)
#define HCR		__ACCESS_CP15(c1, 4, c1, 0)
#define HDCR		__ACCESS_CP15(c1, 4, c1, 1)
#define HCPTR		__ACCESS_CP15(c1, 4, c1, 2)
#define HSTR		__ACCESS_CP15(c1, 4, c1, 3)
#define TTBCR		__ACCESS_CP15(c2, 0, c0, 2)
#define HTCR		__ACCESS_CP15(c2, 4, c0, 2)
#define VTCR		__ACCESS_CP15(c2, 4, c1, 2)
#define DACR		__ACCESS_CP15(c3, 0, c0, 0)
#define DFSR		__ACCESS_CP15(c5, 0, c0, 0)
#define IFSR		__ACCESS_CP15(c5, 0, c0, 1)
#define ADFSR		__ACCESS_CP15(c5, 0, c1, 0)
#define AIFSR		__ACCESS_CP15(c5, 0, c1, 1)
#define HSR		__ACCESS_CP15(c5, 4, c2, 0)
#define DFAR		__ACCESS_CP15(c6, 0, c0, 0)
#define IFAR		__ACCESS_CP15(c6, 0, c0, 2)
#define HDFAR		__ACCESS_CP15(c6, 4, c0, 0)
#define HIFAR		__ACCESS_CP15(c6, 4, c0, 2)
#define HPFAR		__ACCESS_CP15(c6, 4, c0, 4)
#define ICIALLUIS	__ACCESS_CP15(c7, 0, c1, 0)
#define ATS1CPR		__ACCESS_CP15(c7, 0, c8, 0)
#define TLBIALLIS	__ACCESS_CP15(c8, 0, c3, 0)
#define TLBIALLNSNHIS	__ACCESS_CP15(c8, 4, c3, 4)
#define PRRR		__ACCESS_CP15(c10, 0, c2, 0)
#define NMRR		__ACCESS_CP15(c10, 0, c2, 1)
#define AMAIR0		__ACCESS_CP15(c10, 0, c3, 0)
#define AMAIR1		__ACCESS_CP15(c10, 0, c3, 1)
#define VBAR		__ACCESS_CP15(c12, 0, c0, 0)
#define CID		__ACCESS_CP15(c13, 0, c0, 1)
#define TID_URW		__ACCESS_CP15(c13, 0, c0, 2)
#define TID_URO		__ACCESS_CP15(c13, 0, c0, 3)
#define TID_PRIV	__ACCESS_CP15(c13, 0, c0, 4)
#define HTPIDR		__ACCESS_CP15(c13, 4, c0, 2)
#define CNTKCTL		__ACCESS_CP15(c14, 0, c1, 0)
#define CNTV_CTL	__ACCESS_CP15(c14, 0, c3, 1)
#define CNTHCTL		__ACCESS_CP15(c14, 4, c1, 0)

#define VFP_FPEXC	__ACCESS_VFP(FPEXC)

/* AArch64 compatibility macros, only for the timer so far */
#define read_sysreg_el0(r)		read_sysreg(r##_el0)
#define write_sysreg_el0(v, r)		write_sysreg(v, r##_el0)

#define cntv_ctl_el0			CNTV_CTL
#define cntv_cval_el0			CNTV_CVAL
#define cntvoff_el2			CNTVOFF
#define cnthctl_el2			CNTHCTL

void __timer_save_state(struct kvm_vcpu *vcpu);
void __timer_restore_state(struct kvm_vcpu *vcpu);

void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);

void __sysreg_save_state(struct kvm_cpu_context *ctxt);
void __sysreg_restore_state(struct kvm_cpu_context *ctxt);

void asmlinkage __vfp_save_state(struct vfp_hard_struct *vfp);
void asmlinkage __vfp_restore_state(struct vfp_hard_struct *vfp);
static inline bool __vfp_enabled(void)
{
	return !(read_sysreg(HCPTR) & (HCPTR_TCP(11) | HCPTR_TCP(10)));
}

void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt);
void __hyp_text __banked_restore_state(struct kvm_cpu_context *ctxt);

int asmlinkage __guest_enter(struct kvm_vcpu *vcpu,
			     struct kvm_cpu_context *host);
int asmlinkage __hyp_do_panic(const char *, int, u32);

#endif /* __ARM_KVM_HYP_H__ */
OpenPOWER on IntegriCloud