aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-11-05 01:16:13 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-11-05 01:16:13 -0500
commitd4e09f8432a428d6a46ca4f3c2b28d0385f5b93d (patch)
treec5d7ef8e5a9e69e011e6361f076b43d3e3767575 /arch/powerpc
parent41c8c46bfe52488779e227b77222402579573ccf (diff)
parent544c6761bb05a1dd19a39cb9bed096273f9bdb36 (diff)
Merge branch 'kvm' into next
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/exception-64s.h2
-rw-r--r--arch/powerpc/include/asm/kvm.h2
-rw-r--r--arch/powerpc/include/asm/kvm_asm.h39
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h136
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64_asm.h58
-rw-r--r--arch/powerpc/include/asm/kvm_host.h79
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h1
-rw-r--r--arch/powerpc/include/asm/mmu_context.h2
-rw-r--r--arch/powerpc/include/asm/paca.h9
-rw-r--r--arch/powerpc/kernel/asm-offsets.c18
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S8
-rw-r--r--arch/powerpc/kernel/head_64.S7
-rw-r--r--arch/powerpc/kernel/time.c1
-rw-r--r--arch/powerpc/kvm/Kconfig17
-rw-r--r--arch/powerpc/kvm/Makefile27
-rw-r--r--arch/powerpc/kvm/book3s.c925
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu.c372
-rw-r--r--arch/powerpc/kvm/book3s_64_emulate.c337
-rw-r--r--arch/powerpc/kvm/book3s_64_exports.c24
-rw-r--r--arch/powerpc/kvm/book3s_64_interrupts.S392
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu.c476
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_host.c408
-rw-r--r--arch/powerpc/kvm/book3s_64_rmhandlers.S131
-rw-r--r--arch/powerpc/kvm/book3s_64_slb.S262
-rw-r--r--arch/powerpc/kvm/booke.c5
-rw-r--r--arch/powerpc/kvm/emulate.c66
-rw-r--r--arch/powerpc/kvm/powerpc.c25
-rw-r--r--arch/powerpc/kvm/trace.h6
-rw-r--r--arch/powerpc/mm/hash_utils_64.c2
-rw-r--r--arch/powerpc/mm/mmu_context_hash64.c24
30 files changed, 3830 insertions, 31 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index a98653b26231..57c400071995 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -147,6 +147,7 @@
147 .globl label##_pSeries; \ 147 .globl label##_pSeries; \
148label##_pSeries: \ 148label##_pSeries: \
149 HMT_MEDIUM; \ 149 HMT_MEDIUM; \
150 DO_KVM n; \
150 mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ 151 mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
151 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 152 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
152 153
@@ -170,6 +171,7 @@ label##_pSeries: \
170 .globl label##_pSeries; \ 171 .globl label##_pSeries; \
171label##_pSeries: \ 172label##_pSeries: \
172 HMT_MEDIUM; \ 173 HMT_MEDIUM; \
174 DO_KVM n; \
173 mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ 175 mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
174 mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \ 176 mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \
175 std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ 177 std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index bb2de6aa5ce0..c9ca97f43bc1 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -46,6 +46,8 @@ struct kvm_regs {
46}; 46};
47 47
48struct kvm_sregs { 48struct kvm_sregs {
49 __u32 pvr;
50 char pad[1020];
49}; 51};
50 52
51struct kvm_fpu { 53struct kvm_fpu {
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 56bfae59837f..19ddb352fd0f 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -49,6 +49,45 @@
49#define BOOKE_INTERRUPT_SPE_FP_ROUND 34 49#define BOOKE_INTERRUPT_SPE_FP_ROUND 34
50#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35 50#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
51 51
52/* book3s */
53
54#define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100
55#define BOOK3S_INTERRUPT_MACHINE_CHECK 0x200
56#define BOOK3S_INTERRUPT_DATA_STORAGE 0x300
57#define BOOK3S_INTERRUPT_DATA_SEGMENT 0x380
58#define BOOK3S_INTERRUPT_INST_STORAGE 0x400
59#define BOOK3S_INTERRUPT_INST_SEGMENT 0x480
60#define BOOK3S_INTERRUPT_EXTERNAL 0x500
61#define BOOK3S_INTERRUPT_ALIGNMENT 0x600
62#define BOOK3S_INTERRUPT_PROGRAM 0x700
63#define BOOK3S_INTERRUPT_FP_UNAVAIL 0x800
64#define BOOK3S_INTERRUPT_DECREMENTER 0x900
65#define BOOK3S_INTERRUPT_SYSCALL 0xc00
66#define BOOK3S_INTERRUPT_TRACE 0xd00
67#define BOOK3S_INTERRUPT_PERFMON 0xf00
68#define BOOK3S_INTERRUPT_ALTIVEC 0xf20
69#define BOOK3S_INTERRUPT_VSX 0xf40
70
71#define BOOK3S_IRQPRIO_SYSTEM_RESET 0
72#define BOOK3S_IRQPRIO_DATA_SEGMENT 1
73#define BOOK3S_IRQPRIO_INST_SEGMENT 2
74#define BOOK3S_IRQPRIO_DATA_STORAGE 3
75#define BOOK3S_IRQPRIO_INST_STORAGE 4
76#define BOOK3S_IRQPRIO_ALIGNMENT 5
77#define BOOK3S_IRQPRIO_PROGRAM 6
78#define BOOK3S_IRQPRIO_FP_UNAVAIL 7
79#define BOOK3S_IRQPRIO_ALTIVEC 8
80#define BOOK3S_IRQPRIO_VSX 9
81#define BOOK3S_IRQPRIO_SYSCALL 10
82#define BOOK3S_IRQPRIO_MACHINE_CHECK 11
83#define BOOK3S_IRQPRIO_DEBUG 12
84#define BOOK3S_IRQPRIO_EXTERNAL 13
85#define BOOK3S_IRQPRIO_DECREMENTER 14
86#define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR 15
87#define BOOK3S_IRQPRIO_MAX 16
88
89#define BOOK3S_HFLAG_DCBZ32 0x1
90
52#define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ 91#define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */
53#define RESUME_FLAG_HOST (1<<1) /* Resume host? */ 92#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
54 93
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
new file mode 100644
index 000000000000..c6011336371e
--- /dev/null
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -0,0 +1,136 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#ifndef __ASM_KVM_BOOK3S_H__
21#define __ASM_KVM_BOOK3S_H__
22
23#include <linux/types.h>
24#include <linux/kvm_host.h>
25#include <asm/kvm_ppc.h>
26
27struct kvmppc_slb {
28 u64 esid;
29 u64 vsid;
30 u64 orige;
31 u64 origv;
32 bool valid;
33 bool Ks;
34 bool Kp;
35 bool nx;
36 bool large;
37 bool class;
38};
39
40struct kvmppc_sr {
41 u32 raw;
42 u32 vsid;
43 bool Ks;
44 bool Kp;
45 bool nx;
46};
47
48struct kvmppc_bat {
49 u32 bepi;
50 u32 bepi_mask;
51 bool vs;
52 bool vp;
53 u32 brpn;
54 u8 wimg;
55 u8 pp;
56};
57
58struct kvmppc_sid_map {
59 u64 guest_vsid;
60 u64 guest_esid;
61 u64 host_vsid;
62 bool valid;
63};
64
65#define SID_MAP_BITS 9
66#define SID_MAP_NUM (1 << SID_MAP_BITS)
67#define SID_MAP_MASK (SID_MAP_NUM - 1)
68
69struct kvmppc_vcpu_book3s {
70 struct kvm_vcpu vcpu;
71 struct kvmppc_sid_map sid_map[SID_MAP_NUM];
72 struct kvmppc_slb slb[64];
73 struct {
74 u64 esid;
75 u64 vsid;
76 } slb_shadow[64];
77 u8 slb_shadow_max;
78 struct kvmppc_sr sr[16];
79 struct kvmppc_bat ibat[8];
80 struct kvmppc_bat dbat[8];
81 u64 hid[6];
82 int slb_nr;
83 u64 sdr1;
84 u64 dsisr;
85 u64 hior;
86 u64 msr_mask;
87 u64 vsid_first;
88 u64 vsid_next;
89 u64 vsid_max;
90 int context_id;
91};
92
93#define CONTEXT_HOST 0
94#define CONTEXT_GUEST 1
95#define CONTEXT_GUEST_END 2
96
97#define VSID_REAL 0xfffffffffff00000
98#define VSID_REAL_DR 0xffffffffffe00000
99#define VSID_REAL_IR 0xffffffffffd00000
100#define VSID_BAT 0xffffffffffc00000
101#define VSID_PR 0x8000000000000000
102
103extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask);
104extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask);
105extern void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end);
106extern void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 new_msr);
107extern void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu);
108extern void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu);
109extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte);
110extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr);
111extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu);
112extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data);
113extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data);
114extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr);
115extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
116
117extern u32 kvmppc_trampoline_lowmem;
118extern u32 kvmppc_trampoline_enter;
119
120static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
121{
122 return container_of(vcpu, struct kvmppc_vcpu_book3s, vcpu);
123}
124
125static inline ulong dsisr(void)
126{
127 ulong r;
128 asm ( "mfdsisr %0 " : "=r" (r) );
129 return r;
130}
131
132extern void kvm_return_point(void);
133
134#define INS_DCBZ 0x7c0007ec
135
136#endif /* __ASM_KVM_BOOK3S_H__ */
diff --git a/arch/powerpc/include/asm/kvm_book3s_64_asm.h b/arch/powerpc/include/asm/kvm_book3s_64_asm.h
new file mode 100644
index 000000000000..2e06ee8184ef
--- /dev/null
+++ b/arch/powerpc/include/asm/kvm_book3s_64_asm.h
@@ -0,0 +1,58 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#ifndef __ASM_KVM_BOOK3S_ASM_H__
21#define __ASM_KVM_BOOK3S_ASM_H__
22
23#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
24
25#include <asm/kvm_asm.h>
26
27.macro DO_KVM intno
28 .if (\intno == BOOK3S_INTERRUPT_SYSTEM_RESET) || \
29 (\intno == BOOK3S_INTERRUPT_MACHINE_CHECK) || \
30 (\intno == BOOK3S_INTERRUPT_DATA_STORAGE) || \
31 (\intno == BOOK3S_INTERRUPT_INST_STORAGE) || \
32 (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \
33 (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \
34 (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \
35 (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \
36 (\intno == BOOK3S_INTERRUPT_PROGRAM) || \
37 (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \
38 (\intno == BOOK3S_INTERRUPT_DECREMENTER) || \
39 (\intno == BOOK3S_INTERRUPT_SYSCALL) || \
40 (\intno == BOOK3S_INTERRUPT_TRACE) || \
41 (\intno == BOOK3S_INTERRUPT_PERFMON) || \
42 (\intno == BOOK3S_INTERRUPT_ALTIVEC) || \
43 (\intno == BOOK3S_INTERRUPT_VSX)
44
45 b kvmppc_trampoline_\intno
46kvmppc_resume_\intno:
47
48 .endif
49.endm
50
51#else
52
53.macro DO_KVM intno
54.endm
55
56#endif /* CONFIG_KVM_BOOK3S_64_HANDLER */
57
58#endif /* __ASM_KVM_BOOK3S_ASM_H__ */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index c9c930ed11d7..1201f62d0d73 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -21,7 +21,8 @@
21#define __POWERPC_KVM_HOST_H__ 21#define __POWERPC_KVM_HOST_H__
22 22
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/timer.h> 24#include <linux/hrtimer.h>
25#include <linux/interrupt.h>
25#include <linux/types.h> 26#include <linux/types.h>
26#include <linux/kvm_types.h> 27#include <linux/kvm_types.h>
27#include <asm/kvm_asm.h> 28#include <asm/kvm_asm.h>
@@ -37,6 +38,8 @@
37#define KVM_NR_PAGE_SIZES 1 38#define KVM_NR_PAGE_SIZES 1
38#define KVM_PAGES_PER_HPAGE(x) (1UL<<31) 39#define KVM_PAGES_PER_HPAGE(x) (1UL<<31)
39 40
41#define HPTEG_CACHE_NUM 1024
42
40struct kvm; 43struct kvm;
41struct kvm_run; 44struct kvm_run;
42struct kvm_vcpu; 45struct kvm_vcpu;
@@ -63,6 +66,17 @@ struct kvm_vcpu_stat {
63 u32 dec_exits; 66 u32 dec_exits;
64 u32 ext_intr_exits; 67 u32 ext_intr_exits;
65 u32 halt_wakeup; 68 u32 halt_wakeup;
69#ifdef CONFIG_PPC64
70 u32 pf_storage;
71 u32 pf_instruc;
72 u32 sp_storage;
73 u32 sp_instruc;
74 u32 queue_intr;
75 u32 ld;
76 u32 ld_slow;
77 u32 st;
78 u32 st_slow;
79#endif
66}; 80};
67 81
68enum kvm_exit_types { 82enum kvm_exit_types {
@@ -109,9 +123,53 @@ struct kvmppc_exit_timing {
109struct kvm_arch { 123struct kvm_arch {
110}; 124};
111 125
126struct kvmppc_pte {
127 u64 eaddr;
128 u64 vpage;
129 u64 raddr;
130 bool may_read;
131 bool may_write;
132 bool may_execute;
133};
134
135struct kvmppc_mmu {
136 /* book3s_64 only */
137 void (*slbmte)(struct kvm_vcpu *vcpu, u64 rb, u64 rs);
138 u64 (*slbmfee)(struct kvm_vcpu *vcpu, u64 slb_nr);
139 u64 (*slbmfev)(struct kvm_vcpu *vcpu, u64 slb_nr);
140 void (*slbie)(struct kvm_vcpu *vcpu, u64 slb_nr);
141 void (*slbia)(struct kvm_vcpu *vcpu);
142 /* book3s */
143 void (*mtsrin)(struct kvm_vcpu *vcpu, u32 srnum, ulong value);
144 u32 (*mfsrin)(struct kvm_vcpu *vcpu, u32 srnum);
145 int (*xlate)(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data);
146 void (*reset_msr)(struct kvm_vcpu *vcpu);
147 void (*tlbie)(struct kvm_vcpu *vcpu, ulong addr, bool large);
148 int (*esid_to_vsid)(struct kvm_vcpu *vcpu, u64 esid, u64 *vsid);
149 u64 (*ea_to_vp)(struct kvm_vcpu *vcpu, gva_t eaddr, bool data);
150 bool (*is_dcbz32)(struct kvm_vcpu *vcpu);
151};
152
153struct hpte_cache {
154 u64 host_va;
155 u64 pfn;
156 ulong slot;
157 struct kvmppc_pte pte;
158};
159
112struct kvm_vcpu_arch { 160struct kvm_vcpu_arch {
113 u32 host_stack; 161 ulong host_stack;
114 u32 host_pid; 162 u32 host_pid;
163#ifdef CONFIG_PPC64
164 ulong host_msr;
165 ulong host_r2;
166 void *host_retip;
167 ulong trampoline_lowmem;
168 ulong trampoline_enter;
169 ulong highmem_handler;
170 ulong host_paca_phys;
171 struct kvmppc_mmu mmu;
172#endif
115 173
116 u64 fpr[32]; 174 u64 fpr[32];
117 ulong gpr[32]; 175 ulong gpr[32];
@@ -123,6 +181,10 @@ struct kvm_vcpu_arch {
123 ulong xer; 181 ulong xer;
124 182
125 ulong msr; 183 ulong msr;
184#ifdef CONFIG_PPC64
185 ulong shadow_msr;
186 ulong hflags;
187#endif
126 u32 mmucr; 188 u32 mmucr;
127 ulong sprg0; 189 ulong sprg0;
128 ulong sprg1; 190 ulong sprg1;
@@ -149,6 +211,7 @@ struct kvm_vcpu_arch {
149 u32 ivor[64]; 211 u32 ivor[64];
150 ulong ivpr; 212 ulong ivpr;
151 u32 pir; 213 u32 pir;
214 u32 pvr;
152 215
153 u32 shadow_pid; 216 u32 shadow_pid;
154 u32 pid; 217 u32 pid;
@@ -174,6 +237,9 @@ struct kvm_vcpu_arch {
174#endif 237#endif
175 238
176 u32 last_inst; 239 u32 last_inst;
240#ifdef CONFIG_PPC64
241 ulong fault_dsisr;
242#endif
177 ulong fault_dear; 243 ulong fault_dear;
178 ulong fault_esr; 244 ulong fault_esr;
179 gpa_t paddr_accessed; 245 gpa_t paddr_accessed;
@@ -185,8 +251,15 @@ struct kvm_vcpu_arch {
185 251
186 u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ 252 u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */
187 253
188 struct timer_list dec_timer; 254 struct hrtimer dec_timer;
255 struct tasklet_struct tasklet;
256 u64 dec_jiffies;
189 unsigned long pending_exceptions; 257 unsigned long pending_exceptions;
258
259#ifdef CONFIG_PPC64
260 struct hpte_cache hpte_cache[HPTEG_CACHE_NUM];
261 int hpte_cache_offset;
262#endif
190}; 263};
191 264
192#endif /* __POWERPC_KVM_HOST_H__ */ 265#endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 2c6ee349df5e..269ee46ab028 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -39,6 +39,7 @@ enum emulation_result {
39extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); 39extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
40extern char kvmppc_handlers_start[]; 40extern char kvmppc_handlers_start[];
41extern unsigned long kvmppc_handler_len; 41extern unsigned long kvmppc_handler_len;
42extern void kvmppc_handler_highmem(void);
42 43
43extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); 44extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
44extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, 45extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index b34e94d94435..26383e0778aa 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -23,6 +23,8 @@ extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm);
23extern void set_context(unsigned long id, pgd_t *pgd); 23extern void set_context(unsigned long id, pgd_t *pgd);
24 24
25#ifdef CONFIG_PPC_BOOK3S_64 25#ifdef CONFIG_PPC_BOOK3S_64
26extern int __init_new_context(void);
27extern void __destroy_context(int context_id);
26static inline void mmu_context_init(void) { } 28static inline void mmu_context_init(void) { }
27#else 29#else
28extern void mmu_context_init(void); 30extern void mmu_context_init(void);
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 7d8514ceceae..5e9b4ef71415 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -129,6 +129,15 @@ struct paca_struct {
129 u64 system_time; /* accumulated system TB ticks */ 129 u64 system_time; /* accumulated system TB ticks */
130 u64 startpurr; /* PURR/TB value snapshot */ 130 u64 startpurr; /* PURR/TB value snapshot */
131 u64 startspurr; /* SPURR value snapshot */ 131 u64 startspurr; /* SPURR value snapshot */
132
133#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
134 struct {
135 u64 esid;
136 u64 vsid;
137 } kvm_slb[64]; /* guest SLB */
138 u8 kvm_slb_max; /* highest used guest slb entry */
139 u8 kvm_in_guest; /* are we inside the guest? */
140#endif
132}; 141};
133 142
134extern struct paca_struct paca[]; 143extern struct paca_struct paca[];
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 0812b0f414bb..e2e2082acf29 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -190,6 +190,11 @@ int main(void)
190 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); 190 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
191 DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset)); 191 DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
192 DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); 192 DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
193#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
194 DEFINE(PACA_KVM_IN_GUEST, offsetof(struct paca_struct, kvm_in_guest));
195 DEFINE(PACA_KVM_SLB, offsetof(struct paca_struct, kvm_slb));
196 DEFINE(PACA_KVM_SLB_MAX, offsetof(struct paca_struct, kvm_slb_max));
197#endif
193#endif /* CONFIG_PPC64 */ 198#endif /* CONFIG_PPC64 */
194 199
195 /* RTAS */ 200 /* RTAS */
@@ -398,6 +403,19 @@ int main(void)
398 DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); 403 DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
399 DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); 404 DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
400 DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); 405 DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
406
407 /* book3s_64 */
408#ifdef CONFIG_PPC64
409 DEFINE(VCPU_FAULT_DSISR, offsetof(struct kvm_vcpu, arch.fault_dsisr));
410 DEFINE(VCPU_HOST_RETIP, offsetof(struct kvm_vcpu, arch.host_retip));
411 DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2));
412 DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr));
413 DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr));
414 DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem));
415 DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter));
416 DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler));
417 DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
418#endif
401#endif 419#endif
402#ifdef CONFIG_44x 420#ifdef CONFIG_44x
403 DEFINE(PGD_T_LOG2, PGD_T_LOG2); 421 DEFINE(PGD_T_LOG2, PGD_T_LOG2);
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 1808876edcc9..fc3ead066cec 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -41,6 +41,7 @@ __start_interrupts:
41 . = 0x200 41 . = 0x200
42_machine_check_pSeries: 42_machine_check_pSeries:
43 HMT_MEDIUM 43 HMT_MEDIUM
44 DO_KVM 0x200
44 mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ 45 mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
45 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) 46 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
46 47
@@ -48,6 +49,7 @@ _machine_check_pSeries:
48 .globl data_access_pSeries 49 .globl data_access_pSeries
49data_access_pSeries: 50data_access_pSeries:
50 HMT_MEDIUM 51 HMT_MEDIUM
52 DO_KVM 0x300
51 mtspr SPRN_SPRG_SCRATCH0,r13 53 mtspr SPRN_SPRG_SCRATCH0,r13
52BEGIN_FTR_SECTION 54BEGIN_FTR_SECTION
53 mfspr r13,SPRN_SPRG_PACA 55 mfspr r13,SPRN_SPRG_PACA
@@ -77,6 +79,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
77 .globl data_access_slb_pSeries 79 .globl data_access_slb_pSeries
78data_access_slb_pSeries: 80data_access_slb_pSeries:
79 HMT_MEDIUM 81 HMT_MEDIUM
82 DO_KVM 0x380
80 mtspr SPRN_SPRG_SCRATCH0,r13 83 mtspr SPRN_SPRG_SCRATCH0,r13
81 mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ 84 mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
82 std r3,PACA_EXSLB+EX_R3(r13) 85 std r3,PACA_EXSLB+EX_R3(r13)
@@ -115,6 +118,7 @@ data_access_slb_pSeries:
115 .globl instruction_access_slb_pSeries 118 .globl instruction_access_slb_pSeries
116instruction_access_slb_pSeries: 119instruction_access_slb_pSeries:
117 HMT_MEDIUM 120 HMT_MEDIUM
121 DO_KVM 0x480
118 mtspr SPRN_SPRG_SCRATCH0,r13 122 mtspr SPRN_SPRG_SCRATCH0,r13
119 mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ 123 mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
120 std r3,PACA_EXSLB+EX_R3(r13) 124 std r3,PACA_EXSLB+EX_R3(r13)
@@ -154,6 +158,7 @@ instruction_access_slb_pSeries:
154 .globl system_call_pSeries 158 .globl system_call_pSeries
155system_call_pSeries: 159system_call_pSeries:
156 HMT_MEDIUM 160 HMT_MEDIUM
161 DO_KVM 0xc00
157BEGIN_FTR_SECTION 162BEGIN_FTR_SECTION
158 cmpdi r0,0x1ebe 163 cmpdi r0,0x1ebe
159 beq- 1f 164 beq- 1f
@@ -186,12 +191,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
186 * trickery is thus necessary 191 * trickery is thus necessary
187 */ 192 */
188 . = 0xf00 193 . = 0xf00
194 DO_KVM 0xf00
189 b performance_monitor_pSeries 195 b performance_monitor_pSeries
190 196
191 . = 0xf20 197 . = 0xf20
198 DO_KVM 0xf20
192 b altivec_unavailable_pSeries 199 b altivec_unavailable_pSeries
193 200
194 . = 0xf40 201 . = 0xf40
202 DO_KVM 0xf40
195 b vsx_unavailable_pSeries 203 b vsx_unavailable_pSeries
196 204
197#ifdef CONFIG_CBE_RAS 205#ifdef CONFIG_CBE_RAS
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index c38afdb45d7b..925807488022 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -37,6 +37,7 @@
37#include <asm/firmware.h> 37#include <asm/firmware.h>
38#include <asm/page_64.h> 38#include <asm/page_64.h>
39#include <asm/irqflags.h> 39#include <asm/irqflags.h>
40#include <asm/kvm_book3s_64_asm.h>
40 41
41/* The physical memory is layed out such that the secondary processor 42/* The physical memory is layed out such that the secondary processor
42 * spin code sits at 0x0000...0x00ff. On server, the vectors follow 43 * spin code sits at 0x0000...0x00ff. On server, the vectors follow
@@ -165,6 +166,12 @@ exception_marker:
165#include "exceptions-64s.S" 166#include "exceptions-64s.S"
166#endif 167#endif
167 168
169/* KVM trampoline code needs to be close to the interrupt handlers */
170
171#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
172#include "../kvm/book3s_64_rmhandlers.S"
173#endif
174
168_GLOBAL(generic_secondary_thread_init) 175_GLOBAL(generic_secondary_thread_init)
169 mr r24,r3 176 mr r24,r3
170 177
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 92dc844299b6..e05f6af64353 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -268,6 +268,7 @@ void account_system_vtime(struct task_struct *tsk)
268 per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled; 268 per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
269 local_irq_restore(flags); 269 local_irq_restore(flags);
270} 270}
271EXPORT_SYMBOL_GPL(account_system_vtime);
271 272
272/* 273/*
273 * Transfer the user and system times accumulated in the paca 274 * Transfer the user and system times accumulated in the paca
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index c29926846613..07703f72330e 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -21,6 +21,23 @@ config KVM
21 select PREEMPT_NOTIFIERS 21 select PREEMPT_NOTIFIERS
22 select ANON_INODES 22 select ANON_INODES
23 23
24config KVM_BOOK3S_64_HANDLER
25 bool
26
27config KVM_BOOK3S_64
28 tristate "KVM support for PowerPC book3s_64 processors"
29 depends on EXPERIMENTAL && PPC64
30 select KVM
31 select KVM_BOOK3S_64_HANDLER
32 ---help---
33 Support running unmodified book3s_64 and book3s_32 guest kernels
34 in virtual machines on book3s_64 host processors.
35
36 This module provides access to the hardware capabilities through
37 a character device node named /dev/kvm.
38
39 If unsure, say N.
40
24config KVM_440 41config KVM_440
25 bool "KVM support for PowerPC 440 processors" 42 bool "KVM support for PowerPC 440 processors"
26 depends on EXPERIMENTAL && 44x 43 depends on EXPERIMENTAL && 44x
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 37655fe19f2f..56484d652377 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -12,26 +12,45 @@ CFLAGS_44x_tlb.o := -I.
12CFLAGS_e500_tlb.o := -I. 12CFLAGS_e500_tlb.o := -I.
13CFLAGS_emulate.o := -I. 13CFLAGS_emulate.o := -I.
14 14
15kvm-objs := $(common-objs-y) powerpc.o emulate.o 15common-objs-y += powerpc.o emulate.o
16obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o 16obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o
17obj-$(CONFIG_KVM) += kvm.o 17obj-$(CONFIG_KVM_BOOK3S_64_HANDLER) += book3s_64_exports.o
18 18
19AFLAGS_booke_interrupts.o := -I$(obj) 19AFLAGS_booke_interrupts.o := -I$(obj)
20 20
21kvm-440-objs := \ 21kvm-440-objs := \
22 $(common-objs-y) \
22 booke.o \ 23 booke.o \
23 booke_emulate.o \ 24 booke_emulate.o \
24 booke_interrupts.o \ 25 booke_interrupts.o \
25 44x.o \ 26 44x.o \
26 44x_tlb.o \ 27 44x_tlb.o \
27 44x_emulate.o 28 44x_emulate.o
28obj-$(CONFIG_KVM_440) += kvm-440.o 29kvm-objs-$(CONFIG_KVM_440) := $(kvm-440-objs)
29 30
30kvm-e500-objs := \ 31kvm-e500-objs := \
32 $(common-objs-y) \
31 booke.o \ 33 booke.o \
32 booke_emulate.o \ 34 booke_emulate.o \
33 booke_interrupts.o \ 35 booke_interrupts.o \
34 e500.o \ 36 e500.o \
35 e500_tlb.o \ 37 e500_tlb.o \
36 e500_emulate.o 38 e500_emulate.o
37obj-$(CONFIG_KVM_E500) += kvm-e500.o 39kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs)
40
41kvm-book3s_64-objs := \
42 $(common-objs-y) \
43 book3s.o \
44 book3s_64_emulate.o \
45 book3s_64_interrupts.o \
46 book3s_64_mmu_host.o \
47 book3s_64_mmu.o \
48 book3s_32_mmu.o
49kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-objs)
50
51kvm-objs := $(kvm-objs-m) $(kvm-objs-y)
52
53obj-$(CONFIG_KVM_440) += kvm.o
54obj-$(CONFIG_KVM_E500) += kvm.o
55obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o
56
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
new file mode 100644
index 000000000000..42037d46a416
--- /dev/null
+++ b/arch/powerpc/kvm/book3s.c
@@ -0,0 +1,925 @@
1/*
2 * Copyright (C) 2009. SUSE Linux Products GmbH. All rights reserved.
3 *
4 * Authors:
5 * Alexander Graf <agraf@suse.de>
6 * Kevin Wolf <mail@kevin-wolf.de>
7 *
8 * Description:
9 * This file is derived from arch/powerpc/kvm/44x.c,
10 * by Hollis Blanchard <hollisb@us.ibm.com>.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License, version 2, as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/kvm_host.h>
18#include <linux/err.h>
19
20#include <asm/reg.h>
21#include <asm/cputable.h>
22#include <asm/cacheflush.h>
23#include <asm/tlbflush.h>
24#include <asm/uaccess.h>
25#include <asm/io.h>
26#include <asm/kvm_ppc.h>
27#include <asm/kvm_book3s.h>
28#include <asm/mmu_context.h>
29#include <linux/sched.h>
30#include <linux/vmalloc.h>
31
32#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
33
34/* #define EXIT_DEBUG */
35/* #define EXIT_DEBUG_SIMPLE */
36
37/* Without AGGRESSIVE_DEC we only fire off a DEC interrupt when DEC turns 0.
38 * When set, we retrigger a DEC interrupt after that if DEC <= 0.
39 * PPC32 Linux runs faster without AGGRESSIVE_DEC, PPC64 Linux requires it. */
40
41/* #define AGGRESSIVE_DEC */
42
43struct kvm_stats_debugfs_item debugfs_entries[] = {
44 { "exits", VCPU_STAT(sum_exits) },
45 { "mmio", VCPU_STAT(mmio_exits) },
46 { "sig", VCPU_STAT(signal_exits) },
47 { "sysc", VCPU_STAT(syscall_exits) },
48 { "inst_emu", VCPU_STAT(emulated_inst_exits) },
49 { "dec", VCPU_STAT(dec_exits) },
50 { "ext_intr", VCPU_STAT(ext_intr_exits) },
51 { "queue_intr", VCPU_STAT(queue_intr) },
52 { "halt_wakeup", VCPU_STAT(halt_wakeup) },
53 { "pf_storage", VCPU_STAT(pf_storage) },
54 { "sp_storage", VCPU_STAT(sp_storage) },
55 { "pf_instruc", VCPU_STAT(pf_instruc) },
56 { "sp_instruc", VCPU_STAT(sp_instruc) },
57 { "ld", VCPU_STAT(ld) },
58 { "ld_slow", VCPU_STAT(ld_slow) },
59 { "st", VCPU_STAT(st) },
60 { "st_slow", VCPU_STAT(st_slow) },
61 { NULL }
62};
63
64void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
65{
66}
67
68void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
69{
70}
71
72void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
73{
74 memcpy(get_paca()->kvm_slb, to_book3s(vcpu)->slb_shadow, sizeof(get_paca()->kvm_slb));
75 get_paca()->kvm_slb_max = to_book3s(vcpu)->slb_shadow_max;
76}
77
78void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
79{
80 memcpy(to_book3s(vcpu)->slb_shadow, get_paca()->kvm_slb, sizeof(get_paca()->kvm_slb));
81 to_book3s(vcpu)->slb_shadow_max = get_paca()->kvm_slb_max;
82}
83
84#if defined(AGGRESSIVE_DEC) || defined(EXIT_DEBUG)
85static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
86{
87 u64 jd = mftb() - vcpu->arch.dec_jiffies;
88 return vcpu->arch.dec - jd;
89}
90#endif
91
92void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
93{
94 ulong old_msr = vcpu->arch.msr;
95
96#ifdef EXIT_DEBUG
97 printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
98#endif
99 msr &= to_book3s(vcpu)->msr_mask;
100 vcpu->arch.msr = msr;
101 vcpu->arch.shadow_msr = msr | MSR_USER32;
102 vcpu->arch.shadow_msr &= ( MSR_VEC | MSR_VSX | MSR_FP | MSR_FE0 |
103 MSR_USER64 | MSR_SE | MSR_BE | MSR_DE |
104 MSR_FE1);
105
106 if (msr & (MSR_WE|MSR_POW)) {
107 if (!vcpu->arch.pending_exceptions) {
108 kvm_vcpu_block(vcpu);
109 vcpu->stat.halt_wakeup++;
110 }
111 }
112
113 if (((vcpu->arch.msr & (MSR_IR|MSR_DR)) != (old_msr & (MSR_IR|MSR_DR))) ||
114 (vcpu->arch.msr & MSR_PR) != (old_msr & MSR_PR)) {
115 kvmppc_mmu_flush_segments(vcpu);
116 kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc);
117 }
118}
119
120void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
121{
122 vcpu->arch.srr0 = vcpu->arch.pc;
123 vcpu->arch.srr1 = vcpu->arch.msr | flags;
124 vcpu->arch.pc = to_book3s(vcpu)->hior + vec;
125 vcpu->arch.mmu.reset_msr(vcpu);
126}
127
128void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
129{
130 unsigned int prio;
131
132 vcpu->stat.queue_intr++;
133 switch (vec) {
134 case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET; break;
135 case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK; break;
136 case 0x300: prio = BOOK3S_IRQPRIO_DATA_STORAGE; break;
137 case 0x380: prio = BOOK3S_IRQPRIO_DATA_SEGMENT; break;
138 case 0x400: prio = BOOK3S_IRQPRIO_INST_STORAGE; break;
139 case 0x480: prio = BOOK3S_IRQPRIO_INST_SEGMENT; break;
140 case 0x500: prio = BOOK3S_IRQPRIO_EXTERNAL; break;
141 case 0x600: prio = BOOK3S_IRQPRIO_ALIGNMENT; break;
142 case 0x700: prio = BOOK3S_IRQPRIO_PROGRAM; break;
143 case 0x800: prio = BOOK3S_IRQPRIO_FP_UNAVAIL; break;
144 case 0x900: prio = BOOK3S_IRQPRIO_DECREMENTER; break;
145 case 0xc00: prio = BOOK3S_IRQPRIO_SYSCALL; break;
146 case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG; break;
147 case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC; break;
148 case 0xf40: prio = BOOK3S_IRQPRIO_VSX; break;
149 default: prio = BOOK3S_IRQPRIO_MAX; break;
150 }
151
152 set_bit(prio, &vcpu->arch.pending_exceptions);
153#ifdef EXIT_DEBUG
154 printk(KERN_INFO "Queueing interrupt %x\n", vec);
155#endif
156}
157
158
159void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
160{
161 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
162}
163
164void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
165{
166 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
167}
168
169int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
170{
171 return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
172}
173
174void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
175 struct kvm_interrupt *irq)
176{
177 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
178}
179
180int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
181{
182 int deliver = 1;
183 int vec = 0;
184
185 switch (priority) {
186 case BOOK3S_IRQPRIO_DECREMENTER:
187 deliver = vcpu->arch.msr & MSR_EE;
188 vec = BOOK3S_INTERRUPT_DECREMENTER;
189 break;
190 case BOOK3S_IRQPRIO_EXTERNAL:
191 deliver = vcpu->arch.msr & MSR_EE;
192 vec = BOOK3S_INTERRUPT_EXTERNAL;
193 break;
194 case BOOK3S_IRQPRIO_SYSTEM_RESET:
195 vec = BOOK3S_INTERRUPT_SYSTEM_RESET;
196 break;
197 case BOOK3S_IRQPRIO_MACHINE_CHECK:
198 vec = BOOK3S_INTERRUPT_MACHINE_CHECK;
199 break;
200 case BOOK3S_IRQPRIO_DATA_STORAGE:
201 vec = BOOK3S_INTERRUPT_DATA_STORAGE;
202 break;
203 case BOOK3S_IRQPRIO_INST_STORAGE:
204 vec = BOOK3S_INTERRUPT_INST_STORAGE;
205 break;
206 case BOOK3S_IRQPRIO_DATA_SEGMENT:
207 vec = BOOK3S_INTERRUPT_DATA_SEGMENT;
208 break;
209 case BOOK3S_IRQPRIO_INST_SEGMENT:
210 vec = BOOK3S_INTERRUPT_INST_SEGMENT;
211 break;
212 case BOOK3S_IRQPRIO_ALIGNMENT:
213 vec = BOOK3S_INTERRUPT_ALIGNMENT;
214 break;
215 case BOOK3S_IRQPRIO_PROGRAM:
216 vec = BOOK3S_INTERRUPT_PROGRAM;
217 break;
218 case BOOK3S_IRQPRIO_VSX:
219 vec = BOOK3S_INTERRUPT_VSX;
220 break;
221 case BOOK3S_IRQPRIO_ALTIVEC:
222 vec = BOOK3S_INTERRUPT_ALTIVEC;
223 break;
224 case BOOK3S_IRQPRIO_FP_UNAVAIL:
225 vec = BOOK3S_INTERRUPT_FP_UNAVAIL;
226 break;
227 case BOOK3S_IRQPRIO_SYSCALL:
228 vec = BOOK3S_INTERRUPT_SYSCALL;
229 break;
230 case BOOK3S_IRQPRIO_DEBUG:
231 vec = BOOK3S_INTERRUPT_TRACE;
232 break;
233 case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR:
234 vec = BOOK3S_INTERRUPT_PERFMON;
235 break;
236 default:
237 deliver = 0;
238 printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority);
239 break;
240 }
241
242#if 0
243 printk(KERN_INFO "Deliver interrupt 0x%x? %x\n", vec, deliver);
244#endif
245
246 if (deliver)
247 kvmppc_inject_interrupt(vcpu, vec, 0ULL);
248
249 return deliver;
250}
251
252void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
253{
254 unsigned long *pending = &vcpu->arch.pending_exceptions;
255 unsigned int priority;
256
257 /* XXX be more clever here - no need to mftb() on every entry */
258 /* Issue DEC again if it's still active */
259#ifdef AGGRESSIVE_DEC
260 if (vcpu->arch.msr & MSR_EE)
261 if (kvmppc_get_dec(vcpu) & 0x80000000)
262 kvmppc_core_queue_dec(vcpu);
263#endif
264
265#ifdef EXIT_DEBUG
266 if (vcpu->arch.pending_exceptions)
267 printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
268#endif
269 priority = __ffs(*pending);
270 while (priority <= (sizeof(unsigned int) * 8)) {
271 if (kvmppc_book3s_irqprio_deliver(vcpu, priority)) {
272 clear_bit(priority, &vcpu->arch.pending_exceptions);
273 break;
274 }
275
276 priority = find_next_bit(pending,
277 BITS_PER_BYTE * sizeof(*pending),
278 priority + 1);
279 }
280}
281
282void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
283{
284 vcpu->arch.pvr = pvr;
285 if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
286 kvmppc_mmu_book3s_64_init(vcpu);
287 to_book3s(vcpu)->hior = 0xfff00000;
288 to_book3s(vcpu)->msr_mask = 0xffffffffffffffffULL;
289 } else {
290 kvmppc_mmu_book3s_32_init(vcpu);
291 to_book3s(vcpu)->hior = 0;
292 to_book3s(vcpu)->msr_mask = 0xffffffffULL;
293 }
294
295 /* If we are in hypervisor level on 970, we can tell the CPU to
296 * treat DCBZ as 32 bytes store */
297 vcpu->arch.hflags &= ~BOOK3S_HFLAG_DCBZ32;
298 if (vcpu->arch.mmu.is_dcbz32(vcpu) && (mfmsr() & MSR_HV) &&
299 !strcmp(cur_cpu_spec->platform, "ppc970"))
300 vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
301
302}
303
304/* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To
305 * make Book3s_32 Linux work on Book3s_64, we have to make sure we trap dcbz to
306 * emulate 32 bytes dcbz length.
307 *
308 * The Book3s_64 inventors also realized this case and implemented a special bit
309 * in the HID5 register, which is a hypervisor ressource. Thus we can't use it.
310 *
311 * My approach here is to patch the dcbz instruction on executing pages.
312 */
313static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
314{
315 bool touched = false;
316 hva_t hpage;
317 u32 *page;
318 int i;
319
320 hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
321 if (kvm_is_error_hva(hpage))
322 return;
323
324 hpage |= pte->raddr & ~PAGE_MASK;
325 hpage &= ~0xFFFULL;
326
327 page = vmalloc(HW_PAGE_SIZE);
328
329 if (copy_from_user(page, (void __user *)hpage, HW_PAGE_SIZE))
330 goto out;
331
332 for (i=0; i < HW_PAGE_SIZE / 4; i++)
333 if ((page[i] & 0xff0007ff) == INS_DCBZ) {
334 page[i] &= 0xfffffff7; // reserved instruction, so we trap
335 touched = true;
336 }
337
338 if (touched)
339 copy_to_user((void __user *)hpage, page, HW_PAGE_SIZE);
340
341out:
342 vfree(page);
343}
344
345static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data,
346 struct kvmppc_pte *pte)
347{
348 int relocated = (vcpu->arch.msr & (data ? MSR_DR : MSR_IR));
349 int r;
350
351 if (relocated) {
352 r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data);
353 } else {
354 pte->eaddr = eaddr;
355 pte->raddr = eaddr & 0xffffffff;
356 pte->vpage = eaddr >> 12;
357 switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
358 case 0:
359 pte->vpage |= VSID_REAL;
360 case MSR_DR:
361 pte->vpage |= VSID_REAL_DR;
362 case MSR_IR:
363 pte->vpage |= VSID_REAL_IR;
364 }
365 pte->may_read = true;
366 pte->may_write = true;
367 pte->may_execute = true;
368 r = 0;
369 }
370
371 return r;
372}
373
374static hva_t kvmppc_bad_hva(void)
375{
376 return PAGE_OFFSET;
377}
378
379static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte,
380 bool read)
381{
382 hva_t hpage;
383
384 if (read && !pte->may_read)
385 goto err;
386
387 if (!read && !pte->may_write)
388 goto err;
389
390 hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
391 if (kvm_is_error_hva(hpage))
392 goto err;
393
394 return hpage | (pte->raddr & ~PAGE_MASK);
395err:
396 return kvmppc_bad_hva();
397}
398
399int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr)
400{
401 struct kvmppc_pte pte;
402 hva_t hva = eaddr;
403
404 vcpu->stat.st++;
405
406 if (kvmppc_xlate(vcpu, eaddr, false, &pte))
407 goto err;
408
409 hva = kvmppc_pte_to_hva(vcpu, &pte, false);
410 if (kvm_is_error_hva(hva))
411 goto err;
412
413 if (copy_to_user((void __user *)hva, ptr, size)) {
414 printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva);
415 goto err;
416 }
417
418 return 0;
419
420err:
421 return -ENOENT;
422}
423
424int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr,
425 bool data)
426{
427 struct kvmppc_pte pte;
428 hva_t hva = eaddr;
429
430 vcpu->stat.ld++;
431
432 if (kvmppc_xlate(vcpu, eaddr, data, &pte))
433 goto err;
434
435 hva = kvmppc_pte_to_hva(vcpu, &pte, true);
436 if (kvm_is_error_hva(hva))
437 goto err;
438
439 if (copy_from_user(ptr, (void __user *)hva, size)) {
440 printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva);
441 goto err;
442 }
443
444 return 0;
445
446err:
447 return -ENOENT;
448}
449
450static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
451{
452 return kvm_is_visible_gfn(vcpu->kvm, gfn);
453}
454
455int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
456 ulong eaddr, int vec)
457{
458 bool data = (vec == BOOK3S_INTERRUPT_DATA_STORAGE);
459 int r = RESUME_GUEST;
460 int relocated;
461 int page_found = 0;
462 struct kvmppc_pte pte;
463 bool is_mmio = false;
464
465 if ( vec == BOOK3S_INTERRUPT_DATA_STORAGE ) {
466 relocated = (vcpu->arch.msr & MSR_DR);
467 } else {
468 relocated = (vcpu->arch.msr & MSR_IR);
469 }
470
471 /* Resolve real address if translation turned on */
472 if (relocated) {
473 page_found = vcpu->arch.mmu.xlate(vcpu, eaddr, &pte, data);
474 } else {
475 pte.may_execute = true;
476 pte.may_read = true;
477 pte.may_write = true;
478 pte.raddr = eaddr & 0xffffffff;
479 pte.eaddr = eaddr;
480 pte.vpage = eaddr >> 12;
481 switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
482 case 0:
483 pte.vpage |= VSID_REAL;
484 case MSR_DR:
485 pte.vpage |= VSID_REAL_DR;
486 case MSR_IR:
487 pte.vpage |= VSID_REAL_IR;
488 }
489 }
490
491 if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
492 (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) {
493 /*
494 * If we do the dcbz hack, we have to NX on every execution,
495 * so we can patch the executing code. This renders our guest
496 * NX-less.
497 */
498 pte.may_execute = !data;
499 }
500
501 if (page_found == -ENOENT) {
502 /* Page not found in guest PTE entries */
503 vcpu->arch.dear = vcpu->arch.fault_dear;
504 to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
505 vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
506 kvmppc_book3s_queue_irqprio(vcpu, vec);
507 } else if (page_found == -EPERM) {
508 /* Storage protection */
509 vcpu->arch.dear = vcpu->arch.fault_dear;
510 to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE;
511 to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT;
512 vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
513 kvmppc_book3s_queue_irqprio(vcpu, vec);
514 } else if (page_found == -EINVAL) {
515 /* Page not found in guest SLB */
516 vcpu->arch.dear = vcpu->arch.fault_dear;
517 kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80);
518 } else if (!is_mmio &&
519 kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) {
520 /* The guest's PTE is not mapped yet. Map on the host */
521 kvmppc_mmu_map_page(vcpu, &pte);
522 if (data)
523 vcpu->stat.sp_storage++;
524 else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
525 (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32)))
526 kvmppc_patch_dcbz(vcpu, &pte);
527 } else {
528 /* MMIO */
529 vcpu->stat.mmio_exits++;
530 vcpu->arch.paddr_accessed = pte.raddr;
531 r = kvmppc_emulate_mmio(run, vcpu);
532 if ( r == RESUME_HOST_NV )
533 r = RESUME_HOST;
534 if ( r == RESUME_GUEST_NV )
535 r = RESUME_GUEST;
536 }
537
538 return r;
539}
540
541int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
542 unsigned int exit_nr)
543{
544 int r = RESUME_HOST;
545
546 vcpu->stat.sum_exits++;
547
548 run->exit_reason = KVM_EXIT_UNKNOWN;
549 run->ready_for_interrupt_injection = 1;
550#ifdef EXIT_DEBUG
551 printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | dec=0x%x | msr=0x%lx\n",
552 exit_nr, vcpu->arch.pc, vcpu->arch.fault_dear,
553 kvmppc_get_dec(vcpu), vcpu->arch.msr);
554#elif defined (EXIT_DEBUG_SIMPLE)
555 if ((exit_nr != 0x900) && (exit_nr != 0x500))
556 printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | msr=0x%lx\n",
557 exit_nr, vcpu->arch.pc, vcpu->arch.fault_dear,
558 vcpu->arch.msr);
559#endif
560 kvm_resched(vcpu);
561 switch (exit_nr) {
562 case BOOK3S_INTERRUPT_INST_STORAGE:
563 vcpu->stat.pf_instruc++;
564 /* only care about PTEG not found errors, but leave NX alone */
565 if (vcpu->arch.shadow_msr & 0x40000000) {
566 r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.pc, exit_nr);
567 vcpu->stat.sp_instruc++;
568 } else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
569 (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) {
570 /*
571 * XXX If we do the dcbz hack we use the NX bit to flush&patch the page,
572 * so we can't use the NX bit inside the guest. Let's cross our fingers,
573 * that no guest that needs the dcbz hack does NX.
574 */
575 kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
576 } else {
577 vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x58000000);
578 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
579 kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
580 r = RESUME_GUEST;
581 }
582 break;
583 case BOOK3S_INTERRUPT_DATA_STORAGE:
584 vcpu->stat.pf_storage++;
585 /* The only case we need to handle is missing shadow PTEs */
586 if (vcpu->arch.fault_dsisr & DSISR_NOHPTE) {
587 r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.fault_dear, exit_nr);
588 } else {
589 vcpu->arch.dear = vcpu->arch.fault_dear;
590 to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
591 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
592 kvmppc_mmu_pte_flush(vcpu, vcpu->arch.dear, ~0xFFFULL);
593 r = RESUME_GUEST;
594 }
595 break;
596 case BOOK3S_INTERRUPT_DATA_SEGMENT:
597 if (kvmppc_mmu_map_segment(vcpu, vcpu->arch.fault_dear) < 0) {
598 vcpu->arch.dear = vcpu->arch.fault_dear;
599 kvmppc_book3s_queue_irqprio(vcpu,
600 BOOK3S_INTERRUPT_DATA_SEGMENT);
601 }
602 r = RESUME_GUEST;
603 break;
604 case BOOK3S_INTERRUPT_INST_SEGMENT:
605 if (kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc) < 0) {
606 kvmppc_book3s_queue_irqprio(vcpu,
607 BOOK3S_INTERRUPT_INST_SEGMENT);
608 }
609 r = RESUME_GUEST;
610 break;
611 /* We're good on these - the host merely wanted to get our attention */
612 case BOOK3S_INTERRUPT_DECREMENTER:
613 vcpu->stat.dec_exits++;
614 r = RESUME_GUEST;
615 break;
616 case BOOK3S_INTERRUPT_EXTERNAL:
617 vcpu->stat.ext_intr_exits++;
618 r = RESUME_GUEST;
619 break;
620 case BOOK3S_INTERRUPT_PROGRAM:
621 {
622 enum emulation_result er;
623
624 if (vcpu->arch.msr & MSR_PR) {
625#ifdef EXIT_DEBUG
626 printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", vcpu->arch.pc, vcpu->arch.last_inst);
627#endif
628 if ((vcpu->arch.last_inst & 0xff0007ff) !=
629 (INS_DCBZ & 0xfffffff7)) {
630 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
631 r = RESUME_GUEST;
632 break;
633 }
634 }
635
636 vcpu->stat.emulated_inst_exits++;
637 er = kvmppc_emulate_instruction(run, vcpu);
638 switch (er) {
639 case EMULATE_DONE:
640 r = RESUME_GUEST;
641 break;
642 case EMULATE_FAIL:
643 printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
644 __func__, vcpu->arch.pc, vcpu->arch.last_inst);
645 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
646 r = RESUME_GUEST;
647 break;
648 default:
649 BUG();
650 }
651 break;
652 }
653 case BOOK3S_INTERRUPT_SYSCALL:
654#ifdef EXIT_DEBUG
655 printk(KERN_INFO "Syscall Nr %d\n", (int)vcpu->arch.gpr[0]);
656#endif
657 vcpu->stat.syscall_exits++;
658 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
659 r = RESUME_GUEST;
660 break;
661 case BOOK3S_INTERRUPT_MACHINE_CHECK:
662 case BOOK3S_INTERRUPT_FP_UNAVAIL:
663 case BOOK3S_INTERRUPT_TRACE:
664 case BOOK3S_INTERRUPT_ALTIVEC:
665 case BOOK3S_INTERRUPT_VSX:
666 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
667 r = RESUME_GUEST;
668 break;
669 default:
670 /* Ugh - bork here! What did we get? */
671 printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", exit_nr, vcpu->arch.pc, vcpu->arch.shadow_msr);
672 r = RESUME_HOST;
673 BUG();
674 break;
675 }
676
677
678 if (!(r & RESUME_HOST)) {
679 /* To avoid clobbering exit_reason, only check for signals if
680 * we aren't already exiting to userspace for some other
681 * reason. */
682 if (signal_pending(current)) {
683#ifdef EXIT_DEBUG
684 printk(KERN_EMERG "KVM: Going back to host\n");
685#endif
686 vcpu->stat.signal_exits++;
687 run->exit_reason = KVM_EXIT_INTR;
688 r = -EINTR;
689 } else {
690 /* In case an interrupt came in that was triggered
691 * from userspace (like DEC), we need to check what
692 * to inject now! */
693 kvmppc_core_deliver_interrupts(vcpu);
694 }
695 }
696
697#ifdef EXIT_DEBUG
698 printk(KERN_EMERG "KVM exit: vcpu=0x%p pc=0x%lx r=0x%x\n", vcpu, vcpu->arch.pc, r);
699#endif
700
701 return r;
702}
703
704int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
705{
706 return 0;
707}
708
709int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
710{
711 int i;
712
713 regs->pc = vcpu->arch.pc;
714 regs->cr = vcpu->arch.cr;
715 regs->ctr = vcpu->arch.ctr;
716 regs->lr = vcpu->arch.lr;
717 regs->xer = vcpu->arch.xer;
718 regs->msr = vcpu->arch.msr;
719 regs->srr0 = vcpu->arch.srr0;
720 regs->srr1 = vcpu->arch.srr1;
721 regs->pid = vcpu->arch.pid;
722 regs->sprg0 = vcpu->arch.sprg0;
723 regs->sprg1 = vcpu->arch.sprg1;
724 regs->sprg2 = vcpu->arch.sprg2;
725 regs->sprg3 = vcpu->arch.sprg3;
726 regs->sprg5 = vcpu->arch.sprg4;
727 regs->sprg6 = vcpu->arch.sprg5;
728 regs->sprg7 = vcpu->arch.sprg6;
729
730 for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
731 regs->gpr[i] = vcpu->arch.gpr[i];
732
733 return 0;
734}
735
736int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
737{
738 int i;
739
740 vcpu->arch.pc = regs->pc;
741 vcpu->arch.cr = regs->cr;
742 vcpu->arch.ctr = regs->ctr;
743 vcpu->arch.lr = regs->lr;
744 vcpu->arch.xer = regs->xer;
745 kvmppc_set_msr(vcpu, regs->msr);
746 vcpu->arch.srr0 = regs->srr0;
747 vcpu->arch.srr1 = regs->srr1;
748 vcpu->arch.sprg0 = regs->sprg0;
749 vcpu->arch.sprg1 = regs->sprg1;
750 vcpu->arch.sprg2 = regs->sprg2;
751 vcpu->arch.sprg3 = regs->sprg3;
752 vcpu->arch.sprg5 = regs->sprg4;
753 vcpu->arch.sprg6 = regs->sprg5;
754 vcpu->arch.sprg7 = regs->sprg6;
755
756 for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
757 vcpu->arch.gpr[i] = regs->gpr[i];
758
759 return 0;
760}
761
762int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
763 struct kvm_sregs *sregs)
764{
765 sregs->pvr = vcpu->arch.pvr;
766 return 0;
767}
768
769int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
770 struct kvm_sregs *sregs)
771{
772 kvmppc_set_pvr(vcpu, sregs->pvr);
773 return 0;
774}
775
776int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
777{
778 return -ENOTSUPP;
779}
780
781int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
782{
783 return -ENOTSUPP;
784}
785
786int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
787 struct kvm_translation *tr)
788{
789 return 0;
790}
791
792/*
793 * Get (and clear) the dirty memory log for a memory slot.
794 */
795int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
796 struct kvm_dirty_log *log)
797{
798 struct kvm_memory_slot *memslot;
799 struct kvm_vcpu *vcpu;
800 ulong ga, ga_end;
801 int is_dirty = 0;
802 int r, n;
803
804 down_write(&kvm->slots_lock);
805
806 r = kvm_get_dirty_log(kvm, log, &is_dirty);
807 if (r)
808 goto out;
809
810 /* If nothing is dirty, don't bother messing with page tables. */
811 if (is_dirty) {
812 memslot = &kvm->memslots[log->slot];
813
814 ga = memslot->base_gfn << PAGE_SHIFT;
815 ga_end = ga + (memslot->npages << PAGE_SHIFT);
816
817 kvm_for_each_vcpu(n, vcpu, kvm)
818 kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
819
820 n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
821 memset(memslot->dirty_bitmap, 0, n);
822 }
823
824 r = 0;
825out:
826 up_write(&kvm->slots_lock);
827 return r;
828}
829
830int kvmppc_core_check_processor_compat(void)
831{
832 return 0;
833}
834
835struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
836{
837 struct kvmppc_vcpu_book3s *vcpu_book3s;
838 struct kvm_vcpu *vcpu;
839 int err;
840
841 vcpu_book3s = (struct kvmppc_vcpu_book3s *)__get_free_pages( GFP_KERNEL | __GFP_ZERO,
842 get_order(sizeof(struct kvmppc_vcpu_book3s)));
843 if (!vcpu_book3s) {
844 err = -ENOMEM;
845 goto out;
846 }
847
848 vcpu = &vcpu_book3s->vcpu;
849 err = kvm_vcpu_init(vcpu, kvm, id);
850 if (err)
851 goto free_vcpu;
852
853 vcpu->arch.host_retip = kvm_return_point;
854 vcpu->arch.host_msr = mfmsr();
855 /* default to book3s_64 (970fx) */
856 vcpu->arch.pvr = 0x3C0301;
857 kvmppc_set_pvr(vcpu, vcpu->arch.pvr);
858 vcpu_book3s->slb_nr = 64;
859
860 /* remember where some real-mode handlers are */
861 vcpu->arch.trampoline_lowmem = kvmppc_trampoline_lowmem;
862 vcpu->arch.trampoline_enter = kvmppc_trampoline_enter;
863 vcpu->arch.highmem_handler = (ulong)kvmppc_handler_highmem;
864
865 vcpu->arch.shadow_msr = MSR_USER64;
866
867 err = __init_new_context();
868 if (err < 0)
869 goto free_vcpu;
870 vcpu_book3s->context_id = err;
871
872 vcpu_book3s->vsid_max = ((vcpu_book3s->context_id + 1) << USER_ESID_BITS) - 1;
873 vcpu_book3s->vsid_first = vcpu_book3s->context_id << USER_ESID_BITS;
874 vcpu_book3s->vsid_next = vcpu_book3s->vsid_first;
875
876 return vcpu;
877
878free_vcpu:
879 free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s)));
880out:
881 return ERR_PTR(err);
882}
883
884void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
885{
886 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
887
888 __destroy_context(vcpu_book3s->context_id);
889 kvm_vcpu_uninit(vcpu);
890 free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s)));
891}
892
893extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
894int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
895{
896 int ret;
897
898 /* No need to go into the guest when all we do is going out */
899 if (signal_pending(current)) {
900 kvm_run->exit_reason = KVM_EXIT_INTR;
901 return -EINTR;
902 }
903
904 /* XXX we get called with irq disabled - change that! */
905 local_irq_enable();
906
907 ret = __kvmppc_vcpu_entry(kvm_run, vcpu);
908
909 local_irq_disable();
910
911 return ret;
912}
913
914static int kvmppc_book3s_init(void)
915{
916 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), THIS_MODULE);
917}
918
919static void kvmppc_book3s_exit(void)
920{
921 kvm_exit();
922}
923
924module_init(kvmppc_book3s_init);
925module_exit(kvmppc_book3s_exit);
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c
new file mode 100644
index 000000000000..faf99f20d993
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_32_mmu.c
@@ -0,0 +1,372 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#include <linux/types.h>
21#include <linux/string.h>
22#include <linux/kvm.h>
23#include <linux/kvm_host.h>
24#include <linux/highmem.h>
25
26#include <asm/tlbflush.h>
27#include <asm/kvm_ppc.h>
28#include <asm/kvm_book3s.h>
29
30/* #define DEBUG_MMU */
31/* #define DEBUG_MMU_PTE */
32/* #define DEBUG_MMU_PTE_IP 0xfff14c40 */
33
34#ifdef DEBUG_MMU
35#define dprintk(X...) printk(KERN_INFO X)
36#else
37#define dprintk(X...) do { } while(0)
38#endif
39
40#ifdef DEBUG_PTE
41#define dprintk_pte(X...) printk(KERN_INFO X)
42#else
43#define dprintk_pte(X...) do { } while(0)
44#endif
45
46#define PTEG_FLAG_ACCESSED 0x00000100
47#define PTEG_FLAG_DIRTY 0x00000080
48
49static inline bool check_debug_ip(struct kvm_vcpu *vcpu)
50{
51#ifdef DEBUG_MMU_PTE_IP
52 return vcpu->arch.pc == DEBUG_MMU_PTE_IP;
53#else
54 return true;
55#endif
56}
57
58static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
59 struct kvmppc_pte *pte, bool data);
60
61static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr)
62{
63 return &vcpu_book3s->sr[(eaddr >> 28) & 0xf];
64}
65
66static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
67 bool data)
68{
69 struct kvmppc_sr *sre = find_sr(to_book3s(vcpu), eaddr);
70 struct kvmppc_pte pte;
71
72 if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data))
73 return pte.vpage;
74
75 return (((u64)eaddr >> 12) & 0xffff) | (((u64)sre->vsid) << 16);
76}
77
78static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu)
79{
80 kvmppc_set_msr(vcpu, 0);
81}
82
83static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3s,
84 struct kvmppc_sr *sre, gva_t eaddr,
85 bool primary)
86{
87 u32 page, hash, pteg, htabmask;
88 hva_t r;
89
90 page = (eaddr & 0x0FFFFFFF) >> 12;
91 htabmask = ((vcpu_book3s->sdr1 & 0x1FF) << 16) | 0xFFC0;
92
93 hash = ((sre->vsid ^ page) << 6);
94 if (!primary)
95 hash = ~hash;
96 hash &= htabmask;
97
98 pteg = (vcpu_book3s->sdr1 & 0xffff0000) | hash;
99
100 dprintk("MMU: pc=0x%lx eaddr=0x%lx sdr1=0x%llx pteg=0x%x vsid=0x%x\n",
101 vcpu_book3s->vcpu.arch.pc, eaddr, vcpu_book3s->sdr1, pteg,
102 sre->vsid);
103
104 r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT);
105 if (kvm_is_error_hva(r))
106 return r;
107 return r | (pteg & ~PAGE_MASK);
108}
109
110static u32 kvmppc_mmu_book3s_32_get_ptem(struct kvmppc_sr *sre, gva_t eaddr,
111 bool primary)
112{
113 return ((eaddr & 0x0fffffff) >> 22) | (sre->vsid << 7) |
114 (primary ? 0 : 0x40) | 0x80000000;
115}
116
117static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
118 struct kvmppc_pte *pte, bool data)
119{
120 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
121 struct kvmppc_bat *bat;
122 int i;
123
124 for (i = 0; i < 8; i++) {
125 if (data)
126 bat = &vcpu_book3s->dbat[i];
127 else
128 bat = &vcpu_book3s->ibat[i];
129
130 if (vcpu->arch.msr & MSR_PR) {
131 if (!bat->vp)
132 continue;
133 } else {
134 if (!bat->vs)
135 continue;
136 }
137
138 if (check_debug_ip(vcpu))
139 {
140 dprintk_pte("%cBAT %02d: 0x%lx - 0x%x (0x%x)\n",
141 data ? 'd' : 'i', i, eaddr, bat->bepi,
142 bat->bepi_mask);
143 }
144 if ((eaddr & bat->bepi_mask) == bat->bepi) {
145 pte->raddr = bat->brpn | (eaddr & ~bat->bepi_mask);
146 pte->vpage = (eaddr >> 12) | VSID_BAT;
147 pte->may_read = bat->pp;
148 pte->may_write = bat->pp > 1;
149 pte->may_execute = true;
150 if (!pte->may_read) {
151 printk(KERN_INFO "BAT is not readable!\n");
152 continue;
153 }
154 if (!pte->may_write) {
155 /* let's treat r/o BATs as not-readable for now */
156 dprintk_pte("BAT is read-only!\n");
157 continue;
158 }
159
160 return 0;
161 }
162 }
163
164 return -ENOENT;
165}
166
167static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
168 struct kvmppc_pte *pte, bool data,
169 bool primary)
170{
171 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
172 struct kvmppc_sr *sre;
173 hva_t ptegp;
174 u32 pteg[16];
175 u64 ptem = 0;
176 int i;
177 int found = 0;
178
179 sre = find_sr(vcpu_book3s, eaddr);
180
181 dprintk_pte("SR 0x%lx: vsid=0x%x, raw=0x%x\n", eaddr >> 28,
182 sre->vsid, sre->raw);
183
184 pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
185
186 ptegp = kvmppc_mmu_book3s_32_get_pteg(vcpu_book3s, sre, eaddr, primary);
187 if (kvm_is_error_hva(ptegp)) {
188 printk(KERN_INFO "KVM: Invalid PTEG!\n");
189 goto no_page_found;
190 }
191
192 ptem = kvmppc_mmu_book3s_32_get_ptem(sre, eaddr, primary);
193
194 if(copy_from_user(pteg, (void __user *)ptegp, sizeof(pteg))) {
195 printk(KERN_ERR "KVM: Can't copy data from 0x%lx!\n", ptegp);
196 goto no_page_found;
197 }
198
199 for (i=0; i<16; i+=2) {
200 if (ptem == pteg[i]) {
201 u8 pp;
202
203 pte->raddr = (pteg[i+1] & ~(0xFFFULL)) | (eaddr & 0xFFF);
204 pp = pteg[i+1] & 3;
205
206 if ((sre->Kp && (vcpu->arch.msr & MSR_PR)) ||
207 (sre->Ks && !(vcpu->arch.msr & MSR_PR)))
208 pp |= 4;
209
210 pte->may_write = false;
211 pte->may_read = false;
212 pte->may_execute = true;
213 switch (pp) {
214 case 0:
215 case 1:
216 case 2:
217 case 6:
218 pte->may_write = true;
219 case 3:
220 case 5:
221 case 7:
222 pte->may_read = true;
223 break;
224 }
225
226 if ( !pte->may_read )
227 continue;
228
229 dprintk_pte("MMU: Found PTE -> %x %x - %x\n",
230 pteg[i], pteg[i+1], pp);
231 found = 1;
232 break;
233 }
234 }
235
236 /* Update PTE C and A bits, so the guest's swapper knows we used the
237 page */
238 if (found) {
239 u32 oldpte = pteg[i+1];
240
241 if (pte->may_read)
242 pteg[i+1] |= PTEG_FLAG_ACCESSED;
243 if (pte->may_write)
244 pteg[i+1] |= PTEG_FLAG_DIRTY;
245 else
246 dprintk_pte("KVM: Mapping read-only page!\n");
247
248 /* Write back into the PTEG */
249 if (pteg[i+1] != oldpte)
250 copy_to_user((void __user *)ptegp, pteg, sizeof(pteg));
251
252 return 0;
253 }
254
255no_page_found:
256
257 if (check_debug_ip(vcpu)) {
258 dprintk_pte("KVM MMU: No PTE found (sdr1=0x%llx ptegp=0x%lx)\n",
259 to_book3s(vcpu)->sdr1, ptegp);
260 for (i=0; i<16; i+=2) {
261 dprintk_pte(" %02d: 0x%x - 0x%x (0x%llx)\n",
262 i, pteg[i], pteg[i+1], ptem);
263 }
264 }
265
266 return -ENOENT;
267}
268
269static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
270 struct kvmppc_pte *pte, bool data)
271{
272 int r;
273
274 pte->eaddr = eaddr;
275 r = kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, pte, data);
276 if (r < 0)
277 r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, data, true);
278 if (r < 0)
279 r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, data, false);
280
281 return r;
282}
283
284
285static u32 kvmppc_mmu_book3s_32_mfsrin(struct kvm_vcpu *vcpu, u32 srnum)
286{
287 return to_book3s(vcpu)->sr[srnum].raw;
288}
289
290static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
291 ulong value)
292{
293 struct kvmppc_sr *sre;
294
295 sre = &to_book3s(vcpu)->sr[srnum];
296
297 /* Flush any left-over shadows from the previous SR */
298
299 /* XXX Not necessary? */
300 /* kvmppc_mmu_pte_flush(vcpu, ((u64)sre->vsid) << 28, 0xf0000000ULL); */
301
302 /* And then put in the new SR */
303 sre->raw = value;
304 sre->vsid = (value & 0x0fffffff);
305 sre->Ks = (value & 0x40000000) ? true : false;
306 sre->Kp = (value & 0x20000000) ? true : false;
307 sre->nx = (value & 0x10000000) ? true : false;
308
309 /* Map the new segment */
310 kvmppc_mmu_map_segment(vcpu, srnum << SID_SHIFT);
311}
312
313static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool large)
314{
315 kvmppc_mmu_pte_flush(vcpu, ea, ~0xFFFULL);
316}
317
318static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid,
319 u64 *vsid)
320{
321 /* In case we only have one of MSR_IR or MSR_DR set, let's put
322 that in the real-mode context (and hope RM doesn't access
323 high memory) */
324 switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
325 case 0:
326 *vsid = (VSID_REAL >> 16) | esid;
327 break;
328 case MSR_IR:
329 *vsid = (VSID_REAL_IR >> 16) | esid;
330 break;
331 case MSR_DR:
332 *vsid = (VSID_REAL_DR >> 16) | esid;
333 break;
334 case MSR_DR|MSR_IR:
335 {
336 ulong ea;
337 ea = esid << SID_SHIFT;
338 *vsid = find_sr(to_book3s(vcpu), ea)->vsid;
339 break;
340 }
341 default:
342 BUG();
343 }
344
345 return 0;
346}
347
348static bool kvmppc_mmu_book3s_32_is_dcbz32(struct kvm_vcpu *vcpu)
349{
350 return true;
351}
352
353
354void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu)
355{
356 struct kvmppc_mmu *mmu = &vcpu->arch.mmu;
357
358 mmu->mtsrin = kvmppc_mmu_book3s_32_mtsrin;
359 mmu->mfsrin = kvmppc_mmu_book3s_32_mfsrin;
360 mmu->xlate = kvmppc_mmu_book3s_32_xlate;
361 mmu->reset_msr = kvmppc_mmu_book3s_32_reset_msr;
362 mmu->tlbie = kvmppc_mmu_book3s_32_tlbie;
363 mmu->esid_to_vsid = kvmppc_mmu_book3s_32_esid_to_vsid;
364 mmu->ea_to_vp = kvmppc_mmu_book3s_32_ea_to_vp;
365 mmu->is_dcbz32 = kvmppc_mmu_book3s_32_is_dcbz32;
366
367 mmu->slbmte = NULL;
368 mmu->slbmfee = NULL;
369 mmu->slbmfev = NULL;
370 mmu->slbie = NULL;
371 mmu->slbia = NULL;
372}
diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c
new file mode 100644
index 000000000000..c343e67306e0
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_emulate.c
@@ -0,0 +1,337 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#include <asm/kvm_ppc.h>
21#include <asm/disassemble.h>
22#include <asm/kvm_book3s.h>
23#include <asm/reg.h>
24
25#define OP_19_XOP_RFID 18
26#define OP_19_XOP_RFI 50
27
28#define OP_31_XOP_MFMSR 83
29#define OP_31_XOP_MTMSR 146
30#define OP_31_XOP_MTMSRD 178
31#define OP_31_XOP_MTSRIN 242
32#define OP_31_XOP_TLBIEL 274
33#define OP_31_XOP_TLBIE 306
34#define OP_31_XOP_SLBMTE 402
35#define OP_31_XOP_SLBIE 434
36#define OP_31_XOP_SLBIA 498
37#define OP_31_XOP_MFSRIN 659
38#define OP_31_XOP_SLBMFEV 851
39#define OP_31_XOP_EIOIO 854
40#define OP_31_XOP_SLBMFEE 915
41
42/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */
43#define OP_31_XOP_DCBZ 1010
44
45int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
46 unsigned int inst, int *advance)
47{
48 int emulated = EMULATE_DONE;
49
50 switch (get_op(inst)) {
51 case 19:
52 switch (get_xop(inst)) {
53 case OP_19_XOP_RFID:
54 case OP_19_XOP_RFI:
55 vcpu->arch.pc = vcpu->arch.srr0;
56 kvmppc_set_msr(vcpu, vcpu->arch.srr1);
57 *advance = 0;
58 break;
59
60 default:
61 emulated = EMULATE_FAIL;
62 break;
63 }
64 break;
65 case 31:
66 switch (get_xop(inst)) {
67 case OP_31_XOP_MFMSR:
68 vcpu->arch.gpr[get_rt(inst)] = vcpu->arch.msr;
69 break;
70 case OP_31_XOP_MTMSRD:
71 {
72 ulong rs = vcpu->arch.gpr[get_rs(inst)];
73 if (inst & 0x10000) {
74 vcpu->arch.msr &= ~(MSR_RI | MSR_EE);
75 vcpu->arch.msr |= rs & (MSR_RI | MSR_EE);
76 } else
77 kvmppc_set_msr(vcpu, rs);
78 break;
79 }
80 case OP_31_XOP_MTMSR:
81 kvmppc_set_msr(vcpu, vcpu->arch.gpr[get_rs(inst)]);
82 break;
83 case OP_31_XOP_MFSRIN:
84 {
85 int srnum;
86
87 srnum = (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf;
88 if (vcpu->arch.mmu.mfsrin) {
89 u32 sr;
90 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
91 vcpu->arch.gpr[get_rt(inst)] = sr;
92 }
93 break;
94 }
95 case OP_31_XOP_MTSRIN:
96 vcpu->arch.mmu.mtsrin(vcpu,
97 (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf,
98 vcpu->arch.gpr[get_rs(inst)]);
99 break;
100 case OP_31_XOP_TLBIE:
101 case OP_31_XOP_TLBIEL:
102 {
103 bool large = (inst & 0x00200000) ? true : false;
104 ulong addr = vcpu->arch.gpr[get_rb(inst)];
105 vcpu->arch.mmu.tlbie(vcpu, addr, large);
106 break;
107 }
108 case OP_31_XOP_EIOIO:
109 break;
110 case OP_31_XOP_SLBMTE:
111 if (!vcpu->arch.mmu.slbmte)
112 return EMULATE_FAIL;
113
114 vcpu->arch.mmu.slbmte(vcpu, vcpu->arch.gpr[get_rs(inst)],
115 vcpu->arch.gpr[get_rb(inst)]);
116 break;
117 case OP_31_XOP_SLBIE:
118 if (!vcpu->arch.mmu.slbie)
119 return EMULATE_FAIL;
120
121 vcpu->arch.mmu.slbie(vcpu, vcpu->arch.gpr[get_rb(inst)]);
122 break;
123 case OP_31_XOP_SLBIA:
124 if (!vcpu->arch.mmu.slbia)
125 return EMULATE_FAIL;
126
127 vcpu->arch.mmu.slbia(vcpu);
128 break;
129 case OP_31_XOP_SLBMFEE:
130 if (!vcpu->arch.mmu.slbmfee) {
131 emulated = EMULATE_FAIL;
132 } else {
133 ulong t, rb;
134
135 rb = vcpu->arch.gpr[get_rb(inst)];
136 t = vcpu->arch.mmu.slbmfee(vcpu, rb);
137 vcpu->arch.gpr[get_rt(inst)] = t;
138 }
139 break;
140 case OP_31_XOP_SLBMFEV:
141 if (!vcpu->arch.mmu.slbmfev) {
142 emulated = EMULATE_FAIL;
143 } else {
144 ulong t, rb;
145
146 rb = vcpu->arch.gpr[get_rb(inst)];
147 t = vcpu->arch.mmu.slbmfev(vcpu, rb);
148 vcpu->arch.gpr[get_rt(inst)] = t;
149 }
150 break;
151 case OP_31_XOP_DCBZ:
152 {
153 ulong rb = vcpu->arch.gpr[get_rb(inst)];
154 ulong ra = 0;
155 ulong addr;
156 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
157
158 if (get_ra(inst))
159 ra = vcpu->arch.gpr[get_ra(inst)];
160
161 addr = (ra + rb) & ~31ULL;
162 if (!(vcpu->arch.msr & MSR_SF))
163 addr &= 0xffffffff;
164
165 if (kvmppc_st(vcpu, addr, 32, zeros)) {
166 vcpu->arch.dear = addr;
167 vcpu->arch.fault_dear = addr;
168 to_book3s(vcpu)->dsisr = DSISR_PROTFAULT |
169 DSISR_ISSTORE;
170 kvmppc_book3s_queue_irqprio(vcpu,
171 BOOK3S_INTERRUPT_DATA_STORAGE);
172 kvmppc_mmu_pte_flush(vcpu, addr, ~0xFFFULL);
173 }
174
175 break;
176 }
177 default:
178 emulated = EMULATE_FAIL;
179 }
180 break;
181 default:
182 emulated = EMULATE_FAIL;
183 }
184
185 return emulated;
186}
187
188static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u64 val)
189{
190 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
191 struct kvmppc_bat *bat;
192
193 switch (sprn) {
194 case SPRN_IBAT0U ... SPRN_IBAT3L:
195 bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2];
196 break;
197 case SPRN_IBAT4U ... SPRN_IBAT7L:
198 bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT4U) / 2];
199 break;
200 case SPRN_DBAT0U ... SPRN_DBAT3L:
201 bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2];
202 break;
203 case SPRN_DBAT4U ... SPRN_DBAT7L:
204 bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT4U) / 2];
205 break;
206 default:
207 BUG();
208 }
209
210 if (!(sprn % 2)) {
211 /* Upper BAT */
212 u32 bl = (val >> 2) & 0x7ff;
213 bat->bepi_mask = (~bl << 17);
214 bat->bepi = val & 0xfffe0000;
215 bat->vs = (val & 2) ? 1 : 0;
216 bat->vp = (val & 1) ? 1 : 0;
217 } else {
218 /* Lower BAT */
219 bat->brpn = val & 0xfffe0000;
220 bat->wimg = (val >> 3) & 0xf;
221 bat->pp = val & 3;
222 }
223}
224
225int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
226{
227 int emulated = EMULATE_DONE;
228
229 switch (sprn) {
230 case SPRN_SDR1:
231 to_book3s(vcpu)->sdr1 = vcpu->arch.gpr[rs];
232 break;
233 case SPRN_DSISR:
234 to_book3s(vcpu)->dsisr = vcpu->arch.gpr[rs];
235 break;
236 case SPRN_DAR:
237 vcpu->arch.dear = vcpu->arch.gpr[rs];
238 break;
239 case SPRN_HIOR:
240 to_book3s(vcpu)->hior = vcpu->arch.gpr[rs];
241 break;
242 case SPRN_IBAT0U ... SPRN_IBAT3L:
243 case SPRN_IBAT4U ... SPRN_IBAT7L:
244 case SPRN_DBAT0U ... SPRN_DBAT3L:
245 case SPRN_DBAT4U ... SPRN_DBAT7L:
246 kvmppc_write_bat(vcpu, sprn, vcpu->arch.gpr[rs]);
247 /* BAT writes happen so rarely that we're ok to flush
248 * everything here */
249 kvmppc_mmu_pte_flush(vcpu, 0, 0);
250 break;
251 case SPRN_HID0:
252 to_book3s(vcpu)->hid[0] = vcpu->arch.gpr[rs];
253 break;
254 case SPRN_HID1:
255 to_book3s(vcpu)->hid[1] = vcpu->arch.gpr[rs];
256 break;
257 case SPRN_HID2:
258 to_book3s(vcpu)->hid[2] = vcpu->arch.gpr[rs];
259 break;
260 case SPRN_HID4:
261 to_book3s(vcpu)->hid[4] = vcpu->arch.gpr[rs];
262 break;
263 case SPRN_HID5:
264 to_book3s(vcpu)->hid[5] = vcpu->arch.gpr[rs];
265 /* guest HID5 set can change is_dcbz32 */
266 if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
267 (mfmsr() & MSR_HV))
268 vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
269 break;
270 case SPRN_ICTC:
271 case SPRN_THRM1:
272 case SPRN_THRM2:
273 case SPRN_THRM3:
274 case SPRN_CTRLF:
275 case SPRN_CTRLT:
276 break;
277 default:
278 printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
279#ifndef DEBUG_SPR
280 emulated = EMULATE_FAIL;
281#endif
282 break;
283 }
284
285 return emulated;
286}
287
288int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
289{
290 int emulated = EMULATE_DONE;
291
292 switch (sprn) {
293 case SPRN_SDR1:
294 vcpu->arch.gpr[rt] = to_book3s(vcpu)->sdr1;
295 break;
296 case SPRN_DSISR:
297 vcpu->arch.gpr[rt] = to_book3s(vcpu)->dsisr;
298 break;
299 case SPRN_DAR:
300 vcpu->arch.gpr[rt] = vcpu->arch.dear;
301 break;
302 case SPRN_HIOR:
303 vcpu->arch.gpr[rt] = to_book3s(vcpu)->hior;
304 break;
305 case SPRN_HID0:
306 vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[0];
307 break;
308 case SPRN_HID1:
309 vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[1];
310 break;
311 case SPRN_HID2:
312 vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[2];
313 break;
314 case SPRN_HID4:
315 vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[4];
316 break;
317 case SPRN_HID5:
318 vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[5];
319 break;
320 case SPRN_THRM1:
321 case SPRN_THRM2:
322 case SPRN_THRM3:
323 case SPRN_CTRLF:
324 case SPRN_CTRLT:
325 vcpu->arch.gpr[rt] = 0;
326 break;
327 default:
328 printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
329#ifndef DEBUG_SPR
330 emulated = EMULATE_FAIL;
331#endif
332 break;
333 }
334
335 return emulated;
336}
337
diff --git a/arch/powerpc/kvm/book3s_64_exports.c b/arch/powerpc/kvm/book3s_64_exports.c
new file mode 100644
index 000000000000..5b2db38ed86c
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_exports.c
@@ -0,0 +1,24 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#include <linux/module.h>
21#include <asm/kvm_book3s.h>
22
23EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter);
24EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem);
diff --git a/arch/powerpc/kvm/book3s_64_interrupts.S b/arch/powerpc/kvm/book3s_64_interrupts.S
new file mode 100644
index 000000000000..7b55d8094c8b
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_interrupts.S
@@ -0,0 +1,392 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#include <asm/ppc_asm.h>
21#include <asm/kvm_asm.h>
22#include <asm/reg.h>
23#include <asm/page.h>
24#include <asm/asm-offsets.h>
25#include <asm/exception-64s.h>
26
27#define KVMPPC_HANDLE_EXIT .kvmppc_handle_exit
28#define ULONG_SIZE 8
29#define VCPU_GPR(n) (VCPU_GPRS + (n * ULONG_SIZE))
30
31.macro mfpaca tmp_reg, src_reg, offset, vcpu_reg
32 ld \tmp_reg, (PACA_EXMC+\offset)(r13)
33 std \tmp_reg, VCPU_GPR(\src_reg)(\vcpu_reg)
34.endm
35
36.macro DISABLE_INTERRUPTS
37 mfmsr r0
38 rldicl r0,r0,48,1
39 rotldi r0,r0,16
40 mtmsrd r0,1
41.endm
42
43/*****************************************************************************
44 * *
45 * Guest entry / exit code that is in kernel module memory (highmem) *
46 * *
47 ****************************************************************************/
48
49/* Registers:
50 * r3: kvm_run pointer
51 * r4: vcpu pointer
52 */
53_GLOBAL(__kvmppc_vcpu_entry)
54
55kvm_start_entry:
56 /* Write correct stack frame */
57 mflr r0
58 std r0,16(r1)
59
60 /* Save host state to the stack */
61 stdu r1, -SWITCH_FRAME_SIZE(r1)
62
63 /* Save r3 (kvm_run) and r4 (vcpu) */
64 SAVE_2GPRS(3, r1)
65
66 /* Save non-volatile registers (r14 - r31) */
67 SAVE_NVGPRS(r1)
68
69 /* Save LR */
70 mflr r14
71 std r14, _LINK(r1)
72
73/* XXX optimize non-volatile loading away */
74kvm_start_lightweight:
75
76 DISABLE_INTERRUPTS
77
78 /* Save R1/R2 in the PACA */
79 std r1, PACAR1(r13)
80 std r2, (PACA_EXMC+EX_SRR0)(r13)
81 ld r3, VCPU_HIGHMEM_HANDLER(r4)
82 std r3, PACASAVEDMSR(r13)
83
84 /* Load non-volatile guest state from the vcpu */
85 ld r14, VCPU_GPR(r14)(r4)
86 ld r15, VCPU_GPR(r15)(r4)
87 ld r16, VCPU_GPR(r16)(r4)
88 ld r17, VCPU_GPR(r17)(r4)
89 ld r18, VCPU_GPR(r18)(r4)
90 ld r19, VCPU_GPR(r19)(r4)
91 ld r20, VCPU_GPR(r20)(r4)
92 ld r21, VCPU_GPR(r21)(r4)
93 ld r22, VCPU_GPR(r22)(r4)
94 ld r23, VCPU_GPR(r23)(r4)
95 ld r24, VCPU_GPR(r24)(r4)
96 ld r25, VCPU_GPR(r25)(r4)
97 ld r26, VCPU_GPR(r26)(r4)
98 ld r27, VCPU_GPR(r27)(r4)
99 ld r28, VCPU_GPR(r28)(r4)
100 ld r29, VCPU_GPR(r29)(r4)
101 ld r30, VCPU_GPR(r30)(r4)
102 ld r31, VCPU_GPR(r31)(r4)
103
104 ld r9, VCPU_PC(r4) /* r9 = vcpu->arch.pc */
105 ld r10, VCPU_SHADOW_MSR(r4) /* r10 = vcpu->arch.shadow_msr */
106
107 ld r3, VCPU_TRAMPOLINE_ENTER(r4)
108 mtsrr0 r3
109
110 LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
111 mtsrr1 r3
112
113 /* Load guest state in the respective registers */
114 lwz r3, VCPU_CR(r4) /* r3 = vcpu->arch.cr */
115 stw r3, (PACA_EXMC + EX_CCR)(r13)
116
117 ld r3, VCPU_CTR(r4) /* r3 = vcpu->arch.ctr */
118 mtctr r3 /* CTR = r3 */
119
120 ld r3, VCPU_LR(r4) /* r3 = vcpu->arch.lr */
121 mtlr r3 /* LR = r3 */
122
123 ld r3, VCPU_XER(r4) /* r3 = vcpu->arch.xer */
124 std r3, (PACA_EXMC + EX_R3)(r13)
125
126 /* Some guests may need to have dcbz set to 32 byte length.
127 *
128 * Usually we ensure that by patching the guest's instructions
129 * to trap on dcbz and emulate it in the hypervisor.
130 *
131 * If we can, we should tell the CPU to use 32 byte dcbz though,
132 * because that's a lot faster.
133 */
134
135 ld r3, VCPU_HFLAGS(r4)
136 rldicl. r3, r3, 0, 63 /* CR = ((r3 & 1) == 0) */
137 beq no_dcbz32_on
138
139 mfspr r3,SPRN_HID5
140 ori r3, r3, 0x80 /* XXX HID5_dcbz32 = 0x80 */
141 mtspr SPRN_HID5,r3
142
143no_dcbz32_on:
144 /* Load guest GPRs */
145
146 ld r3, VCPU_GPR(r9)(r4)
147 std r3, (PACA_EXMC + EX_R9)(r13)
148 ld r3, VCPU_GPR(r10)(r4)
149 std r3, (PACA_EXMC + EX_R10)(r13)
150 ld r3, VCPU_GPR(r11)(r4)
151 std r3, (PACA_EXMC + EX_R11)(r13)
152 ld r3, VCPU_GPR(r12)(r4)
153 std r3, (PACA_EXMC + EX_R12)(r13)
154 ld r3, VCPU_GPR(r13)(r4)
155 std r3, (PACA_EXMC + EX_R13)(r13)
156
157 ld r0, VCPU_GPR(r0)(r4)
158 ld r1, VCPU_GPR(r1)(r4)
159 ld r2, VCPU_GPR(r2)(r4)
160 ld r3, VCPU_GPR(r3)(r4)
161 ld r5, VCPU_GPR(r5)(r4)
162 ld r6, VCPU_GPR(r6)(r4)
163 ld r7, VCPU_GPR(r7)(r4)
164 ld r8, VCPU_GPR(r8)(r4)
165 ld r4, VCPU_GPR(r4)(r4)
166
167 /* This sets the Magic value for the trampoline */
168
169 li r11, 1
170 stb r11, PACA_KVM_IN_GUEST(r13)
171
172 /* Jump to SLB patching handlder and into our guest */
173 RFI
174
175/*
176 * This is the handler in module memory. It gets jumped at from the
177 * lowmem trampoline code, so it's basically the guest exit code.
178 *
179 */
180
181.global kvmppc_handler_highmem
182kvmppc_handler_highmem:
183
184 /*
185 * Register usage at this point:
186 *
187 * R00 = guest R13
188 * R01 = host R1
189 * R02 = host R2
190 * R10 = guest PC
191 * R11 = guest MSR
192 * R12 = exit handler id
193 * R13 = PACA
194 * PACA.exmc.R9 = guest R1
195 * PACA.exmc.R10 = guest R10
196 * PACA.exmc.R11 = guest R11
197 * PACA.exmc.R12 = guest R12
198 * PACA.exmc.R13 = guest R2
199 * PACA.exmc.DAR = guest DAR
200 * PACA.exmc.DSISR = guest DSISR
201 * PACA.exmc.LR = guest instruction
202 * PACA.exmc.CCR = guest CR
203 * PACA.exmc.SRR0 = guest R0
204 *
205 */
206
207 std r3, (PACA_EXMC+EX_R3)(r13)
208
209 /* save the exit id in R3 */
210 mr r3, r12
211
212 /* R12 = vcpu */
213 ld r12, GPR4(r1)
214
215 /* Now save the guest state */
216
217 std r0, VCPU_GPR(r13)(r12)
218 std r4, VCPU_GPR(r4)(r12)
219 std r5, VCPU_GPR(r5)(r12)
220 std r6, VCPU_GPR(r6)(r12)
221 std r7, VCPU_GPR(r7)(r12)
222 std r8, VCPU_GPR(r8)(r12)
223 std r9, VCPU_GPR(r9)(r12)
224
225 /* get registers from PACA */
226 mfpaca r5, r0, EX_SRR0, r12
227 mfpaca r5, r3, EX_R3, r12
228 mfpaca r5, r1, EX_R9, r12
229 mfpaca r5, r10, EX_R10, r12
230 mfpaca r5, r11, EX_R11, r12
231 mfpaca r5, r12, EX_R12, r12
232 mfpaca r5, r2, EX_R13, r12
233
234 lwz r5, (PACA_EXMC+EX_LR)(r13)
235 stw r5, VCPU_LAST_INST(r12)
236
237 lwz r5, (PACA_EXMC+EX_CCR)(r13)
238 stw r5, VCPU_CR(r12)
239
240 ld r5, VCPU_HFLAGS(r12)
241 rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */
242 beq no_dcbz32_off
243
244 mfspr r5,SPRN_HID5
245 rldimi r5,r5,6,56
246 mtspr SPRN_HID5,r5
247
248no_dcbz32_off:
249
250 /* XXX maybe skip on lightweight? */
251 std r14, VCPU_GPR(r14)(r12)
252 std r15, VCPU_GPR(r15)(r12)
253 std r16, VCPU_GPR(r16)(r12)
254 std r17, VCPU_GPR(r17)(r12)
255 std r18, VCPU_GPR(r18)(r12)
256 std r19, VCPU_GPR(r19)(r12)
257 std r20, VCPU_GPR(r20)(r12)
258 std r21, VCPU_GPR(r21)(r12)
259 std r22, VCPU_GPR(r22)(r12)
260 std r23, VCPU_GPR(r23)(r12)
261 std r24, VCPU_GPR(r24)(r12)
262 std r25, VCPU_GPR(r25)(r12)
263 std r26, VCPU_GPR(r26)(r12)
264 std r27, VCPU_GPR(r27)(r12)
265 std r28, VCPU_GPR(r28)(r12)
266 std r29, VCPU_GPR(r29)(r12)
267 std r30, VCPU_GPR(r30)(r12)
268 std r31, VCPU_GPR(r31)(r12)
269
270 /* Restore non-volatile host registers (r14 - r31) */
271 REST_NVGPRS(r1)
272
273 /* Save guest PC (R10) */
274 std r10, VCPU_PC(r12)
275
276 /* Save guest msr (R11) */
277 std r11, VCPU_SHADOW_MSR(r12)
278
279 /* Save guest CTR (in R12) */
280 mfctr r5
281 std r5, VCPU_CTR(r12)
282
283 /* Save guest LR */
284 mflr r5
285 std r5, VCPU_LR(r12)
286
287 /* Save guest XER */
288 mfxer r5
289 std r5, VCPU_XER(r12)
290
291 /* Save guest DAR */
292 ld r5, (PACA_EXMC+EX_DAR)(r13)
293 std r5, VCPU_FAULT_DEAR(r12)
294
295 /* Save guest DSISR */
296 lwz r5, (PACA_EXMC+EX_DSISR)(r13)
297 std r5, VCPU_FAULT_DSISR(r12)
298
299 /* Restore host msr -> SRR1 */
300 ld r7, VCPU_HOST_MSR(r12)
301 mtsrr1 r7
302
303 /* Restore host IP -> SRR0 */
304 ld r6, VCPU_HOST_RETIP(r12)
305 mtsrr0 r6
306
307 /*
308 * For some interrupts, we need to call the real Linux
309 * handler, so it can do work for us. This has to happen
310 * as if the interrupt arrived from the kernel though,
311 * so let's fake it here where most state is restored.
312 *
313 * Call Linux for hardware interrupts/decrementer
314 * r3 = address of interrupt handler (exit reason)
315 */
316
317 cmpwi r3, BOOK3S_INTERRUPT_EXTERNAL
318 beq call_linux_handler
319 cmpwi r3, BOOK3S_INTERRUPT_DECREMENTER
320 beq call_linux_handler
321
322 /* Back to Interruptable Mode! (goto kvm_return_point) */
323 RFI
324
325call_linux_handler:
326
327 /*
328 * If we land here we need to jump back to the handler we
329 * came from.
330 *
331 * We have a page that we can access from real mode, so let's
332 * jump back to that and use it as a trampoline to get back into the
333 * interrupt handler!
334 *
335 * R3 still contains the exit code,
336 * R6 VCPU_HOST_RETIP and
337 * R7 VCPU_HOST_MSR
338 */
339
340 mtlr r3
341
342 ld r5, VCPU_TRAMPOLINE_LOWMEM(r12)
343 mtsrr0 r5
344 LOAD_REG_IMMEDIATE(r5, MSR_KERNEL & ~(MSR_IR | MSR_DR))
345 mtsrr1 r5
346
347 RFI
348
349.global kvm_return_point
350kvm_return_point:
351
352 /* Jump back to lightweight entry if we're supposed to */
353 /* go back into the guest */
354 mr r5, r3
355 /* Restore r3 (kvm_run) and r4 (vcpu) */
356 REST_2GPRS(3, r1)
357 bl KVMPPC_HANDLE_EXIT
358
359#if 0 /* XXX get lightweight exits back */
360 cmpwi r3, RESUME_GUEST
361 bne kvm_exit_heavyweight
362
363 /* put VCPU and KVM_RUN back into place and roll again! */
364 REST_2GPRS(3, r1)
365 b kvm_start_lightweight
366
367kvm_exit_heavyweight:
368 /* Restore non-volatile host registers */
369 ld r14, _LINK(r1)
370 mtlr r14
371 REST_NVGPRS(r1)
372
373 addi r1, r1, SWITCH_FRAME_SIZE
374#else
375 ld r4, _LINK(r1)
376 mtlr r4
377
378 cmpwi r3, RESUME_GUEST
379 bne kvm_exit_heavyweight
380
381 REST_2GPRS(3, r1)
382
383 addi r1, r1, SWITCH_FRAME_SIZE
384
385 b kvm_start_entry
386
387kvm_exit_heavyweight:
388
389 addi r1, r1, SWITCH_FRAME_SIZE
390#endif
391
392 blr
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
new file mode 100644
index 000000000000..a31f9c677d23
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -0,0 +1,476 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#include <linux/types.h>
21#include <linux/string.h>
22#include <linux/kvm.h>
23#include <linux/kvm_host.h>
24#include <linux/highmem.h>
25
26#include <asm/tlbflush.h>
27#include <asm/kvm_ppc.h>
28#include <asm/kvm_book3s.h>
29
30/* #define DEBUG_MMU */
31
32#ifdef DEBUG_MMU
33#define dprintk(X...) printk(KERN_INFO X)
34#else
35#define dprintk(X...) do { } while(0)
36#endif
37
38static void kvmppc_mmu_book3s_64_reset_msr(struct kvm_vcpu *vcpu)
39{
40 kvmppc_set_msr(vcpu, MSR_SF);
41}
42
43static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe(
44 struct kvmppc_vcpu_book3s *vcpu_book3s,
45 gva_t eaddr)
46{
47 int i;
48 u64 esid = GET_ESID(eaddr);
49 u64 esid_1t = GET_ESID_1T(eaddr);
50
51 for (i = 0; i < vcpu_book3s->slb_nr; i++) {
52 u64 cmp_esid = esid;
53
54 if (!vcpu_book3s->slb[i].valid)
55 continue;
56
57 if (vcpu_book3s->slb[i].large)
58 cmp_esid = esid_1t;
59
60 if (vcpu_book3s->slb[i].esid == cmp_esid)
61 return &vcpu_book3s->slb[i];
62 }
63
64 dprintk("KVM: No SLB entry found for 0x%lx [%llx | %llx]\n",
65 eaddr, esid, esid_1t);
66 for (i = 0; i < vcpu_book3s->slb_nr; i++) {
67 if (vcpu_book3s->slb[i].vsid)
68 dprintk(" %d: %c%c %llx %llx\n", i,
69 vcpu_book3s->slb[i].valid ? 'v' : ' ',
70 vcpu_book3s->slb[i].large ? 'l' : ' ',
71 vcpu_book3s->slb[i].esid,
72 vcpu_book3s->slb[i].vsid);
73 }
74
75 return NULL;
76}
77
78static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
79 bool data)
80{
81 struct kvmppc_slb *slb;
82
83 slb = kvmppc_mmu_book3s_64_find_slbe(to_book3s(vcpu), eaddr);
84 if (!slb)
85 return 0;
86
87 if (slb->large)
88 return (((u64)eaddr >> 12) & 0xfffffff) |
89 (((u64)slb->vsid) << 28);
90
91 return (((u64)eaddr >> 12) & 0xffff) | (((u64)slb->vsid) << 16);
92}
93
94static int kvmppc_mmu_book3s_64_get_pagesize(struct kvmppc_slb *slbe)
95{
96 return slbe->large ? 24 : 12;
97}
98
99static u32 kvmppc_mmu_book3s_64_get_page(struct kvmppc_slb *slbe, gva_t eaddr)
100{
101 int p = kvmppc_mmu_book3s_64_get_pagesize(slbe);
102 return ((eaddr & 0xfffffff) >> p);
103}
104
105static hva_t kvmppc_mmu_book3s_64_get_pteg(
106 struct kvmppc_vcpu_book3s *vcpu_book3s,
107 struct kvmppc_slb *slbe, gva_t eaddr,
108 bool second)
109{
110 u64 hash, pteg, htabsize;
111 u32 page;
112 hva_t r;
113
114 page = kvmppc_mmu_book3s_64_get_page(slbe, eaddr);
115 htabsize = ((1 << ((vcpu_book3s->sdr1 & 0x1f) + 11)) - 1);
116
117 hash = slbe->vsid ^ page;
118 if (second)
119 hash = ~hash;
120 hash &= ((1ULL << 39ULL) - 1ULL);
121 hash &= htabsize;
122 hash <<= 7ULL;
123
124 pteg = vcpu_book3s->sdr1 & 0xfffffffffffc0000ULL;
125 pteg |= hash;
126
127 dprintk("MMU: page=0x%x sdr1=0x%llx pteg=0x%llx vsid=0x%llx\n",
128 page, vcpu_book3s->sdr1, pteg, slbe->vsid);
129
130 r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT);
131 if (kvm_is_error_hva(r))
132 return r;
133 return r | (pteg & ~PAGE_MASK);
134}
135
136static u64 kvmppc_mmu_book3s_64_get_avpn(struct kvmppc_slb *slbe, gva_t eaddr)
137{
138 int p = kvmppc_mmu_book3s_64_get_pagesize(slbe);
139 u64 avpn;
140
141 avpn = kvmppc_mmu_book3s_64_get_page(slbe, eaddr);
142 avpn |= slbe->vsid << (28 - p);
143
144 if (p < 24)
145 avpn >>= ((80 - p) - 56) - 8;
146 else
147 avpn <<= 8;
148
149 return avpn;
150}
151
152static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
153 struct kvmppc_pte *gpte, bool data)
154{
155 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
156 struct kvmppc_slb *slbe;
157 hva_t ptegp;
158 u64 pteg[16];
159 u64 avpn = 0;
160 int i;
161 u8 key = 0;
162 bool found = false;
163 bool perm_err = false;
164 int second = 0;
165
166 slbe = kvmppc_mmu_book3s_64_find_slbe(vcpu_book3s, eaddr);
167 if (!slbe)
168 goto no_seg_found;
169
170do_second:
171 ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second);
172 if (kvm_is_error_hva(ptegp))
173 goto no_page_found;
174
175 avpn = kvmppc_mmu_book3s_64_get_avpn(slbe, eaddr);
176
177 if(copy_from_user(pteg, (void __user *)ptegp, sizeof(pteg))) {
178 printk(KERN_ERR "KVM can't copy data from 0x%lx!\n", ptegp);
179 goto no_page_found;
180 }
181
182 if ((vcpu->arch.msr & MSR_PR) && slbe->Kp)
183 key = 4;
184 else if (!(vcpu->arch.msr & MSR_PR) && slbe->Ks)
185 key = 4;
186
187 for (i=0; i<16; i+=2) {
188 u64 v = pteg[i];
189 u64 r = pteg[i+1];
190
191 /* Valid check */
192 if (!(v & HPTE_V_VALID))
193 continue;
194 /* Hash check */
195 if ((v & HPTE_V_SECONDARY) != second)
196 continue;
197
198 /* AVPN compare */
199 if (HPTE_V_AVPN_VAL(avpn) == HPTE_V_AVPN_VAL(v)) {
200 u8 pp = (r & HPTE_R_PP) | key;
201 int eaddr_mask = 0xFFF;
202
203 gpte->eaddr = eaddr;
204 gpte->vpage = kvmppc_mmu_book3s_64_ea_to_vp(vcpu,
205 eaddr,
206 data);
207 if (slbe->large)
208 eaddr_mask = 0xFFFFFF;
209 gpte->raddr = (r & HPTE_R_RPN) | (eaddr & eaddr_mask);
210 gpte->may_execute = ((r & HPTE_R_N) ? false : true);
211 gpte->may_read = false;
212 gpte->may_write = false;
213
214 switch (pp) {
215 case 0:
216 case 1:
217 case 2:
218 case 6:
219 gpte->may_write = true;
220 /* fall through */
221 case 3:
222 case 5:
223 case 7:
224 gpte->may_read = true;
225 break;
226 }
227
228 if (!gpte->may_read) {
229 perm_err = true;
230 continue;
231 }
232
233 dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx "
234 "-> 0x%llx\n",
235 eaddr, avpn, gpte->vpage, gpte->raddr);
236 found = true;
237 break;
238 }
239 }
240
241 /* Update PTE R and C bits, so the guest's swapper knows we used the
242 * page */
243 if (found) {
244 u32 oldr = pteg[i+1];
245
246 if (gpte->may_read) {
247 /* Set the accessed flag */
248 pteg[i+1] |= HPTE_R_R;
249 }
250 if (gpte->may_write) {
251 /* Set the dirty flag */
252 pteg[i+1] |= HPTE_R_C;
253 } else {
254 dprintk("KVM: Mapping read-only page!\n");
255 }
256
257 /* Write back into the PTEG */
258 if (pteg[i+1] != oldr)
259 copy_to_user((void __user *)ptegp, pteg, sizeof(pteg));
260
261 return 0;
262 } else {
263 dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx "
264 "ptegp=0x%lx)\n",
265 eaddr, to_book3s(vcpu)->sdr1, ptegp);
266 for (i = 0; i < 16; i += 2)
267 dprintk(" %02d: 0x%llx - 0x%llx (0x%llx)\n",
268 i, pteg[i], pteg[i+1], avpn);
269
270 if (!second) {
271 second = HPTE_V_SECONDARY;
272 goto do_second;
273 }
274 }
275
276
277no_page_found:
278
279
280 if (perm_err)
281 return -EPERM;
282
283 return -ENOENT;
284
285no_seg_found:
286
287 dprintk("KVM MMU: Trigger segment fault\n");
288 return -EINVAL;
289}
290
291static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb)
292{
293 struct kvmppc_vcpu_book3s *vcpu_book3s;
294 u64 esid, esid_1t;
295 int slb_nr;
296 struct kvmppc_slb *slbe;
297
298 dprintk("KVM MMU: slbmte(0x%llx, 0x%llx)\n", rs, rb);
299
300 vcpu_book3s = to_book3s(vcpu);
301
302 esid = GET_ESID(rb);
303 esid_1t = GET_ESID_1T(rb);
304 slb_nr = rb & 0xfff;
305
306 if (slb_nr > vcpu_book3s->slb_nr)
307 return;
308
309 slbe = &vcpu_book3s->slb[slb_nr];
310
311 slbe->large = (rs & SLB_VSID_L) ? 1 : 0;
312 slbe->esid = slbe->large ? esid_1t : esid;
313 slbe->vsid = rs >> 12;
314 slbe->valid = (rb & SLB_ESID_V) ? 1 : 0;
315 slbe->Ks = (rs & SLB_VSID_KS) ? 1 : 0;
316 slbe->Kp = (rs & SLB_VSID_KP) ? 1 : 0;
317 slbe->nx = (rs & SLB_VSID_N) ? 1 : 0;
318 slbe->class = (rs & SLB_VSID_C) ? 1 : 0;
319
320 slbe->orige = rb & (ESID_MASK | SLB_ESID_V);
321 slbe->origv = rs;
322
323 /* Map the new segment */
324 kvmppc_mmu_map_segment(vcpu, esid << SID_SHIFT);
325}
326
327static u64 kvmppc_mmu_book3s_64_slbmfee(struct kvm_vcpu *vcpu, u64 slb_nr)
328{
329 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
330 struct kvmppc_slb *slbe;
331
332 if (slb_nr > vcpu_book3s->slb_nr)
333 return 0;
334
335 slbe = &vcpu_book3s->slb[slb_nr];
336
337 return slbe->orige;
338}
339
340static u64 kvmppc_mmu_book3s_64_slbmfev(struct kvm_vcpu *vcpu, u64 slb_nr)
341{
342 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
343 struct kvmppc_slb *slbe;
344
345 if (slb_nr > vcpu_book3s->slb_nr)
346 return 0;
347
348 slbe = &vcpu_book3s->slb[slb_nr];
349
350 return slbe->origv;
351}
352
353static void kvmppc_mmu_book3s_64_slbie(struct kvm_vcpu *vcpu, u64 ea)
354{
355 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
356 struct kvmppc_slb *slbe;
357
358 dprintk("KVM MMU: slbie(0x%llx)\n", ea);
359
360 slbe = kvmppc_mmu_book3s_64_find_slbe(vcpu_book3s, ea);
361
362 if (!slbe)
363 return;
364
365 dprintk("KVM MMU: slbie(0x%llx, 0x%llx)\n", ea, slbe->esid);
366
367 slbe->valid = false;
368
369 kvmppc_mmu_map_segment(vcpu, ea);
370}
371
372static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu)
373{
374 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
375 int i;
376
377 dprintk("KVM MMU: slbia()\n");
378
379 for (i = 1; i < vcpu_book3s->slb_nr; i++)
380 vcpu_book3s->slb[i].valid = false;
381
382 if (vcpu->arch.msr & MSR_IR) {
383 kvmppc_mmu_flush_segments(vcpu);
384 kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc);
385 }
386}
387
388static void kvmppc_mmu_book3s_64_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
389 ulong value)
390{
391 u64 rb = 0, rs = 0;
392
393 /* ESID = srnum */
394 rb |= (srnum & 0xf) << 28;
395 /* Set the valid bit */
396 rb |= 1 << 27;
397 /* Index = ESID */
398 rb |= srnum;
399
400 /* VSID = VSID */
401 rs |= (value & 0xfffffff) << 12;
402 /* flags = flags */
403 rs |= ((value >> 27) & 0xf) << 9;
404
405 kvmppc_mmu_book3s_64_slbmte(vcpu, rs, rb);
406}
407
408static void kvmppc_mmu_book3s_64_tlbie(struct kvm_vcpu *vcpu, ulong va,
409 bool large)
410{
411 u64 mask = 0xFFFFFFFFFULL;
412
413 dprintk("KVM MMU: tlbie(0x%lx)\n", va);
414
415 if (large)
416 mask = 0xFFFFFF000ULL;
417 kvmppc_mmu_pte_vflush(vcpu, va >> 12, mask);
418}
419
420static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid,
421 u64 *vsid)
422{
423 switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
424 case 0:
425 *vsid = (VSID_REAL >> 16) | esid;
426 break;
427 case MSR_IR:
428 *vsid = (VSID_REAL_IR >> 16) | esid;
429 break;
430 case MSR_DR:
431 *vsid = (VSID_REAL_DR >> 16) | esid;
432 break;
433 case MSR_DR|MSR_IR:
434 {
435 ulong ea;
436 struct kvmppc_slb *slb;
437 ea = esid << SID_SHIFT;
438 slb = kvmppc_mmu_book3s_64_find_slbe(to_book3s(vcpu), ea);
439 if (slb)
440 *vsid = slb->vsid;
441 else
442 return -ENOENT;
443
444 break;
445 }
446 default:
447 BUG();
448 break;
449 }
450
451 return 0;
452}
453
454static bool kvmppc_mmu_book3s_64_is_dcbz32(struct kvm_vcpu *vcpu)
455{
456 return (to_book3s(vcpu)->hid[5] & 0x80);
457}
458
459void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu)
460{
461 struct kvmppc_mmu *mmu = &vcpu->arch.mmu;
462
463 mmu->mfsrin = NULL;
464 mmu->mtsrin = kvmppc_mmu_book3s_64_mtsrin;
465 mmu->slbmte = kvmppc_mmu_book3s_64_slbmte;
466 mmu->slbmfee = kvmppc_mmu_book3s_64_slbmfee;
467 mmu->slbmfev = kvmppc_mmu_book3s_64_slbmfev;
468 mmu->slbie = kvmppc_mmu_book3s_64_slbie;
469 mmu->slbia = kvmppc_mmu_book3s_64_slbia;
470 mmu->xlate = kvmppc_mmu_book3s_64_xlate;
471 mmu->reset_msr = kvmppc_mmu_book3s_64_reset_msr;
472 mmu->tlbie = kvmppc_mmu_book3s_64_tlbie;
473 mmu->esid_to_vsid = kvmppc_mmu_book3s_64_esid_to_vsid;
474 mmu->ea_to_vp = kvmppc_mmu_book3s_64_ea_to_vp;
475 mmu->is_dcbz32 = kvmppc_mmu_book3s_64_is_dcbz32;
476}
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
new file mode 100644
index 000000000000..f2899b297ffd
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -0,0 +1,408 @@
1/*
2 * Copyright (C) 2009 SUSE Linux Products GmbH. All rights reserved.
3 *
4 * Authors:
5 * Alexander Graf <agraf@suse.de>
6 * Kevin Wolf <mail@kevin-wolf.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License, version 2, as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#include <linux/kvm_host.h>
23
24#include <asm/kvm_ppc.h>
25#include <asm/kvm_book3s.h>
26#include <asm/mmu-hash64.h>
27#include <asm/machdep.h>
28#include <asm/mmu_context.h>
29#include <asm/hw_irq.h>
30
31#define PTE_SIZE 12
32#define VSID_ALL 0
33
34/* #define DEBUG_MMU */
35/* #define DEBUG_SLB */
36
37#ifdef DEBUG_MMU
38#define dprintk_mmu(a, ...) printk(KERN_INFO a, __VA_ARGS__)
39#else
40#define dprintk_mmu(a, ...) do { } while(0)
41#endif
42
43#ifdef DEBUG_SLB
44#define dprintk_slb(a, ...) printk(KERN_INFO a, __VA_ARGS__)
45#else
46#define dprintk_slb(a, ...) do { } while(0)
47#endif
48
49static void invalidate_pte(struct hpte_cache *pte)
50{
51 dprintk_mmu("KVM: Flushing SPT %d: 0x%llx (0x%llx) -> 0x%llx\n",
52 i, pte->pte.eaddr, pte->pte.vpage, pte->host_va);
53
54 ppc_md.hpte_invalidate(pte->slot, pte->host_va,
55 MMU_PAGE_4K, MMU_SEGSIZE_256M,
56 false);
57 pte->host_va = 0;
58 kvm_release_pfn_dirty(pte->pfn);
59}
60
61void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 guest_ea, u64 ea_mask)
62{
63 int i;
64
65 dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%llx & 0x%llx\n",
66 vcpu->arch.hpte_cache_offset, guest_ea, ea_mask);
67 BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM);
68
69 guest_ea &= ea_mask;
70 for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) {
71 struct hpte_cache *pte;
72
73 pte = &vcpu->arch.hpte_cache[i];
74 if (!pte->host_va)
75 continue;
76
77 if ((pte->pte.eaddr & ea_mask) == guest_ea) {
78 invalidate_pte(pte);
79 }
80 }
81
82 /* Doing a complete flush -> start from scratch */
83 if (!ea_mask)
84 vcpu->arch.hpte_cache_offset = 0;
85}
86
87void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask)
88{
89 int i;
90
91 dprintk_mmu("KVM: Flushing %d Shadow vPTEs: 0x%llx & 0x%llx\n",
92 vcpu->arch.hpte_cache_offset, guest_vp, vp_mask);
93 BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM);
94
95 guest_vp &= vp_mask;
96 for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) {
97 struct hpte_cache *pte;
98
99 pte = &vcpu->arch.hpte_cache[i];
100 if (!pte->host_va)
101 continue;
102
103 if ((pte->pte.vpage & vp_mask) == guest_vp) {
104 invalidate_pte(pte);
105 }
106 }
107}
108
109void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end)
110{
111 int i;
112
113 dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%llx & 0x%llx\n",
114 vcpu->arch.hpte_cache_offset, guest_pa, pa_mask);
115 BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM);
116
117 for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) {
118 struct hpte_cache *pte;
119
120 pte = &vcpu->arch.hpte_cache[i];
121 if (!pte->host_va)
122 continue;
123
124 if ((pte->pte.raddr >= pa_start) &&
125 (pte->pte.raddr < pa_end)) {
126 invalidate_pte(pte);
127 }
128 }
129}
130
131struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data)
132{
133 int i;
134 u64 guest_vp;
135
136 guest_vp = vcpu->arch.mmu.ea_to_vp(vcpu, ea, false);
137 for (i=0; i<vcpu->arch.hpte_cache_offset; i++) {
138 struct hpte_cache *pte;
139
140 pte = &vcpu->arch.hpte_cache[i];
141 if (!pte->host_va)
142 continue;
143
144 if (pte->pte.vpage == guest_vp)
145 return &pte->pte;
146 }
147
148 return NULL;
149}
150
151static int kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu)
152{
153 if (vcpu->arch.hpte_cache_offset == HPTEG_CACHE_NUM)
154 kvmppc_mmu_pte_flush(vcpu, 0, 0);
155
156 return vcpu->arch.hpte_cache_offset++;
157}
158
159/* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using
160 * a hash, so we don't waste cycles on looping */
161static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid)
162{
163 return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^
164 ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^
165 ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^
166 ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^
167 ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^
168 ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^
169 ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^
170 ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK));
171}
172
173
174static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid)
175{
176 struct kvmppc_sid_map *map;
177 u16 sid_map_mask;
178
179 if (vcpu->arch.msr & MSR_PR)
180 gvsid |= VSID_PR;
181
182 sid_map_mask = kvmppc_sid_hash(vcpu, gvsid);
183 map = &to_book3s(vcpu)->sid_map[sid_map_mask];
184 if (map->guest_vsid == gvsid) {
185 dprintk_slb("SLB: Searching 0x%llx -> 0x%llx\n",
186 gvsid, map->host_vsid);
187 return map;
188 }
189
190 map = &to_book3s(vcpu)->sid_map[SID_MAP_MASK - sid_map_mask];
191 if (map->guest_vsid == gvsid) {
192 dprintk_slb("SLB: Searching 0x%llx -> 0x%llx\n",
193 gvsid, map->host_vsid);
194 return map;
195 }
196
197 dprintk_slb("SLB: Searching 0x%llx -> not found\n", gvsid);
198 return NULL;
199}
200
201int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
202{
203 pfn_t hpaddr;
204 ulong hash, hpteg, va;
205 u64 vsid;
206 int ret;
207 int rflags = 0x192;
208 int vflags = 0;
209 int attempt = 0;
210 struct kvmppc_sid_map *map;
211
212 /* Get host physical address for gpa */
213 hpaddr = gfn_to_pfn(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT);
214 if (kvm_is_error_hva(hpaddr)) {
215 printk(KERN_INFO "Couldn't get guest page for gfn %llx!\n", orig_pte->eaddr);
216 return -EINVAL;
217 }
218 hpaddr <<= PAGE_SHIFT;
219#if PAGE_SHIFT == 12
220#elif PAGE_SHIFT == 16
221 hpaddr |= orig_pte->raddr & 0xf000;
222#else
223#error Unknown page size
224#endif
225
226 /* and write the mapping ea -> hpa into the pt */
227 vcpu->arch.mmu.esid_to_vsid(vcpu, orig_pte->eaddr >> SID_SHIFT, &vsid);
228 map = find_sid_vsid(vcpu, vsid);
229 if (!map) {
230 kvmppc_mmu_map_segment(vcpu, orig_pte->eaddr);
231 map = find_sid_vsid(vcpu, vsid);
232 }
233 BUG_ON(!map);
234
235 vsid = map->host_vsid;
236 va = hpt_va(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M);
237
238 if (!orig_pte->may_write)
239 rflags |= HPTE_R_PP;
240 else
241 mark_page_dirty(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT);
242
243 if (!orig_pte->may_execute)
244 rflags |= HPTE_R_N;
245
246 hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M);
247
248map_again:
249 hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
250
251 /* In case we tried normal mapping already, let's nuke old entries */
252 if (attempt > 1)
253 if (ppc_md.hpte_remove(hpteg) < 0)
254 return -1;
255
256 ret = ppc_md.hpte_insert(hpteg, va, hpaddr, rflags, vflags, MMU_PAGE_4K, MMU_SEGSIZE_256M);
257
258 if (ret < 0) {
259 /* If we couldn't map a primary PTE, try a secondary */
260#ifdef USE_SECONDARY
261 hash = ~hash;
262 attempt++;
263 if (attempt % 2)
264 vflags = HPTE_V_SECONDARY;
265 else
266 vflags = 0;
267#else
268 attempt = 2;
269#endif
270 goto map_again;
271 } else {
272 int hpte_id = kvmppc_mmu_hpte_cache_next(vcpu);
273 struct hpte_cache *pte = &vcpu->arch.hpte_cache[hpte_id];
274
275 dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%lx (0x%llx) -> %lx\n",
276 ((rflags & HPTE_R_PP) == 3) ? '-' : 'w',
277 (rflags & HPTE_R_N) ? '-' : 'x',
278 orig_pte->eaddr, hpteg, va, orig_pte->vpage, hpaddr);
279
280 pte->slot = hpteg + (ret & 7);
281 pte->host_va = va;
282 pte->pte = *orig_pte;
283 pte->pfn = hpaddr >> PAGE_SHIFT;
284 }
285
286 return 0;
287}
288
289static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
290{
291 struct kvmppc_sid_map *map;
292 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
293 u16 sid_map_mask;
294 static int backwards_map = 0;
295
296 if (vcpu->arch.msr & MSR_PR)
297 gvsid |= VSID_PR;
298
299 /* We might get collisions that trap in preceding order, so let's
300 map them differently */
301
302 sid_map_mask = kvmppc_sid_hash(vcpu, gvsid);
303 if (backwards_map)
304 sid_map_mask = SID_MAP_MASK - sid_map_mask;
305
306 map = &to_book3s(vcpu)->sid_map[sid_map_mask];
307
308 /* Make sure we're taking the other map next time */
309 backwards_map = !backwards_map;
310
311 /* Uh-oh ... out of mappings. Let's flush! */
312 if (vcpu_book3s->vsid_next == vcpu_book3s->vsid_max) {
313 vcpu_book3s->vsid_next = vcpu_book3s->vsid_first;
314 memset(vcpu_book3s->sid_map, 0,
315 sizeof(struct kvmppc_sid_map) * SID_MAP_NUM);
316 kvmppc_mmu_pte_flush(vcpu, 0, 0);
317 kvmppc_mmu_flush_segments(vcpu);
318 }
319 map->host_vsid = vcpu_book3s->vsid_next++;
320
321 map->guest_vsid = gvsid;
322 map->valid = true;
323
324 return map;
325}
326
327static int kvmppc_mmu_next_segment(struct kvm_vcpu *vcpu, ulong esid)
328{
329 int i;
330 int max_slb_size = 64;
331 int found_inval = -1;
332 int r;
333
334 if (!get_paca()->kvm_slb_max)
335 get_paca()->kvm_slb_max = 1;
336
337 /* Are we overwriting? */
338 for (i = 1; i < get_paca()->kvm_slb_max; i++) {
339 if (!(get_paca()->kvm_slb[i].esid & SLB_ESID_V))
340 found_inval = i;
341 else if ((get_paca()->kvm_slb[i].esid & ESID_MASK) == esid)
342 return i;
343 }
344
345 /* Found a spare entry that was invalidated before */
346 if (found_inval > 0)
347 return found_inval;
348
349 /* No spare invalid entry, so create one */
350
351 if (mmu_slb_size < 64)
352 max_slb_size = mmu_slb_size;
353
354 /* Overflowing -> purge */
355 if ((get_paca()->kvm_slb_max) == max_slb_size)
356 kvmppc_mmu_flush_segments(vcpu);
357
358 r = get_paca()->kvm_slb_max;
359 get_paca()->kvm_slb_max++;
360
361 return r;
362}
363
364int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr)
365{
366 u64 esid = eaddr >> SID_SHIFT;
367 u64 slb_esid = (eaddr & ESID_MASK) | SLB_ESID_V;
368 u64 slb_vsid = SLB_VSID_USER;
369 u64 gvsid;
370 int slb_index;
371 struct kvmppc_sid_map *map;
372
373 slb_index = kvmppc_mmu_next_segment(vcpu, eaddr & ESID_MASK);
374
375 if (vcpu->arch.mmu.esid_to_vsid(vcpu, esid, &gvsid)) {
376 /* Invalidate an entry */
377 get_paca()->kvm_slb[slb_index].esid = 0;
378 return -ENOENT;
379 }
380
381 map = find_sid_vsid(vcpu, gvsid);
382 if (!map)
383 map = create_sid_map(vcpu, gvsid);
384
385 map->guest_esid = esid;
386
387 slb_vsid |= (map->host_vsid << 12);
388 slb_vsid &= ~SLB_VSID_KP;
389 slb_esid |= slb_index;
390
391 get_paca()->kvm_slb[slb_index].esid = slb_esid;
392 get_paca()->kvm_slb[slb_index].vsid = slb_vsid;
393
394 dprintk_slb("slbmte %#llx, %#llx\n", slb_vsid, slb_esid);
395
396 return 0;
397}
398
399void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu)
400{
401 get_paca()->kvm_slb_max = 1;
402 get_paca()->kvm_slb[0].esid = 0;
403}
404
405void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
406{
407 kvmppc_mmu_pte_flush(vcpu, 0, 0);
408}
diff --git a/arch/powerpc/kvm/book3s_64_rmhandlers.S b/arch/powerpc/kvm/book3s_64_rmhandlers.S
new file mode 100644
index 000000000000..fb7dd2e9ac88
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_rmhandlers.S
@@ -0,0 +1,131 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#include <asm/ppc_asm.h>
21#include <asm/kvm_asm.h>
22#include <asm/reg.h>
23#include <asm/page.h>
24#include <asm/asm-offsets.h>
25#include <asm/exception-64s.h>
26
27/*****************************************************************************
28 * *
29 * Real Mode handlers that need to be in low physical memory *
30 * *
31 ****************************************************************************/
32
33
34.macro INTERRUPT_TRAMPOLINE intno
35
36.global kvmppc_trampoline_\intno
37kvmppc_trampoline_\intno:
38
39 mtspr SPRN_SPRG_SCRATCH0, r13 /* Save r13 */
40
41 /*
42 * First thing to do is to find out if we're coming
43 * from a KVM guest or a Linux process.
44 *
45 * To distinguish, we check a magic byte in the PACA
46 */
47 mfspr r13, SPRN_SPRG_PACA /* r13 = PACA */
48 std r12, (PACA_EXMC + EX_R12)(r13)
49 mfcr r12
50 stw r12, (PACA_EXMC + EX_CCR)(r13)
51 lbz r12, PACA_KVM_IN_GUEST(r13)
52 cmpwi r12, 0
53 bne ..kvmppc_handler_hasmagic_\intno
54 /* No KVM guest? Then jump back to the Linux handler! */
55 lwz r12, (PACA_EXMC + EX_CCR)(r13)
56 mtcr r12
57 ld r12, (PACA_EXMC + EX_R12)(r13)
58 mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */
59 b kvmppc_resume_\intno /* Get back original handler */
60
61 /* Now we know we're handling a KVM guest */
62..kvmppc_handler_hasmagic_\intno:
63 /* Unset guest state */
64 li r12, 0
65 stb r12, PACA_KVM_IN_GUEST(r13)
66
67 std r1, (PACA_EXMC+EX_R9)(r13)
68 std r10, (PACA_EXMC+EX_R10)(r13)
69 std r11, (PACA_EXMC+EX_R11)(r13)
70 std r2, (PACA_EXMC+EX_R13)(r13)
71
72 mfsrr0 r10
73 mfsrr1 r11
74
75 /* Restore R1/R2 so we can handle faults */
76 ld r1, PACAR1(r13)
77 ld r2, (PACA_EXMC+EX_SRR0)(r13)
78
79 /* Let's store which interrupt we're handling */
80 li r12, \intno
81
82 /* Jump into the SLB exit code that goes to the highmem handler */
83 b kvmppc_handler_trampoline_exit
84
85.endm
86
87INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET
88INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK
89INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE
90INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_SEGMENT
91INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE
92INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_SEGMENT
93INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL
94INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT
95INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM
96INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL
97INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER
98INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL
99INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE
100INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON
101INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC
102INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_VSX
103
104/*
105 * This trampoline brings us back to a real mode handler
106 *
107 * Input Registers:
108 *
109 * R6 = SRR0
110 * R7 = SRR1
111 * LR = real-mode IP
112 *
113 */
114.global kvmppc_handler_lowmem_trampoline
115kvmppc_handler_lowmem_trampoline:
116
117 mtsrr0 r6
118 mtsrr1 r7
119 blr
120kvmppc_handler_lowmem_trampoline_end:
121
122.global kvmppc_trampoline_lowmem
123kvmppc_trampoline_lowmem:
124 .long kvmppc_handler_lowmem_trampoline - _stext
125
126.global kvmppc_trampoline_enter
127kvmppc_trampoline_enter:
128 .long kvmppc_handler_trampoline_enter - _stext
129
130#include "book3s_64_slb.S"
131
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S
new file mode 100644
index 000000000000..ecd237a03fd0
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_slb.S
@@ -0,0 +1,262 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright SUSE Linux Products GmbH 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#define SHADOW_SLB_ESID(num) (SLBSHADOW_SAVEAREA + (num * 0x10))
21#define SHADOW_SLB_VSID(num) (SLBSHADOW_SAVEAREA + (num * 0x10) + 0x8)
22#define UNBOLT_SLB_ENTRY(num) \
23 ld r9, SHADOW_SLB_ESID(num)(r12); \
24 /* Invalid? Skip. */; \
25 rldicl. r0, r9, 37, 63; \
26 beq slb_entry_skip_ ## num; \
27 xoris r9, r9, SLB_ESID_V@h; \
28 std r9, SHADOW_SLB_ESID(num)(r12); \
29 slb_entry_skip_ ## num:
30
31#define REBOLT_SLB_ENTRY(num) \
32 ld r10, SHADOW_SLB_ESID(num)(r11); \
33 cmpdi r10, 0; \
34 beq slb_exit_skip_1; \
35 oris r10, r10, SLB_ESID_V@h; \
36 ld r9, SHADOW_SLB_VSID(num)(r11); \
37 slbmte r9, r10; \
38 std r10, SHADOW_SLB_ESID(num)(r11); \
39slb_exit_skip_ ## num:
40
41/******************************************************************************
42 * *
43 * Entry code *
44 * *
45 *****************************************************************************/
46
47.global kvmppc_handler_trampoline_enter
48kvmppc_handler_trampoline_enter:
49
50 /* Required state:
51 *
52 * MSR = ~IR|DR
53 * R13 = PACA
54 * R9 = guest IP
55 * R10 = guest MSR
56 * R11 = free
57 * R12 = free
58 * PACA[PACA_EXMC + EX_R9] = guest R9
59 * PACA[PACA_EXMC + EX_R10] = guest R10
60 * PACA[PACA_EXMC + EX_R11] = guest R11
61 * PACA[PACA_EXMC + EX_R12] = guest R12
62 * PACA[PACA_EXMC + EX_R13] = guest R13
63 * PACA[PACA_EXMC + EX_CCR] = guest CR
64 * PACA[PACA_EXMC + EX_R3] = guest XER
65 */
66
67 mtsrr0 r9
68 mtsrr1 r10
69
70 mtspr SPRN_SPRG_SCRATCH0, r0
71
72 /* Remove LPAR shadow entries */
73
74#if SLB_NUM_BOLTED == 3
75
76 ld r12, PACA_SLBSHADOWPTR(r13)
77
78 /* Save off the first entry so we can slbie it later */
79 ld r10, SHADOW_SLB_ESID(0)(r12)
80 ld r11, SHADOW_SLB_VSID(0)(r12)
81
82 /* Remove bolted entries */
83 UNBOLT_SLB_ENTRY(0)
84 UNBOLT_SLB_ENTRY(1)
85 UNBOLT_SLB_ENTRY(2)
86
87#else
88#error unknown number of bolted entries
89#endif
90
91 /* Flush SLB */
92
93 slbia
94
95 /* r0 = esid & ESID_MASK */
96 rldicr r10, r10, 0, 35
97 /* r0 |= CLASS_BIT(VSID) */
98 rldic r12, r11, 56 - 36, 36
99 or r10, r10, r12
100 slbie r10
101
102 isync
103
104 /* Fill SLB with our shadow */
105
106 lbz r12, PACA_KVM_SLB_MAX(r13)
107 mulli r12, r12, 16
108 addi r12, r12, PACA_KVM_SLB
109 add r12, r12, r13
110
111 /* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */
112 li r11, PACA_KVM_SLB
113 add r11, r11, r13
114
115slb_loop_enter:
116
117 ld r10, 0(r11)
118
119 rldicl. r0, r10, 37, 63
120 beq slb_loop_enter_skip
121
122 ld r9, 8(r11)
123 slbmte r9, r10
124
125slb_loop_enter_skip:
126 addi r11, r11, 16
127 cmpd cr0, r11, r12
128 blt slb_loop_enter
129
130slb_do_enter:
131
132 /* Enter guest */
133
134 mfspr r0, SPRN_SPRG_SCRATCH0
135
136 ld r9, (PACA_EXMC+EX_R9)(r13)
137 ld r10, (PACA_EXMC+EX_R10)(r13)
138 ld r12, (PACA_EXMC+EX_R12)(r13)
139
140 lwz r11, (PACA_EXMC+EX_CCR)(r13)
141 mtcr r11
142
143 ld r11, (PACA_EXMC+EX_R3)(r13)
144 mtxer r11
145
146 ld r11, (PACA_EXMC+EX_R11)(r13)
147 ld r13, (PACA_EXMC+EX_R13)(r13)
148
149 RFI
150kvmppc_handler_trampoline_enter_end:
151
152
153
154/******************************************************************************
155 * *
156 * Exit code *
157 * *
158 *****************************************************************************/
159
160.global kvmppc_handler_trampoline_exit
161kvmppc_handler_trampoline_exit:
162
163 /* Register usage at this point:
164 *
165 * SPRG_SCRATCH0 = guest R13
166 * R01 = host R1
167 * R02 = host R2
168 * R10 = guest PC
169 * R11 = guest MSR
170 * R12 = exit handler id
171 * R13 = PACA
172 * PACA.exmc.CCR = guest CR
173 * PACA.exmc.R9 = guest R1
174 * PACA.exmc.R10 = guest R10
175 * PACA.exmc.R11 = guest R11
176 * PACA.exmc.R12 = guest R12
177 * PACA.exmc.R13 = guest R2
178 *
179 */
180
181 /* Save registers */
182
183 std r0, (PACA_EXMC+EX_SRR0)(r13)
184 std r9, (PACA_EXMC+EX_R3)(r13)
185 std r10, (PACA_EXMC+EX_LR)(r13)
186 std r11, (PACA_EXMC+EX_DAR)(r13)
187
188 /*
189 * In order for us to easily get the last instruction,
190 * we got the #vmexit at, we exploit the fact that the
191 * virtual layout is still the same here, so we can just
192 * ld from the guest's PC address
193 */
194
195 /* We only load the last instruction when it's safe */
196 cmpwi r12, BOOK3S_INTERRUPT_DATA_STORAGE
197 beq ld_last_inst
198 cmpwi r12, BOOK3S_INTERRUPT_PROGRAM
199 beq ld_last_inst
200
201 b no_ld_last_inst
202
203ld_last_inst:
204 /* Save off the guest instruction we're at */
205 /* 1) enable paging for data */
206 mfmsr r9
207 ori r11, r9, MSR_DR /* Enable paging for data */
208 mtmsr r11
209 /* 2) fetch the instruction */
210 lwz r0, 0(r10)
211 /* 3) disable paging again */
212 mtmsr r9
213
214no_ld_last_inst:
215
216 /* Restore bolted entries from the shadow and fix it along the way */
217
218 /* We don't store anything in entry 0, so we don't need to take care of it */
219 slbia
220 isync
221
222#if SLB_NUM_BOLTED == 3
223
224 ld r11, PACA_SLBSHADOWPTR(r13)
225
226 REBOLT_SLB_ENTRY(0)
227 REBOLT_SLB_ENTRY(1)
228 REBOLT_SLB_ENTRY(2)
229
230#else
231#error unknown number of bolted entries
232#endif
233
234slb_do_exit:
235
236 /* Restore registers */
237
238 ld r11, (PACA_EXMC+EX_DAR)(r13)
239 ld r10, (PACA_EXMC+EX_LR)(r13)
240 ld r9, (PACA_EXMC+EX_R3)(r13)
241
242 /* Save last inst */
243 stw r0, (PACA_EXMC+EX_LR)(r13)
244
245 /* Save DAR and DSISR before going to paged mode */
246 mfdar r0
247 std r0, (PACA_EXMC+EX_DAR)(r13)
248 mfdsisr r0
249 stw r0, (PACA_EXMC+EX_DSISR)(r13)
250
251 /* RFI into the highmem handler */
252 mfmsr r0
253 ori r0, r0, MSR_IR|MSR_DR|MSR_RI /* Enable paging */
254 mtsrr1 r0
255 ld r0, PACASAVEDMSR(r13) /* Highmem handler address */
256 mtsrr0 r0
257
258 mfspr r0, SPRN_SPRG_SCRATCH0
259
260 RFI
261kvmppc_handler_trampoline_exit_end:
262
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index e7bf4d029484..06f5a9ecc42c 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -520,6 +520,11 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
520 return kvmppc_core_vcpu_translate(vcpu, tr); 520 return kvmppc_core_vcpu_translate(vcpu, tr);
521} 521}
522 522
523int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
524{
525 return -ENOTSUPP;
526}
527
523int __init kvmppc_booke_init(void) 528int __init kvmppc_booke_init(void)
524{ 529{
525 unsigned long ivor[16]; 530 unsigned long ivor[16];
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 7737146af3fb..4a9ac6640fad 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -18,7 +18,7 @@
18 */ 18 */
19 19
20#include <linux/jiffies.h> 20#include <linux/jiffies.h>
21#include <linux/timer.h> 21#include <linux/hrtimer.h>
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/kvm_host.h> 24#include <linux/kvm_host.h>
@@ -32,6 +32,7 @@
32#include "trace.h" 32#include "trace.h"
33 33
34#define OP_TRAP 3 34#define OP_TRAP 3
35#define OP_TRAP_64 2
35 36
36#define OP_31_XOP_LWZX 23 37#define OP_31_XOP_LWZX 23
37#define OP_31_XOP_LBZX 87 38#define OP_31_XOP_LBZX 87
@@ -64,19 +65,45 @@
64#define OP_STH 44 65#define OP_STH 44
65#define OP_STHU 45 66#define OP_STHU 45
66 67
68#ifdef CONFIG_PPC64
69static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
70{
71 return 1;
72}
73#else
74static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
75{
76 return vcpu->arch.tcr & TCR_DIE;
77}
78#endif
79
67void kvmppc_emulate_dec(struct kvm_vcpu *vcpu) 80void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
68{ 81{
69 if (vcpu->arch.tcr & TCR_DIE) { 82 unsigned long dec_nsec;
83
84 pr_debug("mtDEC: %x\n", vcpu->arch.dec);
85#ifdef CONFIG_PPC64
86 /* POWER4+ triggers a dec interrupt if the value is < 0 */
87 if (vcpu->arch.dec & 0x80000000) {
88 hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
89 kvmppc_core_queue_dec(vcpu);
90 return;
91 }
92#endif
93 if (kvmppc_dec_enabled(vcpu)) {
70 /* The decrementer ticks at the same rate as the timebase, so 94 /* The decrementer ticks at the same rate as the timebase, so
71 * that's how we convert the guest DEC value to the number of 95 * that's how we convert the guest DEC value to the number of
72 * host ticks. */ 96 * host ticks. */
73 unsigned long nr_jiffies;
74 97
75 nr_jiffies = vcpu->arch.dec / tb_ticks_per_jiffy; 98 hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
76 mod_timer(&vcpu->arch.dec_timer, 99 dec_nsec = vcpu->arch.dec;
77 get_jiffies_64() + nr_jiffies); 100 dec_nsec *= 1000;
101 dec_nsec /= tb_ticks_per_usec;
102 hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
103 HRTIMER_MODE_REL);
104 vcpu->arch.dec_jiffies = get_tb();
78 } else { 105 } else {
79 del_timer(&vcpu->arch.dec_timer); 106 hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
80 } 107 }
81} 108}
82 109
@@ -111,9 +138,15 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
111 /* this default type might be overwritten by subcategories */ 138 /* this default type might be overwritten by subcategories */
112 kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); 139 kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
113 140
141 pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
142
114 switch (get_op(inst)) { 143 switch (get_op(inst)) {
115 case OP_TRAP: 144 case OP_TRAP:
145#ifdef CONFIG_PPC64
146 case OP_TRAP_64:
147#else
116 vcpu->arch.esr |= ESR_PTR; 148 vcpu->arch.esr |= ESR_PTR;
149#endif
117 kvmppc_core_queue_program(vcpu); 150 kvmppc_core_queue_program(vcpu);
118 advance = 0; 151 advance = 0;
119 break; 152 break;
@@ -188,17 +221,19 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
188 case SPRN_SRR1: 221 case SPRN_SRR1:
189 vcpu->arch.gpr[rt] = vcpu->arch.srr1; break; 222 vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
190 case SPRN_PVR: 223 case SPRN_PVR:
191 vcpu->arch.gpr[rt] = mfspr(SPRN_PVR); break; 224 vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
192 case SPRN_PIR: 225 case SPRN_PIR:
193 vcpu->arch.gpr[rt] = mfspr(SPRN_PIR); break; 226 vcpu->arch.gpr[rt] = vcpu->vcpu_id; break;
227 case SPRN_MSSSR0:
228 vcpu->arch.gpr[rt] = 0; break;
194 229
195 /* Note: mftb and TBRL/TBWL are user-accessible, so 230 /* Note: mftb and TBRL/TBWL are user-accessible, so
196 * the guest can always access the real TB anyways. 231 * the guest can always access the real TB anyways.
197 * In fact, we probably will never see these traps. */ 232 * In fact, we probably will never see these traps. */
198 case SPRN_TBWL: 233 case SPRN_TBWL:
199 vcpu->arch.gpr[rt] = mftbl(); break; 234 vcpu->arch.gpr[rt] = get_tb() >> 32; break;
200 case SPRN_TBWU: 235 case SPRN_TBWU:
201 vcpu->arch.gpr[rt] = mftbu(); break; 236 vcpu->arch.gpr[rt] = get_tb(); break;
202 237
203 case SPRN_SPRG0: 238 case SPRN_SPRG0:
204 vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break; 239 vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break;
@@ -211,6 +246,13 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
211 /* Note: SPRG4-7 are user-readable, so we don't get 246 /* Note: SPRG4-7 are user-readable, so we don't get
212 * a trap. */ 247 * a trap. */
213 248
249 case SPRN_DEC:
250 {
251 u64 jd = get_tb() - vcpu->arch.dec_jiffies;
252 vcpu->arch.gpr[rt] = vcpu->arch.dec - jd;
253 pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, vcpu->arch.gpr[rt]);
254 break;
255 }
214 default: 256 default:
215 emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt); 257 emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
216 if (emulated == EMULATE_FAIL) { 258 if (emulated == EMULATE_FAIL) {
@@ -260,6 +302,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
260 case SPRN_TBWL: break; 302 case SPRN_TBWL: break;
261 case SPRN_TBWU: break; 303 case SPRN_TBWU: break;
262 304
305 case SPRN_MSSSR0: break;
306
263 case SPRN_DEC: 307 case SPRN_DEC:
264 vcpu->arch.dec = vcpu->arch.gpr[rs]; 308 vcpu->arch.dec = vcpu->arch.gpr[rs];
265 kvmppc_emulate_dec(vcpu); 309 kvmppc_emulate_dec(vcpu);
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2a4551f78f60..692c3709011e 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -23,6 +23,7 @@
23#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
26#include <linux/hrtimer.h>
26#include <linux/fs.h> 27#include <linux/fs.h>
27#include <asm/cputable.h> 28#include <asm/cputable.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
@@ -208,10 +209,25 @@ static void kvmppc_decrementer_func(unsigned long data)
208 } 209 }
209} 210}
210 211
212/*
213 * low level hrtimer wake routine. Because this runs in hardirq context
214 * we schedule a tasklet to do the real work.
215 */
216enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer)
217{
218 struct kvm_vcpu *vcpu;
219
220 vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer);
221 tasklet_schedule(&vcpu->arch.tasklet);
222
223 return HRTIMER_NORESTART;
224}
225
211int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) 226int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
212{ 227{
213 setup_timer(&vcpu->arch.dec_timer, kvmppc_decrementer_func, 228 hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
214 (unsigned long)vcpu); 229 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
230 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
215 231
216 return 0; 232 return 0;
217} 233}
@@ -409,11 +425,6 @@ out:
409 return r; 425 return r;
410} 426}
411 427
412int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
413{
414 return -ENOTSUPP;
415}
416
417long kvm_arch_vm_ioctl(struct file *filp, 428long kvm_arch_vm_ioctl(struct file *filp,
418 unsigned int ioctl, unsigned long arg) 429 unsigned int ioctl, unsigned long arg)
419{ 430{
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h
index 67f219de0455..a8e840018052 100644
--- a/arch/powerpc/kvm/trace.h
+++ b/arch/powerpc/kvm/trace.h
@@ -12,8 +12,8 @@
12 * Tracepoint for guest mode entry. 12 * Tracepoint for guest mode entry.
13 */ 13 */
14TRACE_EVENT(kvm_ppc_instr, 14TRACE_EVENT(kvm_ppc_instr,
15 TP_PROTO(unsigned int inst, unsigned long pc, unsigned int emulate), 15 TP_PROTO(unsigned int inst, unsigned long _pc, unsigned int emulate),
16 TP_ARGS(inst, pc, emulate), 16 TP_ARGS(inst, _pc, emulate),
17 17
18 TP_STRUCT__entry( 18 TP_STRUCT__entry(
19 __field( unsigned int, inst ) 19 __field( unsigned int, inst )
@@ -23,7 +23,7 @@ TRACE_EVENT(kvm_ppc_instr,
23 23
24 TP_fast_assign( 24 TP_fast_assign(
25 __entry->inst = inst; 25 __entry->inst = inst;
26 __entry->pc = pc; 26 __entry->pc = _pc;
27 __entry->emulate = emulate; 27 __entry->emulate = emulate;
28 ), 28 ),
29 29
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index fa251f8c2f82..6810128aba30 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -92,6 +92,7 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
92struct hash_pte *htab_address; 92struct hash_pte *htab_address;
93unsigned long htab_size_bytes; 93unsigned long htab_size_bytes;
94unsigned long htab_hash_mask; 94unsigned long htab_hash_mask;
95EXPORT_SYMBOL_GPL(htab_hash_mask);
95int mmu_linear_psize = MMU_PAGE_4K; 96int mmu_linear_psize = MMU_PAGE_4K;
96int mmu_virtual_psize = MMU_PAGE_4K; 97int mmu_virtual_psize = MMU_PAGE_4K;
97int mmu_vmalloc_psize = MMU_PAGE_4K; 98int mmu_vmalloc_psize = MMU_PAGE_4K;
@@ -102,6 +103,7 @@ int mmu_io_psize = MMU_PAGE_4K;
102int mmu_kernel_ssize = MMU_SEGSIZE_256M; 103int mmu_kernel_ssize = MMU_SEGSIZE_256M;
103int mmu_highuser_ssize = MMU_SEGSIZE_256M; 104int mmu_highuser_ssize = MMU_SEGSIZE_256M;
104u16 mmu_slb_size = 64; 105u16 mmu_slb_size = 64;
106EXPORT_SYMBOL_GPL(mmu_slb_size);
105#ifdef CONFIG_HUGETLB_PAGE 107#ifdef CONFIG_HUGETLB_PAGE
106unsigned int HPAGE_SHIFT; 108unsigned int HPAGE_SHIFT;
107#endif 109#endif
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index dbeb86ac90cd..b9e4cc2c2057 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -18,6 +18,7 @@
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/idr.h> 20#include <linux/idr.h>
21#include <linux/module.h>
21 22
22#include <asm/mmu_context.h> 23#include <asm/mmu_context.h>
23 24
@@ -32,7 +33,7 @@ static DEFINE_IDR(mmu_context_idr);
32#define NO_CONTEXT 0 33#define NO_CONTEXT 0
33#define MAX_CONTEXT ((1UL << 19) - 1) 34#define MAX_CONTEXT ((1UL << 19) - 1)
34 35
35int init_new_context(struct task_struct *tsk, struct mm_struct *mm) 36int __init_new_context(void)
36{ 37{
37 int index; 38 int index;
38 int err; 39 int err;
@@ -57,6 +58,18 @@ again:
57 return -ENOMEM; 58 return -ENOMEM;
58 } 59 }
59 60
61 return index;
62}
63EXPORT_SYMBOL_GPL(__init_new_context);
64
65int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
66{
67 int index;
68
69 index = __init_new_context();
70 if (index < 0)
71 return index;
72
60 /* The old code would re-promote on fork, we don't do that 73 /* The old code would re-promote on fork, we don't do that
61 * when using slices as it could cause problem promoting slices 74 * when using slices as it could cause problem promoting slices
62 * that have been forced down to 4K 75 * that have been forced down to 4K
@@ -68,11 +81,16 @@ again:
68 return 0; 81 return 0;
69} 82}
70 83
71void destroy_context(struct mm_struct *mm) 84void __destroy_context(int context_id)
72{ 85{
73 spin_lock(&mmu_context_lock); 86 spin_lock(&mmu_context_lock);
74 idr_remove(&mmu_context_idr, mm->context.id); 87 idr_remove(&mmu_context_idr, context_id);
75 spin_unlock(&mmu_context_lock); 88 spin_unlock(&mmu_context_lock);
89}
90EXPORT_SYMBOL_GPL(__destroy_context);
76 91
92void destroy_context(struct mm_struct *mm)
93{
94 __destroy_context(mm->context.id);
77 mm->context.id = NO_CONTEXT; 95 mm->context.id = NO_CONTEXT;
78} 96}