summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include/asm/kvm_book3s_asm.h
blob: d978fdf698af2ad5e89a4243e7bf2efe3e4e15bb (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
 * 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, write to the Free Software
 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * Copyright SUSE Linux Products GmbH 2009
 *
 * Authors: Alexander Graf <agraf@suse.de>
 */

#ifndef __ASM_KVM_BOOK3S_ASM_H__
#define __ASM_KVM_BOOK3S_ASM_H__

/* XICS ICP register offsets */
#define XICS_XIRR		4
#define XICS_MFRR		0xc
#define XICS_IPI		2	/* interrupt source # for IPIs */

/* Maximum number of threads per physical core */
#define MAX_SMT_THREADS		8

/* Maximum number of subcores per physical core */
#define MAX_SUBCORES		4

#ifdef __ASSEMBLY__

#ifdef CONFIG_KVM_BOOK3S_HANDLER

#include <asm/kvm_asm.h>

.macro DO_KVM intno
	.if (\intno == BOOK3S_INTERRUPT_SYSTEM_RESET) || \
	    (\intno == BOOK3S_INTERRUPT_MACHINE_CHECK) || \
	    (\intno == BOOK3S_INTERRUPT_DATA_STORAGE) || \
	    (\intno == BOOK3S_INTERRUPT_INST_STORAGE) || \
	    (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \
	    (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \
	    (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \
	    (\intno == BOOK3S_INTERRUPT_EXTERNAL_HV) || \
	    (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \
	    (\intno == BOOK3S_INTERRUPT_PROGRAM) || \
	    (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \
	    (\intno == BOOK3S_INTERRUPT_DECREMENTER) || \
	    (\intno == BOOK3S_INTERRUPT_SYSCALL) || \
	    (\intno == BOOK3S_INTERRUPT_TRACE) || \
	    (\intno == BOOK3S_INTERRUPT_PERFMON) || \
	    (\intno == BOOK3S_INTERRUPT_ALTIVEC) || \
	    (\intno == BOOK3S_INTERRUPT_VSX)

	b	kvmppc_trampoline_\intno
kvmppc_resume_\intno:

	.endif
.endm

#else

.macro DO_KVM intno
.endm

#endif /* CONFIG_KVM_BOOK3S_HANDLER */

#else  /*__ASSEMBLY__ */

struct kvmppc_vcore;

/* Struct used for coordinating micro-threading (split-core) mode changes */
struct kvm_split_mode {
	unsigned long	rpr;
	unsigned long	pmmar;
	unsigned long	ldbar;
	u8		subcore_size;
	u8		do_nap;
	u8		napped[MAX_SMT_THREADS];
	struct kvmppc_vcore *vc[MAX_SUBCORES];
	/* Bits for changing lpcr on P9 */
	unsigned long	lpcr_req;
	unsigned long	lpidr_req;
	unsigned long	host_lpcr;
	u32		do_set;
	u32		do_restore;
	union {
		u32	allphases;
		u8	phase[4];
	} lpcr_sync;
};

/*
 * This struct goes in the PACA on 64-bit processors.  It is used
 * to store host state that needs to be saved when we enter a guest
 * and restored when we exit, but isn't specific to any particular
 * guest or vcpu.  It also has some scratch fields used by the guest
 * exit code.
 */
struct kvmppc_host_state {
	ulong host_r1;
	ulong host_r2;
	ulong host_msr;
	ulong vmhandler;
	ulong scratch0;
	ulong scratch1;
	ulong scratch2;
	u8 in_guest;
	u8 restore_hid5;
	u8 napping;

#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
	u8 hwthread_req;
	u8 hwthread_state;
	u8 host_ipi;
	u8 ptid;		/* thread number within subcore when split */
	u8 tid;			/* thread number within whole core */
	u8 fake_suspend;
	struct kvm_vcpu *kvm_vcpu;
	struct kvmppc_vcore *kvm_vcore;
	void __iomem *xics_phys;
	void __iomem *xive_tima_phys;
	void __iomem *xive_tima_virt;
	u32 saved_xirr;
	u64 dabr;
	u64 host_mmcr[7];	/* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */
	u32 host_pmc[8];
	u64 host_purr;
	u64 host_spurr;
	u64 host_dscr;
	u64 dec_expires;
	struct kvm_split_mode *kvm_split_mode;
#endif
#ifdef CONFIG_PPC_BOOK3S_64
	u64 cfar;
	u64 ppr;
	u64 host_fscr;
#endif
};

struct kvmppc_book3s_shadow_vcpu {
	bool in_use;
	ulong gpr[14];
	u32 cr;
	ulong xer;
	ulong ctr;
	ulong lr;
	ulong pc;

	ulong shadow_srr1;
	ulong fault_dar;
	u32 fault_dsisr;
	u32 last_inst;

#ifdef CONFIG_PPC_BOOK3S_32
	u32     sr[16];			/* Guest SRs */

	struct kvmppc_host_state hstate;
#endif

#ifdef CONFIG_PPC_BOOK3S_64
	u8 slb_max;			/* highest used guest slb entry */
	struct  {
		u64     esid;
		u64     vsid;
	} slb[64];			/* guest SLB */
	u64 shadow_fscr;
#endif
};

#endif /*__ASSEMBLY__ */

/* Values for kvm_state */
#define KVM_HWTHREAD_IN_KERNEL	0
#define KVM_HWTHREAD_IN_IDLE	1
#define KVM_HWTHREAD_IN_KVM	2

#endif /* __ASM_KVM_BOOK3S_ASM_H__ */
OpenPOWER on IntegriCloud