aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHollis Blanchard <hollisb@us.ibm.com>2008-04-17 00:28:09 -0400
committerAvi Kivity <avi@qumranet.com>2008-04-27 11:21:39 -0400
commitbbf45ba57eaec56569918a8bab96ab653bd45ec1 (patch)
tree63c53b1c1d93ec6559c7695c16b2345238e270f5
parent513014b717203d1d689652d0fda86eee959a6a8a (diff)
KVM: ppc: PowerPC 440 KVM implementation
This functionality is definitely experimental, but is capable of running unmodified PowerPC 440 Linux kernels as guests on a PowerPC 440 host. (Only tested with 440EP "Bamboo" guests so far, but with appropriate userspace support other SoC/board combinations should work.) See Documentation/powerpc/kvm_440.txt for technical details. [stephen: build fix] Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com> Acked-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--Documentation/powerpc/kvm_440.txt41
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/Kconfig.debug3
-rw-r--r--arch/powerpc/Makefile1
-rw-r--r--arch/powerpc/kernel/asm-offsets.c28
-rw-r--r--arch/powerpc/kvm/44x_tlb.c224
-rw-r--r--arch/powerpc/kvm/44x_tlb.h91
-rw-r--r--arch/powerpc/kvm/Kconfig42
-rw-r--r--arch/powerpc/kvm/Makefile15
-rw-r--r--arch/powerpc/kvm/booke_guest.c615
-rw-r--r--arch/powerpc/kvm/booke_host.c83
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S436
-rw-r--r--arch/powerpc/kvm/emulate.c760
-rw-r--r--arch/powerpc/kvm/powerpc.c436
-rw-r--r--include/asm-powerpc/kvm.h53
-rw-r--r--include/asm-powerpc/kvm_asm.h55
-rw-r--r--include/asm-powerpc/kvm_host.h152
-rw-r--r--include/asm-powerpc/kvm_para.h37
-rw-r--r--include/asm-powerpc/kvm_ppc.h88
19 files changed, 3159 insertions, 2 deletions
diff --git a/Documentation/powerpc/kvm_440.txt b/Documentation/powerpc/kvm_440.txt
new file mode 100644
index 000000000000..c02a003fa03a
--- /dev/null
+++ b/Documentation/powerpc/kvm_440.txt
@@ -0,0 +1,41 @@
1Hollis Blanchard <hollisb@us.ibm.com>
215 Apr 2008
3
4Various notes on the implementation of KVM for PowerPC 440:
5
6To enforce isolation, host userspace, guest kernel, and guest userspace all
7run at user privilege level. Only the host kernel runs in supervisor mode.
8Executing privileged instructions in the guest traps into KVM (in the host
9kernel), where we decode and emulate them. Through this technique, unmodified
10440 Linux kernels can be run (slowly) as guests. Future performance work will
11focus on reducing the overhead and frequency of these traps.
12
13The usual code flow is started from userspace invoking an "run" ioctl, which
14causes KVM to switch into guest context. We use IVPR to hijack the host
15interrupt vectors while running the guest, which allows us to direct all
16interrupts to kvmppc_handle_interrupt(). At this point, we could either
17- handle the interrupt completely (e.g. emulate "mtspr SPRG0"), or
18- let the host interrupt handler run (e.g. when the decrementer fires), or
19- return to host userspace (e.g. when the guest performs device MMIO)
20
21Address spaces: We take advantage of the fact that Linux doesn't use the AS=1
22address space (in host or guest), which gives us virtual address space to use
23for guest mappings. While the guest is running, the host kernel remains mapped
24in AS=0, but the guest can only use AS=1 mappings.
25
26TLB entries: The TLB entries covering the host linear mapping remain
27present while running the guest. This reduces the overhead of lightweight
28exits, which are handled by KVM running in the host kernel. We keep three
29copies of the TLB:
30 - guest TLB: contents of the TLB as the guest sees it
31 - shadow TLB: the TLB that is actually in hardware while guest is running
32 - host TLB: to restore TLB state when context switching guest -> host
33When a TLB miss occurs because a mapping was not present in the shadow TLB,
34but was present in the guest TLB, KVM handles the fault without invoking the
35guest. Large guest pages are backed by multiple 4KB shadow pages through this
36mechanism.
37
38IO: MMIO and DCR accesses are emulated by userspace. We use virtio for network
39and block IO, so those drivers must be enabled in the guest. It's possible
40that some qemu device emulation (e.g. e1000 or rtl8139) may also work with
41little effort.
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 20f45a8b87e3..4e40c122bf26 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -803,3 +803,4 @@ config PPC_CLOCK
803config PPC_LIB_RHEAP 803config PPC_LIB_RHEAP
804 bool 804 bool
805 805
806source "arch/powerpc/kvm/Kconfig"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index a86d8d853214..807a2dce6263 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -151,6 +151,9 @@ config BOOTX_TEXT
151 151
152config PPC_EARLY_DEBUG 152config PPC_EARLY_DEBUG
153 bool "Early debugging (dangerous)" 153 bool "Early debugging (dangerous)"
154 # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water
155 # mark, which doesn't work with current 440 KVM.
156 depends on !KVM
154 help 157 help
155 Say Y to enable some early debugging facilities that may be available 158 Say Y to enable some early debugging facilities that may be available
156 for your processor/board combination. Those facilities are hacks 159 for your processor/board combination. Those facilities are hacks
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index e2ec4a91ccef..9dcdc036cdf7 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -145,6 +145,7 @@ core-y += arch/powerpc/kernel/ \
145 arch/powerpc/platforms/ 145 arch/powerpc/platforms/
146core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/ 146core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/
147core-$(CONFIG_XMON) += arch/powerpc/xmon/ 147core-$(CONFIG_XMON) += arch/powerpc/xmon/
148core-$(CONFIG_KVM) += arch/powerpc/kvm/
148 149
149drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 150drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
150 151
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index adf1d09d726f..62134845af08 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -23,6 +23,9 @@
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/suspend.h> 24#include <linux/suspend.h>
25#include <linux/hrtimer.h> 25#include <linux/hrtimer.h>
26#ifdef CONFIG_KVM
27#include <linux/kvm_host.h>
28#endif
26#ifdef CONFIG_PPC64 29#ifdef CONFIG_PPC64
27#include <linux/time.h> 30#include <linux/time.h>
28#include <linux/hardirq.h> 31#include <linux/hardirq.h>
@@ -324,5 +327,30 @@ int main(void)
324 327
325 DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE); 328 DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE);
326 329
330#ifdef CONFIG_KVM
331 DEFINE(TLBE_BYTES, sizeof(struct tlbe));
332
333 DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
334 DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
335 DEFINE(VCPU_HOST_TLB, offsetof(struct kvm_vcpu, arch.host_tlb));
336 DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb));
337 DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
338 DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
339 DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
340 DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
341 DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
342 DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
343 DEFINE(VCPU_MSR, offsetof(struct kvm_vcpu, arch.msr));
344 DEFINE(VCPU_SPRG4, offsetof(struct kvm_vcpu, arch.sprg4));
345 DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5));
346 DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
347 DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7));
348 DEFINE(VCPU_PID, offsetof(struct kvm_vcpu, arch.pid));
349
350 DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
351 DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
352 DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
353#endif
354
327 return 0; 355 return 0;
328} 356}
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
new file mode 100644
index 000000000000..f5d7a5eab96e
--- /dev/null
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -0,0 +1,224 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#include <linux/types.h>
21#include <linux/string.h>
22#include <linux/kvm_host.h>
23#include <linux/highmem.h>
24#include <asm/mmu-44x.h>
25#include <asm/kvm_ppc.h>
26
27#include "44x_tlb.h"
28
29#define PPC44x_TLB_USER_PERM_MASK (PPC44x_TLB_UX|PPC44x_TLB_UR|PPC44x_TLB_UW)
30#define PPC44x_TLB_SUPER_PERM_MASK (PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW)
31
32static unsigned int kvmppc_tlb_44x_pos;
33
34static u32 kvmppc_44x_tlb_shadow_attrib(u32 attrib, int usermode)
35{
36 /* Mask off reserved bits. */
37 attrib &= PPC44x_TLB_PERM_MASK|PPC44x_TLB_ATTR_MASK;
38
39 if (!usermode) {
40 /* Guest is in supervisor mode, so we need to translate guest
41 * supervisor permissions into user permissions. */
42 attrib &= ~PPC44x_TLB_USER_PERM_MASK;
43 attrib |= (attrib & PPC44x_TLB_SUPER_PERM_MASK) << 3;
44 }
45
46 /* Make sure host can always access this memory. */
47 attrib |= PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW;
48
49 return attrib;
50}
51
52/* Search the guest TLB for a matching entry. */
53int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr, unsigned int pid,
54 unsigned int as)
55{
56 int i;
57
58 /* XXX Replace loop with fancy data structures. */
59 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
60 struct tlbe *tlbe = &vcpu->arch.guest_tlb[i];
61 unsigned int tid;
62
63 if (eaddr < get_tlb_eaddr(tlbe))
64 continue;
65
66 if (eaddr > get_tlb_end(tlbe))
67 continue;
68
69 tid = get_tlb_tid(tlbe);
70 if (tid && (tid != pid))
71 continue;
72
73 if (!get_tlb_v(tlbe))
74 continue;
75
76 if (get_tlb_ts(tlbe) != as)
77 continue;
78
79 return i;
80 }
81
82 return -1;
83}
84
85struct tlbe *kvmppc_44x_itlb_search(struct kvm_vcpu *vcpu, gva_t eaddr)
86{
87 unsigned int as = !!(vcpu->arch.msr & MSR_IS);
88 unsigned int index;
89
90 index = kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
91 if (index == -1)
92 return NULL;
93 return &vcpu->arch.guest_tlb[index];
94}
95
96struct tlbe *kvmppc_44x_dtlb_search(struct kvm_vcpu *vcpu, gva_t eaddr)
97{
98 unsigned int as = !!(vcpu->arch.msr & MSR_DS);
99 unsigned int index;
100
101 index = kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
102 if (index == -1)
103 return NULL;
104 return &vcpu->arch.guest_tlb[index];
105}
106
107static int kvmppc_44x_tlbe_is_writable(struct tlbe *tlbe)
108{
109 return tlbe->word2 & (PPC44x_TLB_SW|PPC44x_TLB_UW);
110}
111
112/* Must be called with mmap_sem locked for writing. */
113static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu,
114 unsigned int index)
115{
116 struct tlbe *stlbe = &vcpu->arch.shadow_tlb[index];
117 struct page *page = vcpu->arch.shadow_pages[index];
118
119 kunmap(vcpu->arch.shadow_pages[index]);
120
121 if (get_tlb_v(stlbe)) {
122 if (kvmppc_44x_tlbe_is_writable(stlbe))
123 kvm_release_page_dirty(page);
124 else
125 kvm_release_page_clean(page);
126 }
127}
128
129/* Caller must ensure that the specified guest TLB entry is safe to insert into
130 * the shadow TLB. */
131void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
132 u32 flags)
133{
134 struct page *new_page;
135 struct tlbe *stlbe;
136 hpa_t hpaddr;
137 unsigned int victim;
138
139 /* Future optimization: don't overwrite the TLB entry containing the
140 * current PC (or stack?). */
141 victim = kvmppc_tlb_44x_pos++;
142 if (kvmppc_tlb_44x_pos > tlb_44x_hwater)
143 kvmppc_tlb_44x_pos = 0;
144 stlbe = &vcpu->arch.shadow_tlb[victim];
145
146 /* Get reference to new page. */
147 down_write(&current->mm->mmap_sem);
148 new_page = gfn_to_page(vcpu->kvm, gfn);
149 if (is_error_page(new_page)) {
150 printk(KERN_ERR "Couldn't get guest page!\n");
151 kvm_release_page_clean(new_page);
152 return;
153 }
154 hpaddr = page_to_phys(new_page);
155
156 /* Drop reference to old page. */
157 kvmppc_44x_shadow_release(vcpu, victim);
158 up_write(&current->mm->mmap_sem);
159
160 vcpu->arch.shadow_pages[victim] = new_page;
161
162 /* XXX Make sure (va, size) doesn't overlap any other
163 * entries. 440x6 user manual says the result would be
164 * "undefined." */
165
166 /* XXX what about AS? */
167
168 stlbe->tid = asid & 0xff;
169
170 /* Force TS=1 for all guest mappings. */
171 /* For now we hardcode 4KB mappings, but it will be important to
172 * use host large pages in the future. */
173 stlbe->word0 = (gvaddr & PAGE_MASK) | PPC44x_TLB_VALID | PPC44x_TLB_TS
174 | PPC44x_TLB_4K;
175
176 stlbe->word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf);
177 stlbe->word2 = kvmppc_44x_tlb_shadow_attrib(flags,
178 vcpu->arch.msr & MSR_PR);
179}
180
181void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid)
182{
183 unsigned int pid = asid & 0xff;
184 int i;
185
186 /* XXX Replace loop with fancy data structures. */
187 down_write(&current->mm->mmap_sem);
188 for (i = 0; i <= tlb_44x_hwater; i++) {
189 struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i];
190 unsigned int tid;
191
192 if (!get_tlb_v(stlbe))
193 continue;
194
195 if (eaddr < get_tlb_eaddr(stlbe))
196 continue;
197
198 if (eaddr > get_tlb_end(stlbe))
199 continue;
200
201 tid = get_tlb_tid(stlbe);
202 if (tid && (tid != pid))
203 continue;
204
205 kvmppc_44x_shadow_release(vcpu, i);
206 stlbe->word0 = 0;
207 }
208 up_write(&current->mm->mmap_sem);
209}
210
211/* Invalidate all mappings, so that when they fault back in they will get the
212 * proper permission bits. */
213void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode)
214{
215 int i;
216
217 /* XXX Replace loop with fancy data structures. */
218 down_write(&current->mm->mmap_sem);
219 for (i = 0; i <= tlb_44x_hwater; i++) {
220 kvmppc_44x_shadow_release(vcpu, i);
221 vcpu->arch.shadow_tlb[i].word0 = 0;
222 }
223 up_write(&current->mm->mmap_sem);
224}
diff --git a/arch/powerpc/kvm/44x_tlb.h b/arch/powerpc/kvm/44x_tlb.h
new file mode 100644
index 000000000000..2ccd46b6f6b7
--- /dev/null
+++ b/arch/powerpc/kvm/44x_tlb.h
@@ -0,0 +1,91 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#ifndef __KVM_POWERPC_TLB_H__
21#define __KVM_POWERPC_TLB_H__
22
23#include <linux/kvm_host.h>
24#include <asm/mmu-44x.h>
25
26extern int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr,
27 unsigned int pid, unsigned int as);
28extern struct tlbe *kvmppc_44x_dtlb_search(struct kvm_vcpu *vcpu, gva_t eaddr);
29extern struct tlbe *kvmppc_44x_itlb_search(struct kvm_vcpu *vcpu, gva_t eaddr);
30
31/* TLB helper functions */
32static inline unsigned int get_tlb_size(const struct tlbe *tlbe)
33{
34 return (tlbe->word0 >> 4) & 0xf;
35}
36
37static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
38{
39 return tlbe->word0 & 0xfffffc00;
40}
41
42static inline gva_t get_tlb_bytes(const struct tlbe *tlbe)
43{
44 unsigned int pgsize = get_tlb_size(tlbe);
45 return 1 << 10 << (pgsize << 1);
46}
47
48static inline gva_t get_tlb_end(const struct tlbe *tlbe)
49{
50 return get_tlb_eaddr(tlbe) + get_tlb_bytes(tlbe) - 1;
51}
52
53static inline u64 get_tlb_raddr(const struct tlbe *tlbe)
54{
55 u64 word1 = tlbe->word1;
56 return ((word1 & 0xf) << 32) | (word1 & 0xfffffc00);
57}
58
59static inline unsigned int get_tlb_tid(const struct tlbe *tlbe)
60{
61 return tlbe->tid & 0xff;
62}
63
64static inline unsigned int get_tlb_ts(const struct tlbe *tlbe)
65{
66 return (tlbe->word0 >> 8) & 0x1;
67}
68
69static inline unsigned int get_tlb_v(const struct tlbe *tlbe)
70{
71 return (tlbe->word0 >> 9) & 0x1;
72}
73
74static inline unsigned int get_mmucr_stid(const struct kvm_vcpu *vcpu)
75{
76 return vcpu->arch.mmucr & 0xff;
77}
78
79static inline unsigned int get_mmucr_sts(const struct kvm_vcpu *vcpu)
80{
81 return (vcpu->arch.mmucr >> 16) & 0x1;
82}
83
84static inline gpa_t tlb_xlate(struct tlbe *tlbe, gva_t eaddr)
85{
86 unsigned int pgmask = get_tlb_bytes(tlbe) - 1;
87
88 return get_tlb_raddr(tlbe) | (eaddr & pgmask);
89}
90
91#endif /* __KVM_POWERPC_TLB_H__ */
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
new file mode 100644
index 000000000000..6b076010213b
--- /dev/null
+++ b/arch/powerpc/kvm/Kconfig
@@ -0,0 +1,42 @@
1#
2# KVM configuration
3#
4
5menuconfig VIRTUALIZATION
6 bool "Virtualization"
7 ---help---
8 Say Y here to get to see options for using your Linux host to run
9 other operating systems inside virtual machines (guests).
10 This option alone does not add any kernel code.
11
12 If you say N, all options in this submenu will be skipped and
13 disabled.
14
15if VIRTUALIZATION
16
17config KVM
18 bool "Kernel-based Virtual Machine (KVM) support"
19 depends on 44x && EXPERIMENTAL
20 select PREEMPT_NOTIFIERS
21 select ANON_INODES
22 # We can only run on Book E hosts so far
23 select KVM_BOOKE_HOST
24 ---help---
25 Support hosting virtualized guest machines. You will also
26 need to select one or more of the processor modules below.
27
28 This module provides access to the hardware capabilities through
29 a character device node named /dev/kvm.
30
31 If unsure, say N.
32
33config KVM_BOOKE_HOST
34 bool "KVM host support for Book E PowerPC processors"
35 depends on KVM && 44x
36 ---help---
37 Provides host support for KVM on Book E PowerPC processors. Currently
38 this works on 440 processors only.
39
40source drivers/virtio/Kconfig
41
42endif # VIRTUALIZATION
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
new file mode 100644
index 000000000000..d0d358d367ec
--- /dev/null
+++ b/arch/powerpc/kvm/Makefile
@@ -0,0 +1,15 @@
1#
2# Makefile for Kernel-based Virtual Machine module
3#
4
5EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm
6
7common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o)
8
9kvm-objs := $(common-objs) powerpc.o emulate.o booke_guest.o
10obj-$(CONFIG_KVM) += kvm.o
11
12AFLAGS_booke_interrupts.o := -I$(obj)
13
14kvm-booke-host-objs := booke_host.o booke_interrupts.o 44x_tlb.o
15obj-$(CONFIG_KVM_BOOKE_HOST) += kvm-booke-host.o
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke_guest.c
new file mode 100644
index 000000000000..6d9884a6884a
--- /dev/null
+++ b/arch/powerpc/kvm/booke_guest.c
@@ -0,0 +1,615 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
19 */
20
21#include <linux/errno.h>
22#include <linux/err.h>
23#include <linux/kvm_host.h>
24#include <linux/module.h>
25#include <linux/vmalloc.h>
26#include <linux/fs.h>
27#include <asm/cputable.h>
28#include <asm/uaccess.h>
29#include <asm/kvm_ppc.h>
30
31#include "44x_tlb.h"
32
33#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
34#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
35
36struct kvm_stats_debugfs_item debugfs_entries[] = {
37 { "exits", VCPU_STAT(sum_exits) },
38 { "mmio", VCPU_STAT(mmio_exits) },
39 { "dcr", VCPU_STAT(dcr_exits) },
40 { "sig", VCPU_STAT(signal_exits) },
41 { "light", VCPU_STAT(light_exits) },
42 { "itlb_r", VCPU_STAT(itlb_real_miss_exits) },
43 { "itlb_v", VCPU_STAT(itlb_virt_miss_exits) },
44 { "dtlb_r", VCPU_STAT(dtlb_real_miss_exits) },
45 { "dtlb_v", VCPU_STAT(dtlb_virt_miss_exits) },
46 { "sysc", VCPU_STAT(syscall_exits) },
47 { "isi", VCPU_STAT(isi_exits) },
48 { "dsi", VCPU_STAT(dsi_exits) },
49 { "inst_emu", VCPU_STAT(emulated_inst_exits) },
50 { "dec", VCPU_STAT(dec_exits) },
51 { "ext_intr", VCPU_STAT(ext_intr_exits) },
52 { NULL }
53};
54
55static const u32 interrupt_msr_mask[16] = {
56 [BOOKE_INTERRUPT_CRITICAL] = MSR_ME,
57 [BOOKE_INTERRUPT_MACHINE_CHECK] = 0,
58 [BOOKE_INTERRUPT_DATA_STORAGE] = MSR_CE|MSR_ME|MSR_DE,
59 [BOOKE_INTERRUPT_INST_STORAGE] = MSR_CE|MSR_ME|MSR_DE,
60 [BOOKE_INTERRUPT_EXTERNAL] = MSR_CE|MSR_ME|MSR_DE,
61 [BOOKE_INTERRUPT_ALIGNMENT] = MSR_CE|MSR_ME|MSR_DE,
62 [BOOKE_INTERRUPT_PROGRAM] = MSR_CE|MSR_ME|MSR_DE,
63 [BOOKE_INTERRUPT_FP_UNAVAIL] = MSR_CE|MSR_ME|MSR_DE,
64 [BOOKE_INTERRUPT_SYSCALL] = MSR_CE|MSR_ME|MSR_DE,
65 [BOOKE_INTERRUPT_AP_UNAVAIL] = MSR_CE|MSR_ME|MSR_DE,
66 [BOOKE_INTERRUPT_DECREMENTER] = MSR_CE|MSR_ME|MSR_DE,
67 [BOOKE_INTERRUPT_FIT] = MSR_CE|MSR_ME|MSR_DE,
68 [BOOKE_INTERRUPT_WATCHDOG] = MSR_ME,
69 [BOOKE_INTERRUPT_DTLB_MISS] = MSR_CE|MSR_ME|MSR_DE,
70 [BOOKE_INTERRUPT_ITLB_MISS] = MSR_CE|MSR_ME|MSR_DE,
71 [BOOKE_INTERRUPT_DEBUG] = MSR_ME,
72};
73
74const unsigned char exception_priority[] = {
75 [BOOKE_INTERRUPT_DATA_STORAGE] = 0,
76 [BOOKE_INTERRUPT_INST_STORAGE] = 1,
77 [BOOKE_INTERRUPT_ALIGNMENT] = 2,
78 [BOOKE_INTERRUPT_PROGRAM] = 3,
79 [BOOKE_INTERRUPT_FP_UNAVAIL] = 4,
80 [BOOKE_INTERRUPT_SYSCALL] = 5,
81 [BOOKE_INTERRUPT_AP_UNAVAIL] = 6,
82 [BOOKE_INTERRUPT_DTLB_MISS] = 7,
83 [BOOKE_INTERRUPT_ITLB_MISS] = 8,
84 [BOOKE_INTERRUPT_MACHINE_CHECK] = 9,
85 [BOOKE_INTERRUPT_DEBUG] = 10,
86 [BOOKE_INTERRUPT_CRITICAL] = 11,
87 [BOOKE_INTERRUPT_WATCHDOG] = 12,
88 [BOOKE_INTERRUPT_EXTERNAL] = 13,
89 [BOOKE_INTERRUPT_FIT] = 14,
90 [BOOKE_INTERRUPT_DECREMENTER] = 15,
91};
92
93const unsigned char priority_exception[] = {
94 BOOKE_INTERRUPT_DATA_STORAGE,
95 BOOKE_INTERRUPT_INST_STORAGE,
96 BOOKE_INTERRUPT_ALIGNMENT,
97 BOOKE_INTERRUPT_PROGRAM,
98 BOOKE_INTERRUPT_FP_UNAVAIL,
99 BOOKE_INTERRUPT_SYSCALL,
100 BOOKE_INTERRUPT_AP_UNAVAIL,
101 BOOKE_INTERRUPT_DTLB_MISS,
102 BOOKE_INTERRUPT_ITLB_MISS,
103 BOOKE_INTERRUPT_MACHINE_CHECK,
104 BOOKE_INTERRUPT_DEBUG,
105 BOOKE_INTERRUPT_CRITICAL,
106 BOOKE_INTERRUPT_WATCHDOG,
107 BOOKE_INTERRUPT_EXTERNAL,
108 BOOKE_INTERRUPT_FIT,
109 BOOKE_INTERRUPT_DECREMENTER,
110};
111
112
113void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
114{
115 struct tlbe *tlbe;
116 int i;
117
118 printk("vcpu %d TLB dump:\n", vcpu->vcpu_id);
119 printk("| %2s | %3s | %8s | %8s | %8s |\n",
120 "nr", "tid", "word0", "word1", "word2");
121
122 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
123 tlbe = &vcpu->arch.guest_tlb[i];
124 if (tlbe->word0 & PPC44x_TLB_VALID)
125 printk(" G%2d | %02X | %08X | %08X | %08X |\n",
126 i, tlbe->tid, tlbe->word0, tlbe->word1,
127 tlbe->word2);
128 }
129
130 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
131 tlbe = &vcpu->arch.shadow_tlb[i];
132 if (tlbe->word0 & PPC44x_TLB_VALID)
133 printk(" S%2d | %02X | %08X | %08X | %08X |\n",
134 i, tlbe->tid, tlbe->word0, tlbe->word1,
135 tlbe->word2);
136 }
137}
138
139/* TODO: use vcpu_printf() */
140void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
141{
142 int i;
143
144 printk("pc: %08x msr: %08x\n", vcpu->arch.pc, vcpu->arch.msr);
145 printk("lr: %08x ctr: %08x\n", vcpu->arch.lr, vcpu->arch.ctr);
146 printk("srr0: %08x srr1: %08x\n", vcpu->arch.srr0, vcpu->arch.srr1);
147
148 printk("exceptions: %08lx\n", vcpu->arch.pending_exceptions);
149
150 for (i = 0; i < 32; i += 4) {
151 printk("gpr%02d: %08x %08x %08x %08x\n", i,
152 vcpu->arch.gpr[i],
153 vcpu->arch.gpr[i+1],
154 vcpu->arch.gpr[i+2],
155 vcpu->arch.gpr[i+3]);
156 }
157}
158
159/* Check if we are ready to deliver the interrupt */
160static int kvmppc_can_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
161{
162 int r;
163
164 switch (interrupt) {
165 case BOOKE_INTERRUPT_CRITICAL:
166 r = vcpu->arch.msr & MSR_CE;
167 break;
168 case BOOKE_INTERRUPT_MACHINE_CHECK:
169 r = vcpu->arch.msr & MSR_ME;
170 break;
171 case BOOKE_INTERRUPT_EXTERNAL:
172 r = vcpu->arch.msr & MSR_EE;
173 break;
174 case BOOKE_INTERRUPT_DECREMENTER:
175 r = vcpu->arch.msr & MSR_EE;
176 break;
177 case BOOKE_INTERRUPT_FIT:
178 r = vcpu->arch.msr & MSR_EE;
179 break;
180 case BOOKE_INTERRUPT_WATCHDOG:
181 r = vcpu->arch.msr & MSR_CE;
182 break;
183 case BOOKE_INTERRUPT_DEBUG:
184 r = vcpu->arch.msr & MSR_DE;
185 break;
186 default:
187 r = 1;
188 }
189
190 return r;
191}
192
193static void kvmppc_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
194{
195 switch (interrupt) {
196 case BOOKE_INTERRUPT_DECREMENTER:
197 vcpu->arch.tsr |= TSR_DIS;
198 break;
199 }
200
201 vcpu->arch.srr0 = vcpu->arch.pc;
202 vcpu->arch.srr1 = vcpu->arch.msr;
203 vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[interrupt];
204 kvmppc_set_msr(vcpu, vcpu->arch.msr & interrupt_msr_mask[interrupt]);
205}
206
207/* Check pending exceptions and deliver one, if possible. */
208void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu)
209{
210 unsigned long *pending = &vcpu->arch.pending_exceptions;
211 unsigned int exception;
212 unsigned int priority;
213
214 priority = find_first_bit(pending, BITS_PER_BYTE * sizeof(*pending));
215 while (priority <= BOOKE_MAX_INTERRUPT) {
216 exception = priority_exception[priority];
217 if (kvmppc_can_deliver_interrupt(vcpu, exception)) {
218 kvmppc_clear_exception(vcpu, exception);
219 kvmppc_deliver_interrupt(vcpu, exception);
220 break;
221 }
222
223 priority = find_next_bit(pending,
224 BITS_PER_BYTE * sizeof(*pending),
225 priority + 1);
226 }
227}
228
229static int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
230{
231 enum emulation_result er;
232 int r;
233
234 er = kvmppc_emulate_instruction(run, vcpu);
235 switch (er) {
236 case EMULATE_DONE:
237 /* Future optimization: only reload non-volatiles if they were
238 * actually modified. */
239 r = RESUME_GUEST_NV;
240 break;
241 case EMULATE_DO_MMIO:
242 run->exit_reason = KVM_EXIT_MMIO;
243 /* We must reload nonvolatiles because "update" load/store
244 * instructions modify register state. */
245 /* Future optimization: only reload non-volatiles if they were
246 * actually modified. */
247 r = RESUME_HOST_NV;
248 break;
249 case EMULATE_FAIL:
250 /* XXX Deliver Program interrupt to guest. */
251 printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__,
252 vcpu->arch.last_inst);
253 r = RESUME_HOST;
254 break;
255 default:
256 BUG();
257 }
258
259 return r;
260}
261
262/**
263 * kvmppc_handle_exit
264 *
265 * Return value is in the form (errcode<<2 | RESUME_FLAG_HOST | RESUME_FLAG_NV)
266 */
267int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
268 unsigned int exit_nr)
269{
270 enum emulation_result er;
271 int r = RESUME_HOST;
272
273 local_irq_enable();
274
275 run->exit_reason = KVM_EXIT_UNKNOWN;
276 run->ready_for_interrupt_injection = 1;
277
278 switch (exit_nr) {
279 case BOOKE_INTERRUPT_MACHINE_CHECK:
280 printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR));
281 kvmppc_dump_vcpu(vcpu);
282 r = RESUME_HOST;
283 break;
284
285 case BOOKE_INTERRUPT_EXTERNAL:
286 case BOOKE_INTERRUPT_DECREMENTER:
287 /* Since we switched IVPR back to the host's value, the host
288 * handled this interrupt the moment we enabled interrupts.
289 * Now we just offer it a chance to reschedule the guest. */
290
291 /* XXX At this point the TLB still holds our shadow TLB, so if
292 * we do reschedule the host will fault over it. Perhaps we
293 * should politely restore the host's entries to minimize
294 * misses before ceding control. */
295 if (need_resched())
296 cond_resched();
297 if (exit_nr == BOOKE_INTERRUPT_DECREMENTER)
298 vcpu->stat.dec_exits++;
299 else
300 vcpu->stat.ext_intr_exits++;
301 r = RESUME_GUEST;
302 break;
303
304 case BOOKE_INTERRUPT_PROGRAM:
305 if (vcpu->arch.msr & MSR_PR) {
306 /* Program traps generated by user-level software must be handled
307 * by the guest kernel. */
308 vcpu->arch.esr = vcpu->arch.fault_esr;
309 kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM);
310 r = RESUME_GUEST;
311 break;
312 }
313
314 er = kvmppc_emulate_instruction(run, vcpu);
315 switch (er) {
316 case EMULATE_DONE:
317 /* Future optimization: only reload non-volatiles if
318 * they were actually modified by emulation. */
319 vcpu->stat.emulated_inst_exits++;
320 r = RESUME_GUEST_NV;
321 break;
322 case EMULATE_DO_DCR:
323 run->exit_reason = KVM_EXIT_DCR;
324 r = RESUME_HOST;
325 break;
326 case EMULATE_FAIL:
327 /* XXX Deliver Program interrupt to guest. */
328 printk(KERN_CRIT "%s: emulation at %x failed (%08x)\n",
329 __func__, vcpu->arch.pc, vcpu->arch.last_inst);
330 /* For debugging, encode the failing instruction and
331 * report it to userspace. */
332 run->hw.hardware_exit_reason = ~0ULL << 32;
333 run->hw.hardware_exit_reason |= vcpu->arch.last_inst;
334 r = RESUME_HOST;
335 break;
336 default:
337 BUG();
338 }
339 break;
340
341 case BOOKE_INTERRUPT_DATA_STORAGE:
342 vcpu->arch.dear = vcpu->arch.fault_dear;
343 vcpu->arch.esr = vcpu->arch.fault_esr;
344 kvmppc_queue_exception(vcpu, exit_nr);
345 vcpu->stat.dsi_exits++;
346 r = RESUME_GUEST;
347 break;
348
349 case BOOKE_INTERRUPT_INST_STORAGE:
350 vcpu->arch.esr = vcpu->arch.fault_esr;
351 kvmppc_queue_exception(vcpu, exit_nr);
352 vcpu->stat.isi_exits++;
353 r = RESUME_GUEST;
354 break;
355
356 case BOOKE_INTERRUPT_SYSCALL:
357 kvmppc_queue_exception(vcpu, exit_nr);
358 vcpu->stat.syscall_exits++;
359 r = RESUME_GUEST;
360 break;
361
362 case BOOKE_INTERRUPT_DTLB_MISS: {
363 struct tlbe *gtlbe;
364 unsigned long eaddr = vcpu->arch.fault_dear;
365 gfn_t gfn;
366
367 /* Check the guest TLB. */
368 gtlbe = kvmppc_44x_dtlb_search(vcpu, eaddr);
369 if (!gtlbe) {
370 /* The guest didn't have a mapping for it. */
371 kvmppc_queue_exception(vcpu, exit_nr);
372 vcpu->arch.dear = vcpu->arch.fault_dear;
373 vcpu->arch.esr = vcpu->arch.fault_esr;
374 vcpu->stat.dtlb_real_miss_exits++;
375 r = RESUME_GUEST;
376 break;
377 }
378
379 vcpu->arch.paddr_accessed = tlb_xlate(gtlbe, eaddr);
380 gfn = vcpu->arch.paddr_accessed >> PAGE_SHIFT;
381
382 if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
383 /* The guest TLB had a mapping, but the shadow TLB
384 * didn't, and it is RAM. This could be because:
385 * a) the entry is mapping the host kernel, or
386 * b) the guest used a large mapping which we're faking
387 * Either way, we need to satisfy the fault without
388 * invoking the guest. */
389 kvmppc_mmu_map(vcpu, eaddr, gfn, gtlbe->tid,
390 gtlbe->word2);
391 vcpu->stat.dtlb_virt_miss_exits++;
392 r = RESUME_GUEST;
393 } else {
394 /* Guest has mapped and accessed a page which is not
395 * actually RAM. */
396 r = kvmppc_emulate_mmio(run, vcpu);
397 }
398
399 break;
400 }
401
402 case BOOKE_INTERRUPT_ITLB_MISS: {
403 struct tlbe *gtlbe;
404 unsigned long eaddr = vcpu->arch.pc;
405 gfn_t gfn;
406
407 r = RESUME_GUEST;
408
409 /* Check the guest TLB. */
410 gtlbe = kvmppc_44x_itlb_search(vcpu, eaddr);
411 if (!gtlbe) {
412 /* The guest didn't have a mapping for it. */
413 kvmppc_queue_exception(vcpu, exit_nr);
414 vcpu->stat.itlb_real_miss_exits++;
415 break;
416 }
417
418 vcpu->stat.itlb_virt_miss_exits++;
419
420 gfn = tlb_xlate(gtlbe, eaddr) >> PAGE_SHIFT;
421
422 if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
423 /* The guest TLB had a mapping, but the shadow TLB
424 * didn't. This could be because:
425 * a) the entry is mapping the host kernel, or
426 * b) the guest used a large mapping which we're faking
427 * Either way, we need to satisfy the fault without
428 * invoking the guest. */
429 kvmppc_mmu_map(vcpu, eaddr, gfn, gtlbe->tid,
430 gtlbe->word2);
431 } else {
432 /* Guest mapped and leaped at non-RAM! */
433 kvmppc_queue_exception(vcpu,
434 BOOKE_INTERRUPT_MACHINE_CHECK);
435 }
436
437 break;
438 }
439
440 default:
441 printk(KERN_EMERG "exit_nr %d\n", exit_nr);
442 BUG();
443 }
444
445 local_irq_disable();
446
447 kvmppc_check_and_deliver_interrupts(vcpu);
448
449 /* Do some exit accounting. */
450 vcpu->stat.sum_exits++;
451 if (!(r & RESUME_HOST)) {
452 /* To avoid clobbering exit_reason, only check for signals if
453 * we aren't already exiting to userspace for some other
454 * reason. */
455 if (signal_pending(current)) {
456 run->exit_reason = KVM_EXIT_INTR;
457 r = (-EINTR << 2) | RESUME_HOST | (r & RESUME_FLAG_NV);
458
459 vcpu->stat.signal_exits++;
460 } else {
461 vcpu->stat.light_exits++;
462 }
463 } else {
464 switch (run->exit_reason) {
465 case KVM_EXIT_MMIO:
466 vcpu->stat.mmio_exits++;
467 break;
468 case KVM_EXIT_DCR:
469 vcpu->stat.dcr_exits++;
470 break;
471 case KVM_EXIT_INTR:
472 vcpu->stat.signal_exits++;
473 break;
474 }
475 }
476
477 return r;
478}
479
480/* Initial guest state: 16MB mapping 0 -> 0, PC = 0, MSR = 0, R1 = 16MB */
481int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
482{
483 struct tlbe *tlbe = &vcpu->arch.guest_tlb[0];
484
485 tlbe->tid = 0;
486 tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID;
487 tlbe->word1 = 0;
488 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR;
489
490 tlbe++;
491 tlbe->tid = 0;
492 tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID;
493 tlbe->word1 = 0xef600000;
494 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR
495 | PPC44x_TLB_I | PPC44x_TLB_G;
496
497 vcpu->arch.pc = 0;
498 vcpu->arch.msr = 0;
499 vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */
500
501 /* Eye-catching number so we know if the guest takes an interrupt
502 * before it's programmed its own IVPR. */
503 vcpu->arch.ivpr = 0x55550000;
504
505 /* Since the guest can directly access the timebase, it must know the
506 * real timebase frequency. Accordingly, it must see the state of
507 * CCR1[TCS]. */
508 vcpu->arch.ccr1 = mfspr(SPRN_CCR1);
509
510 return 0;
511}
512
513int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
514{
515 int i;
516
517 regs->pc = vcpu->arch.pc;
518 regs->cr = vcpu->arch.cr;
519 regs->ctr = vcpu->arch.ctr;
520 regs->lr = vcpu->arch.lr;
521 regs->xer = vcpu->arch.xer;
522 regs->msr = vcpu->arch.msr;
523 regs->srr0 = vcpu->arch.srr0;
524 regs->srr1 = vcpu->arch.srr1;
525 regs->pid = vcpu->arch.pid;
526 regs->sprg0 = vcpu->arch.sprg0;
527 regs->sprg1 = vcpu->arch.sprg1;
528 regs->sprg2 = vcpu->arch.sprg2;
529 regs->sprg3 = vcpu->arch.sprg3;
530 regs->sprg5 = vcpu->arch.sprg4;
531 regs->sprg6 = vcpu->arch.sprg5;
532 regs->sprg7 = vcpu->arch.sprg6;
533
534 for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
535 regs->gpr[i] = vcpu->arch.gpr[i];
536
537 return 0;
538}
539
540int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
541{
542 int i;
543
544 vcpu->arch.pc = regs->pc;
545 vcpu->arch.cr = regs->cr;
546 vcpu->arch.ctr = regs->ctr;
547 vcpu->arch.lr = regs->lr;
548 vcpu->arch.xer = regs->xer;
549 vcpu->arch.msr = regs->msr;
550 vcpu->arch.srr0 = regs->srr0;
551 vcpu->arch.srr1 = regs->srr1;
552 vcpu->arch.sprg0 = regs->sprg0;
553 vcpu->arch.sprg1 = regs->sprg1;
554 vcpu->arch.sprg2 = regs->sprg2;
555 vcpu->arch.sprg3 = regs->sprg3;
556 vcpu->arch.sprg5 = regs->sprg4;
557 vcpu->arch.sprg6 = regs->sprg5;
558 vcpu->arch.sprg7 = regs->sprg6;
559
560 for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
561 vcpu->arch.gpr[i] = regs->gpr[i];
562
563 return 0;
564}
565
566int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
567 struct kvm_sregs *sregs)
568{
569 return -ENOTSUPP;
570}
571
572int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
573 struct kvm_sregs *sregs)
574{
575 return -ENOTSUPP;
576}
577
578int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
579{
580 return -ENOTSUPP;
581}
582
583int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
584{
585 return -ENOTSUPP;
586}
587
588/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
589int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
590 struct kvm_translation *tr)
591{
592 struct tlbe *gtlbe;
593 int index;
594 gva_t eaddr;
595 u8 pid;
596 u8 as;
597
598 eaddr = tr->linear_address;
599 pid = (tr->linear_address >> 32) & 0xff;
600 as = (tr->linear_address >> 40) & 0x1;
601
602 index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as);
603 if (index == -1) {
604 tr->valid = 0;
605 return 0;
606 }
607
608 gtlbe = &vcpu->arch.guest_tlb[index];
609
610 tr->physical_address = tlb_xlate(gtlbe, eaddr);
611 /* XXX what does "writeable" and "usermode" even mean? */
612 tr->valid = 1;
613
614 return 0;
615}
diff --git a/arch/powerpc/kvm/booke_host.c b/arch/powerpc/kvm/booke_host.c
new file mode 100644
index 000000000000..b480341bc31e
--- /dev/null
+++ b/arch/powerpc/kvm/booke_host.c
@@ -0,0 +1,83 @@
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 IBM Corp. 2008
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#include <linux/errno.h>
21#include <linux/kvm_host.h>
22#include <linux/module.h>
23#include <asm/cacheflush.h>
24#include <asm/kvm_ppc.h>
25
26unsigned long kvmppc_booke_handlers;
27
28static int kvmppc_booke_init(void)
29{
30 unsigned long ivor[16];
31 unsigned long max_ivor = 0;
32 int i;
33
34 /* We install our own exception handlers by hijacking IVPR. IVPR must
35 * be 16-bit aligned, so we need a 64KB allocation. */
36 kvmppc_booke_handlers = __get_free_pages(GFP_KERNEL | __GFP_ZERO,
37 VCPU_SIZE_ORDER);
38 if (!kvmppc_booke_handlers)
39 return -ENOMEM;
40
41 /* XXX make sure our handlers are smaller than Linux's */
42
43 /* Copy our interrupt handlers to match host IVORs. That way we don't
44 * have to swap the IVORs on every guest/host transition. */
45 ivor[0] = mfspr(SPRN_IVOR0);
46 ivor[1] = mfspr(SPRN_IVOR1);
47 ivor[2] = mfspr(SPRN_IVOR2);
48 ivor[3] = mfspr(SPRN_IVOR3);
49 ivor[4] = mfspr(SPRN_IVOR4);
50 ivor[5] = mfspr(SPRN_IVOR5);
51 ivor[6] = mfspr(SPRN_IVOR6);
52 ivor[7] = mfspr(SPRN_IVOR7);
53 ivor[8] = mfspr(SPRN_IVOR8);
54 ivor[9] = mfspr(SPRN_IVOR9);
55 ivor[10] = mfspr(SPRN_IVOR10);
56 ivor[11] = mfspr(SPRN_IVOR11);
57 ivor[12] = mfspr(SPRN_IVOR12);
58 ivor[13] = mfspr(SPRN_IVOR13);
59 ivor[14] = mfspr(SPRN_IVOR14);
60 ivor[15] = mfspr(SPRN_IVOR15);
61
62 for (i = 0; i < 16; i++) {
63 if (ivor[i] > max_ivor)
64 max_ivor = ivor[i];
65
66 memcpy((void *)kvmppc_booke_handlers + ivor[i],
67 kvmppc_handlers_start + i * kvmppc_handler_len,
68 kvmppc_handler_len);
69 }
70 flush_icache_range(kvmppc_booke_handlers,
71 kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
72
73 return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE);
74}
75
76static void __exit kvmppc_booke_exit(void)
77{
78 free_pages(kvmppc_booke_handlers, VCPU_SIZE_ORDER);
79 kvm_exit();
80}
81
82module_init(kvmppc_booke_init)
83module_exit(kvmppc_booke_exit)
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
new file mode 100644
index 000000000000..3b653b5309b8
--- /dev/null
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -0,0 +1,436 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#include <asm/ppc_asm.h>
21#include <asm/kvm_asm.h>
22#include <asm/reg.h>
23#include <asm/mmu-44x.h>
24#include <asm/page.h>
25#include <asm/asm-offsets.h>
26
27#define KVMPPC_MSR_MASK (MSR_CE|MSR_EE|MSR_PR|MSR_DE|MSR_ME|MSR_IS|MSR_DS)
28
29#define VCPU_GPR(n) (VCPU_GPRS + (n * 4))
30
31/* The host stack layout: */
32#define HOST_R1 0 /* Implied by stwu. */
33#define HOST_CALLEE_LR 4
34#define HOST_RUN 8
35/* r2 is special: it holds 'current', and it made nonvolatile in the
36 * kernel with the -ffixed-r2 gcc option. */
37#define HOST_R2 12
38#define HOST_NV_GPRS 16
39#define HOST_NV_GPR(n) (HOST_NV_GPRS + ((n - 14) * 4))
40#define HOST_MIN_STACK_SIZE (HOST_NV_GPR(31) + 4)
41#define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */
42#define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */
43
44#define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \
45 (1<<BOOKE_INTERRUPT_DTLB_MISS))
46
47#define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
48 (1<<BOOKE_INTERRUPT_DTLB_MISS))
49
50#define NEED_ESR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
51 (1<<BOOKE_INTERRUPT_INST_STORAGE) | \
52 (1<<BOOKE_INTERRUPT_PROGRAM) | \
53 (1<<BOOKE_INTERRUPT_DTLB_MISS))
54
55.macro KVM_HANDLER ivor_nr
56_GLOBAL(kvmppc_handler_\ivor_nr)
57 /* Get pointer to vcpu and record exit number. */
58 mtspr SPRN_SPRG0, r4
59 mfspr r4, SPRN_SPRG1
60 stw r5, VCPU_GPR(r5)(r4)
61 stw r6, VCPU_GPR(r6)(r4)
62 mfctr r5
63 lis r6, kvmppc_resume_host@h
64 stw r5, VCPU_CTR(r4)
65 li r5, \ivor_nr
66 ori r6, r6, kvmppc_resume_host@l
67 mtctr r6
68 bctr
69.endm
70
71_GLOBAL(kvmppc_handlers_start)
72KVM_HANDLER BOOKE_INTERRUPT_CRITICAL
73KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK
74KVM_HANDLER BOOKE_INTERRUPT_DATA_STORAGE
75KVM_HANDLER BOOKE_INTERRUPT_INST_STORAGE
76KVM_HANDLER BOOKE_INTERRUPT_EXTERNAL
77KVM_HANDLER BOOKE_INTERRUPT_ALIGNMENT
78KVM_HANDLER BOOKE_INTERRUPT_PROGRAM
79KVM_HANDLER BOOKE_INTERRUPT_FP_UNAVAIL
80KVM_HANDLER BOOKE_INTERRUPT_SYSCALL
81KVM_HANDLER BOOKE_INTERRUPT_AP_UNAVAIL
82KVM_HANDLER BOOKE_INTERRUPT_DECREMENTER
83KVM_HANDLER BOOKE_INTERRUPT_FIT
84KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG
85KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS
86KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS
87KVM_HANDLER BOOKE_INTERRUPT_DEBUG
88
89_GLOBAL(kvmppc_handler_len)
90 .long kvmppc_handler_1 - kvmppc_handler_0
91
92
93/* Registers:
94 * SPRG0: guest r4
95 * r4: vcpu pointer
96 * r5: KVM exit number
97 */
98_GLOBAL(kvmppc_resume_host)
99 stw r3, VCPU_GPR(r3)(r4)
100 mfcr r3
101 stw r3, VCPU_CR(r4)
102 stw r7, VCPU_GPR(r7)(r4)
103 stw r8, VCPU_GPR(r8)(r4)
104 stw r9, VCPU_GPR(r9)(r4)
105
106 li r6, 1
107 slw r6, r6, r5
108
109 /* Save the faulting instruction and all GPRs for emulation. */
110 andi. r7, r6, NEED_INST_MASK
111 beq ..skip_inst_copy
112 mfspr r9, SPRN_SRR0
113 mfmsr r8
114 ori r7, r8, MSR_DS
115 mtmsr r7
116 isync
117 lwz r9, 0(r9)
118 mtmsr r8
119 isync
120 stw r9, VCPU_LAST_INST(r4)
121
122 stw r15, VCPU_GPR(r15)(r4)
123 stw r16, VCPU_GPR(r16)(r4)
124 stw r17, VCPU_GPR(r17)(r4)
125 stw r18, VCPU_GPR(r18)(r4)
126 stw r19, VCPU_GPR(r19)(r4)
127 stw r20, VCPU_GPR(r20)(r4)
128 stw r21, VCPU_GPR(r21)(r4)
129 stw r22, VCPU_GPR(r22)(r4)
130 stw r23, VCPU_GPR(r23)(r4)
131 stw r24, VCPU_GPR(r24)(r4)
132 stw r25, VCPU_GPR(r25)(r4)
133 stw r26, VCPU_GPR(r26)(r4)
134 stw r27, VCPU_GPR(r27)(r4)
135 stw r28, VCPU_GPR(r28)(r4)
136 stw r29, VCPU_GPR(r29)(r4)
137 stw r30, VCPU_GPR(r30)(r4)
138 stw r31, VCPU_GPR(r31)(r4)
139..skip_inst_copy:
140
141 /* Also grab DEAR and ESR before the host can clobber them. */
142
143 andi. r7, r6, NEED_DEAR_MASK
144 beq ..skip_dear
145 mfspr r9, SPRN_DEAR
146 stw r9, VCPU_FAULT_DEAR(r4)
147..skip_dear:
148
149 andi. r7, r6, NEED_ESR_MASK
150 beq ..skip_esr
151 mfspr r9, SPRN_ESR
152 stw r9, VCPU_FAULT_ESR(r4)
153..skip_esr:
154
155 /* Save remaining volatile guest register state to vcpu. */
156 stw r0, VCPU_GPR(r0)(r4)
157 stw r1, VCPU_GPR(r1)(r4)
158 stw r2, VCPU_GPR(r2)(r4)
159 stw r10, VCPU_GPR(r10)(r4)
160 stw r11, VCPU_GPR(r11)(r4)
161 stw r12, VCPU_GPR(r12)(r4)
162 stw r13, VCPU_GPR(r13)(r4)
163 stw r14, VCPU_GPR(r14)(r4) /* We need a NV GPR below. */
164 mflr r3
165 stw r3, VCPU_LR(r4)
166 mfxer r3
167 stw r3, VCPU_XER(r4)
168 mfspr r3, SPRN_SPRG0
169 stw r3, VCPU_GPR(r4)(r4)
170 mfspr r3, SPRN_SRR0
171 stw r3, VCPU_PC(r4)
172
173 /* Restore host stack pointer and PID before IVPR, since the host
174 * exception handlers use them. */
175 lwz r1, VCPU_HOST_STACK(r4)
176 lwz r3, VCPU_HOST_PID(r4)
177 mtspr SPRN_PID, r3
178
179 /* Restore host IVPR before re-enabling interrupts. We cheat and know
180 * that Linux IVPR is always 0xc0000000. */
181 lis r3, 0xc000
182 mtspr SPRN_IVPR, r3
183
184 /* Switch to kernel stack and jump to handler. */
185 LOAD_REG_ADDR(r3, kvmppc_handle_exit)
186 mtctr r3
187 lwz r3, HOST_RUN(r1)
188 lwz r2, HOST_R2(r1)
189 mr r14, r4 /* Save vcpu pointer. */
190
191 bctrl /* kvmppc_handle_exit() */
192
193 /* Restore vcpu pointer and the nonvolatiles we used. */
194 mr r4, r14
195 lwz r14, VCPU_GPR(r14)(r4)
196
197 /* Sometimes instruction emulation must restore complete GPR state. */
198 andi. r5, r3, RESUME_FLAG_NV
199 beq ..skip_nv_load
200 lwz r15, VCPU_GPR(r15)(r4)
201 lwz r16, VCPU_GPR(r16)(r4)
202 lwz r17, VCPU_GPR(r17)(r4)
203 lwz r18, VCPU_GPR(r18)(r4)
204 lwz r19, VCPU_GPR(r19)(r4)
205 lwz r20, VCPU_GPR(r20)(r4)
206 lwz r21, VCPU_GPR(r21)(r4)
207 lwz r22, VCPU_GPR(r22)(r4)
208 lwz r23, VCPU_GPR(r23)(r4)
209 lwz r24, VCPU_GPR(r24)(r4)
210 lwz r25, VCPU_GPR(r25)(r4)
211 lwz r26, VCPU_GPR(r26)(r4)
212 lwz r27, VCPU_GPR(r27)(r4)
213 lwz r28, VCPU_GPR(r28)(r4)
214 lwz r29, VCPU_GPR(r29)(r4)
215 lwz r30, VCPU_GPR(r30)(r4)
216 lwz r31, VCPU_GPR(r31)(r4)
217..skip_nv_load:
218
219 /* Should we return to the guest? */
220 andi. r5, r3, RESUME_FLAG_HOST
221 beq lightweight_exit
222
223 srawi r3, r3, 2 /* Shift -ERR back down. */
224
225heavyweight_exit:
226 /* Not returning to guest. */
227
228 /* We already saved guest volatile register state; now save the
229 * non-volatiles. */
230 stw r15, VCPU_GPR(r15)(r4)
231 stw r16, VCPU_GPR(r16)(r4)
232 stw r17, VCPU_GPR(r17)(r4)
233 stw r18, VCPU_GPR(r18)(r4)
234 stw r19, VCPU_GPR(r19)(r4)
235 stw r20, VCPU_GPR(r20)(r4)
236 stw r21, VCPU_GPR(r21)(r4)
237 stw r22, VCPU_GPR(r22)(r4)
238 stw r23, VCPU_GPR(r23)(r4)
239 stw r24, VCPU_GPR(r24)(r4)
240 stw r25, VCPU_GPR(r25)(r4)
241 stw r26, VCPU_GPR(r26)(r4)
242 stw r27, VCPU_GPR(r27)(r4)
243 stw r28, VCPU_GPR(r28)(r4)
244 stw r29, VCPU_GPR(r29)(r4)
245 stw r30, VCPU_GPR(r30)(r4)
246 stw r31, VCPU_GPR(r31)(r4)
247
248 /* Load host non-volatile register state from host stack. */
249 lwz r14, HOST_NV_GPR(r14)(r1)
250 lwz r15, HOST_NV_GPR(r15)(r1)
251 lwz r16, HOST_NV_GPR(r16)(r1)
252 lwz r17, HOST_NV_GPR(r17)(r1)
253 lwz r18, HOST_NV_GPR(r18)(r1)
254 lwz r19, HOST_NV_GPR(r19)(r1)
255 lwz r20, HOST_NV_GPR(r20)(r1)
256 lwz r21, HOST_NV_GPR(r21)(r1)
257 lwz r22, HOST_NV_GPR(r22)(r1)
258 lwz r23, HOST_NV_GPR(r23)(r1)
259 lwz r24, HOST_NV_GPR(r24)(r1)
260 lwz r25, HOST_NV_GPR(r25)(r1)
261 lwz r26, HOST_NV_GPR(r26)(r1)
262 lwz r27, HOST_NV_GPR(r27)(r1)
263 lwz r28, HOST_NV_GPR(r28)(r1)
264 lwz r29, HOST_NV_GPR(r29)(r1)
265 lwz r30, HOST_NV_GPR(r30)(r1)
266 lwz r31, HOST_NV_GPR(r31)(r1)
267
268 /* Return to kvm_vcpu_run(). */
269 lwz r4, HOST_STACK_LR(r1)
270 addi r1, r1, HOST_STACK_SIZE
271 mtlr r4
272 /* r3 still contains the return code from kvmppc_handle_exit(). */
273 blr
274
275
276/* Registers:
277 * r3: kvm_run pointer
278 * r4: vcpu pointer
279 */
280_GLOBAL(__kvmppc_vcpu_run)
281 stwu r1, -HOST_STACK_SIZE(r1)
282 stw r1, VCPU_HOST_STACK(r4) /* Save stack pointer to vcpu. */
283
284 /* Save host state to stack. */
285 stw r3, HOST_RUN(r1)
286 mflr r3
287 stw r3, HOST_STACK_LR(r1)
288
289 /* Save host non-volatile register state to stack. */
290 stw r14, HOST_NV_GPR(r14)(r1)
291 stw r15, HOST_NV_GPR(r15)(r1)
292 stw r16, HOST_NV_GPR(r16)(r1)
293 stw r17, HOST_NV_GPR(r17)(r1)
294 stw r18, HOST_NV_GPR(r18)(r1)
295 stw r19, HOST_NV_GPR(r19)(r1)
296 stw r20, HOST_NV_GPR(r20)(r1)
297 stw r21, HOST_NV_GPR(r21)(r1)
298 stw r22, HOST_NV_GPR(r22)(r1)
299 stw r23, HOST_NV_GPR(r23)(r1)
300 stw r24, HOST_NV_GPR(r24)(r1)
301 stw r25, HOST_NV_GPR(r25)(r1)
302 stw r26, HOST_NV_GPR(r26)(r1)
303 stw r27, HOST_NV_GPR(r27)(r1)
304 stw r28, HOST_NV_GPR(r28)(r1)
305 stw r29, HOST_NV_GPR(r29)(r1)
306 stw r30, HOST_NV_GPR(r30)(r1)
307 stw r31, HOST_NV_GPR(r31)(r1)
308
309 /* Load guest non-volatiles. */
310 lwz r14, VCPU_GPR(r14)(r4)
311 lwz r15, VCPU_GPR(r15)(r4)
312 lwz r16, VCPU_GPR(r16)(r4)
313 lwz r17, VCPU_GPR(r17)(r4)
314 lwz r18, VCPU_GPR(r18)(r4)
315 lwz r19, VCPU_GPR(r19)(r4)
316 lwz r20, VCPU_GPR(r20)(r4)
317 lwz r21, VCPU_GPR(r21)(r4)
318 lwz r22, VCPU_GPR(r22)(r4)
319 lwz r23, VCPU_GPR(r23)(r4)
320 lwz r24, VCPU_GPR(r24)(r4)
321 lwz r25, VCPU_GPR(r25)(r4)
322 lwz r26, VCPU_GPR(r26)(r4)
323 lwz r27, VCPU_GPR(r27)(r4)
324 lwz r28, VCPU_GPR(r28)(r4)
325 lwz r29, VCPU_GPR(r29)(r4)
326 lwz r30, VCPU_GPR(r30)(r4)
327 lwz r31, VCPU_GPR(r31)(r4)
328
329lightweight_exit:
330 stw r2, HOST_R2(r1)
331
332 mfspr r3, SPRN_PID
333 stw r3, VCPU_HOST_PID(r4)
334 lwz r3, VCPU_PID(r4)
335 mtspr SPRN_PID, r3
336
337 /* Prevent all TLB updates. */
338 mfmsr r5
339 lis r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@h
340 ori r6, r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
341 andc r6, r5, r6
342 mtmsr r6
343
344 /* Save the host's non-pinned TLB mappings, and load the guest mappings
345 * over them. Leave the host's "pinned" kernel mappings in place. */
346 /* XXX optimization: use generation count to avoid swapping unmodified
347 * entries. */
348 mfspr r10, SPRN_MMUCR /* Save host MMUCR. */
349 lis r8, tlb_44x_hwater@ha
350 lwz r8, tlb_44x_hwater@l(r8)
351 addi r3, r4, VCPU_HOST_TLB - 4
352 addi r9, r4, VCPU_SHADOW_TLB - 4
353 li r6, 0
3541:
355 /* Save host entry. */
356 tlbre r7, r6, PPC44x_TLB_PAGEID
357 mfspr r5, SPRN_MMUCR
358 stwu r5, 4(r3)
359 stwu r7, 4(r3)
360 tlbre r7, r6, PPC44x_TLB_XLAT
361 stwu r7, 4(r3)
362 tlbre r7, r6, PPC44x_TLB_ATTRIB
363 stwu r7, 4(r3)
364 /* Load guest entry. */
365 lwzu r7, 4(r9)
366 mtspr SPRN_MMUCR, r7
367 lwzu r7, 4(r9)
368 tlbwe r7, r6, PPC44x_TLB_PAGEID
369 lwzu r7, 4(r9)
370 tlbwe r7, r6, PPC44x_TLB_XLAT
371 lwzu r7, 4(r9)
372 tlbwe r7, r6, PPC44x_TLB_ATTRIB
373 /* Increment index. */
374 addi r6, r6, 1
375 cmpw r6, r8
376 blt 1b
377 mtspr SPRN_MMUCR, r10 /* Restore host MMUCR. */
378
379 iccci 0, 0 /* XXX hack */
380
381 /* Load some guest volatiles. */
382 lwz r0, VCPU_GPR(r0)(r4)
383 lwz r2, VCPU_GPR(r2)(r4)
384 lwz r9, VCPU_GPR(r9)(r4)
385 lwz r10, VCPU_GPR(r10)(r4)
386 lwz r11, VCPU_GPR(r11)(r4)
387 lwz r12, VCPU_GPR(r12)(r4)
388 lwz r13, VCPU_GPR(r13)(r4)
389 lwz r3, VCPU_LR(r4)
390 mtlr r3
391 lwz r3, VCPU_XER(r4)
392 mtxer r3
393
394 /* Switch the IVPR. XXX If we take a TLB miss after this we're screwed,
395 * so how do we make sure vcpu won't fault? */
396 lis r8, kvmppc_booke_handlers@ha
397 lwz r8, kvmppc_booke_handlers@l(r8)
398 mtspr SPRN_IVPR, r8
399
400 /* Save vcpu pointer for the exception handlers. */
401 mtspr SPRN_SPRG1, r4
402
403 /* Can't switch the stack pointer until after IVPR is switched,
404 * because host interrupt handlers would get confused. */
405 lwz r1, VCPU_GPR(r1)(r4)
406
407 /* XXX handle USPRG0 */
408 /* Host interrupt handlers may have clobbered these guest-readable
409 * SPRGs, so we need to reload them here with the guest's values. */
410 lwz r3, VCPU_SPRG4(r4)
411 mtspr SPRN_SPRG4, r3
412 lwz r3, VCPU_SPRG5(r4)
413 mtspr SPRN_SPRG5, r3
414 lwz r3, VCPU_SPRG6(r4)
415 mtspr SPRN_SPRG6, r3
416 lwz r3, VCPU_SPRG7(r4)
417 mtspr SPRN_SPRG7, r3
418
419 /* Finish loading guest volatiles and jump to guest. */
420 lwz r3, VCPU_CTR(r4)
421 mtctr r3
422 lwz r3, VCPU_CR(r4)
423 mtcr r3
424 lwz r5, VCPU_GPR(r5)(r4)
425 lwz r6, VCPU_GPR(r6)(r4)
426 lwz r7, VCPU_GPR(r7)(r4)
427 lwz r8, VCPU_GPR(r8)(r4)
428 lwz r3, VCPU_PC(r4)
429 mtsrr0 r3
430 lwz r3, VCPU_MSR(r4)
431 oris r3, r3, KVMPPC_MSR_MASK@h
432 ori r3, r3, KVMPPC_MSR_MASK@l
433 mtsrr1 r3
434 lwz r3, VCPU_GPR(r3)(r4)
435 lwz r4, VCPU_GPR(r4)(r4)
436 rfi
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
new file mode 100644
index 000000000000..a03fe0c80698
--- /dev/null
+++ b/arch/powerpc/kvm/emulate.c
@@ -0,0 +1,760 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#include <linux/jiffies.h>
21#include <linux/timer.h>
22#include <linux/types.h>
23#include <linux/string.h>
24#include <linux/kvm_host.h>
25
26#include <asm/dcr.h>
27#include <asm/dcr-regs.h>
28#include <asm/time.h>
29#include <asm/byteorder.h>
30#include <asm/kvm_ppc.h>
31
32#include "44x_tlb.h"
33
34/* Instruction decoding */
35static inline unsigned int get_op(u32 inst)
36{
37 return inst >> 26;
38}
39
40static inline unsigned int get_xop(u32 inst)
41{
42 return (inst >> 1) & 0x3ff;
43}
44
45static inline unsigned int get_sprn(u32 inst)
46{
47 return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
48}
49
50static inline unsigned int get_dcrn(u32 inst)
51{
52 return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
53}
54
55static inline unsigned int get_rt(u32 inst)
56{
57 return (inst >> 21) & 0x1f;
58}
59
60static inline unsigned int get_rs(u32 inst)
61{
62 return (inst >> 21) & 0x1f;
63}
64
65static inline unsigned int get_ra(u32 inst)
66{
67 return (inst >> 16) & 0x1f;
68}
69
70static inline unsigned int get_rb(u32 inst)
71{
72 return (inst >> 11) & 0x1f;
73}
74
75static inline unsigned int get_rc(u32 inst)
76{
77 return inst & 0x1;
78}
79
80static inline unsigned int get_ws(u32 inst)
81{
82 return (inst >> 11) & 0x1f;
83}
84
85static inline unsigned int get_d(u32 inst)
86{
87 return inst & 0xffff;
88}
89
90static int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
91 const struct tlbe *tlbe)
92{
93 gpa_t gpa;
94
95 if (!get_tlb_v(tlbe))
96 return 0;
97
98 /* Does it match current guest AS? */
99 /* XXX what about IS != DS? */
100 if (get_tlb_ts(tlbe) != !!(vcpu->arch.msr & MSR_IS))
101 return 0;
102
103 gpa = get_tlb_raddr(tlbe);
104 if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
105 /* Mapping is not for RAM. */
106 return 0;
107
108 return 1;
109}
110
111static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst)
112{
113 u64 eaddr;
114 u64 raddr;
115 u64 asid;
116 u32 flags;
117 struct tlbe *tlbe;
118 unsigned int ra;
119 unsigned int rs;
120 unsigned int ws;
121 unsigned int index;
122
123 ra = get_ra(inst);
124 rs = get_rs(inst);
125 ws = get_ws(inst);
126
127 index = vcpu->arch.gpr[ra];
128 if (index > PPC44x_TLB_SIZE) {
129 printk("%s: index %d\n", __func__, index);
130 kvmppc_dump_vcpu(vcpu);
131 return EMULATE_FAIL;
132 }
133
134 tlbe = &vcpu->arch.guest_tlb[index];
135
136 /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
137 if (tlbe->word0 & PPC44x_TLB_VALID) {
138 eaddr = get_tlb_eaddr(tlbe);
139 asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
140 kvmppc_mmu_invalidate(vcpu, eaddr, asid);
141 }
142
143 switch (ws) {
144 case PPC44x_TLB_PAGEID:
145 tlbe->tid = vcpu->arch.mmucr & 0xff;
146 tlbe->word0 = vcpu->arch.gpr[rs];
147 break;
148
149 case PPC44x_TLB_XLAT:
150 tlbe->word1 = vcpu->arch.gpr[rs];
151 break;
152
153 case PPC44x_TLB_ATTRIB:
154 tlbe->word2 = vcpu->arch.gpr[rs];
155 break;
156
157 default:
158 return EMULATE_FAIL;
159 }
160
161 if (tlbe_is_host_safe(vcpu, tlbe)) {
162 eaddr = get_tlb_eaddr(tlbe);
163 raddr = get_tlb_raddr(tlbe);
164 asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
165 flags = tlbe->word2 & 0xffff;
166
167 /* Create a 4KB mapping on the host. If the guest wanted a
168 * large page, only the first 4KB is mapped here and the rest
169 * are mapped on the fly. */
170 kvmppc_mmu_map(vcpu, eaddr, raddr >> PAGE_SHIFT, asid, flags);
171 }
172
173 return EMULATE_DONE;
174}
175
176static void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
177{
178 if (vcpu->arch.tcr & TCR_DIE) {
179 /* The decrementer ticks at the same rate as the timebase, so
180 * that's how we convert the guest DEC value to the number of
181 * host ticks. */
182 unsigned long nr_jiffies;
183
184 nr_jiffies = vcpu->arch.dec / tb_ticks_per_jiffy;
185 mod_timer(&vcpu->arch.dec_timer,
186 get_jiffies_64() + nr_jiffies);
187 } else {
188 del_timer(&vcpu->arch.dec_timer);
189 }
190}
191
192static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
193{
194 vcpu->arch.pc = vcpu->arch.srr0;
195 kvmppc_set_msr(vcpu, vcpu->arch.srr1);
196}
197
198/* XXX to do:
199 * lhax
200 * lhaux
201 * lswx
202 * lswi
203 * stswx
204 * stswi
205 * lha
206 * lhau
207 * lmw
208 * stmw
209 *
210 * XXX is_bigendian should depend on MMU mapping or MSR[LE]
211 */
212int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
213{
214 u32 inst = vcpu->arch.last_inst;
215 u32 ea;
216 int ra;
217 int rb;
218 int rc;
219 int rs;
220 int rt;
221 int sprn;
222 int dcrn;
223 enum emulation_result emulated = EMULATE_DONE;
224 int advance = 1;
225
226 switch (get_op(inst)) {
227 case 3: /* trap */
228 printk("trap!\n");
229 kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM);
230 advance = 0;
231 break;
232
233 case 19:
234 switch (get_xop(inst)) {
235 case 50: /* rfi */
236 kvmppc_emul_rfi(vcpu);
237 advance = 0;
238 break;
239
240 default:
241 emulated = EMULATE_FAIL;
242 break;
243 }
244 break;
245
246 case 31:
247 switch (get_xop(inst)) {
248
249 case 83: /* mfmsr */
250 rt = get_rt(inst);
251 vcpu->arch.gpr[rt] = vcpu->arch.msr;
252 break;
253
254 case 87: /* lbzx */
255 rt = get_rt(inst);
256 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
257 break;
258
259 case 131: /* wrtee */
260 rs = get_rs(inst);
261 vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
262 | (vcpu->arch.gpr[rs] & MSR_EE);
263 break;
264
265 case 146: /* mtmsr */
266 rs = get_rs(inst);
267 kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
268 break;
269
270 case 163: /* wrteei */
271 vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
272 | (inst & MSR_EE);
273 break;
274
275 case 215: /* stbx */
276 rs = get_rs(inst);
277 emulated = kvmppc_handle_store(run, vcpu,
278 vcpu->arch.gpr[rs],
279 1, 1);
280 break;
281
282 case 247: /* stbux */
283 rs = get_rs(inst);
284 ra = get_ra(inst);
285 rb = get_rb(inst);
286
287 ea = vcpu->arch.gpr[rb];
288 if (ra)
289 ea += vcpu->arch.gpr[ra];
290
291 emulated = kvmppc_handle_store(run, vcpu,
292 vcpu->arch.gpr[rs],
293 1, 1);
294 vcpu->arch.gpr[rs] = ea;
295 break;
296
297 case 279: /* lhzx */
298 rt = get_rt(inst);
299 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
300 break;
301
302 case 311: /* lhzux */
303 rt = get_rt(inst);
304 ra = get_ra(inst);
305 rb = get_rb(inst);
306
307 ea = vcpu->arch.gpr[rb];
308 if (ra)
309 ea += vcpu->arch.gpr[ra];
310
311 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
312 vcpu->arch.gpr[ra] = ea;
313 break;
314
315 case 323: /* mfdcr */
316 dcrn = get_dcrn(inst);
317 rt = get_rt(inst);
318
319 /* The guest may access CPR0 registers to determine the timebase
320 * frequency, and it must know the real host frequency because it
321 * can directly access the timebase registers.
322 *
323 * It would be possible to emulate those accesses in userspace,
324 * but userspace can really only figure out the end frequency.
325 * We could decompose that into the factors that compute it, but
326 * that's tricky math, and it's easier to just report the real
327 * CPR0 values.
328 */
329 switch (dcrn) {
330 case DCRN_CPR0_CONFIG_ADDR:
331 vcpu->arch.gpr[rt] = vcpu->arch.cpr0_cfgaddr;
332 break;
333 case DCRN_CPR0_CONFIG_DATA:
334 local_irq_disable();
335 mtdcr(DCRN_CPR0_CONFIG_ADDR,
336 vcpu->arch.cpr0_cfgaddr);
337 vcpu->arch.gpr[rt] = mfdcr(DCRN_CPR0_CONFIG_DATA);
338 local_irq_enable();
339 break;
340 default:
341 run->dcr.dcrn = dcrn;
342 run->dcr.data = 0;
343 run->dcr.is_write = 0;
344 vcpu->arch.io_gpr = rt;
345 vcpu->arch.dcr_needed = 1;
346 emulated = EMULATE_DO_DCR;
347 }
348
349 break;
350
351 case 339: /* mfspr */
352 sprn = get_sprn(inst);
353 rt = get_rt(inst);
354
355 switch (sprn) {
356 case SPRN_SRR0:
357 vcpu->arch.gpr[rt] = vcpu->arch.srr0; break;
358 case SPRN_SRR1:
359 vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
360 case SPRN_MMUCR:
361 vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
362 case SPRN_PID:
363 vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
364 case SPRN_IVPR:
365 vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
366 case SPRN_CCR0:
367 vcpu->arch.gpr[rt] = vcpu->arch.ccr0; break;
368 case SPRN_CCR1:
369 vcpu->arch.gpr[rt] = vcpu->arch.ccr1; break;
370 case SPRN_PVR:
371 vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
372 case SPRN_DEAR:
373 vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
374 case SPRN_ESR:
375 vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
376 case SPRN_DBCR0:
377 vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
378 case SPRN_DBCR1:
379 vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
380
381 /* Note: mftb and TBRL/TBWL are user-accessible, so
382 * the guest can always access the real TB anyways.
383 * In fact, we probably will never see these traps. */
384 case SPRN_TBWL:
385 vcpu->arch.gpr[rt] = mftbl(); break;
386 case SPRN_TBWU:
387 vcpu->arch.gpr[rt] = mftbu(); break;
388
389 case SPRN_SPRG0:
390 vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break;
391 case SPRN_SPRG1:
392 vcpu->arch.gpr[rt] = vcpu->arch.sprg1; break;
393 case SPRN_SPRG2:
394 vcpu->arch.gpr[rt] = vcpu->arch.sprg2; break;
395 case SPRN_SPRG3:
396 vcpu->arch.gpr[rt] = vcpu->arch.sprg3; break;
397 /* Note: SPRG4-7 are user-readable, so we don't get
398 * a trap. */
399
400 case SPRN_IVOR0:
401 vcpu->arch.gpr[rt] = vcpu->arch.ivor[0]; break;
402 case SPRN_IVOR1:
403 vcpu->arch.gpr[rt] = vcpu->arch.ivor[1]; break;
404 case SPRN_IVOR2:
405 vcpu->arch.gpr[rt] = vcpu->arch.ivor[2]; break;
406 case SPRN_IVOR3:
407 vcpu->arch.gpr[rt] = vcpu->arch.ivor[3]; break;
408 case SPRN_IVOR4:
409 vcpu->arch.gpr[rt] = vcpu->arch.ivor[4]; break;
410 case SPRN_IVOR5:
411 vcpu->arch.gpr[rt] = vcpu->arch.ivor[5]; break;
412 case SPRN_IVOR6:
413 vcpu->arch.gpr[rt] = vcpu->arch.ivor[6]; break;
414 case SPRN_IVOR7:
415 vcpu->arch.gpr[rt] = vcpu->arch.ivor[7]; break;
416 case SPRN_IVOR8:
417 vcpu->arch.gpr[rt] = vcpu->arch.ivor[8]; break;
418 case SPRN_IVOR9:
419 vcpu->arch.gpr[rt] = vcpu->arch.ivor[9]; break;
420 case SPRN_IVOR10:
421 vcpu->arch.gpr[rt] = vcpu->arch.ivor[10]; break;
422 case SPRN_IVOR11:
423 vcpu->arch.gpr[rt] = vcpu->arch.ivor[11]; break;
424 case SPRN_IVOR12:
425 vcpu->arch.gpr[rt] = vcpu->arch.ivor[12]; break;
426 case SPRN_IVOR13:
427 vcpu->arch.gpr[rt] = vcpu->arch.ivor[13]; break;
428 case SPRN_IVOR14:
429 vcpu->arch.gpr[rt] = vcpu->arch.ivor[14]; break;
430 case SPRN_IVOR15:
431 vcpu->arch.gpr[rt] = vcpu->arch.ivor[15]; break;
432
433 default:
434 printk("mfspr: unknown spr %x\n", sprn);
435 vcpu->arch.gpr[rt] = 0;
436 break;
437 }
438 break;
439
440 case 407: /* sthx */
441 rs = get_rs(inst);
442 ra = get_ra(inst);
443 rb = get_rb(inst);
444
445 emulated = kvmppc_handle_store(run, vcpu,
446 vcpu->arch.gpr[rs],
447 2, 1);
448 break;
449
450 case 439: /* sthux */
451 rs = get_rs(inst);
452 ra = get_ra(inst);
453 rb = get_rb(inst);
454
455 ea = vcpu->arch.gpr[rb];
456 if (ra)
457 ea += vcpu->arch.gpr[ra];
458
459 emulated = kvmppc_handle_store(run, vcpu,
460 vcpu->arch.gpr[rs],
461 2, 1);
462 vcpu->arch.gpr[ra] = ea;
463 break;
464
465 case 451: /* mtdcr */
466 dcrn = get_dcrn(inst);
467 rs = get_rs(inst);
468
469 /* emulate some access in kernel */
470 switch (dcrn) {
471 case DCRN_CPR0_CONFIG_ADDR:
472 vcpu->arch.cpr0_cfgaddr = vcpu->arch.gpr[rs];
473 break;
474 default:
475 run->dcr.dcrn = dcrn;
476 run->dcr.data = vcpu->arch.gpr[rs];
477 run->dcr.is_write = 1;
478 vcpu->arch.dcr_needed = 1;
479 emulated = EMULATE_DO_DCR;
480 }
481
482 break;
483
484 case 467: /* mtspr */
485 sprn = get_sprn(inst);
486 rs = get_rs(inst);
487 switch (sprn) {
488 case SPRN_SRR0:
489 vcpu->arch.srr0 = vcpu->arch.gpr[rs]; break;
490 case SPRN_SRR1:
491 vcpu->arch.srr1 = vcpu->arch.gpr[rs]; break;
492 case SPRN_MMUCR:
493 vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
494 case SPRN_PID:
495 vcpu->arch.pid = vcpu->arch.gpr[rs]; break;
496 case SPRN_CCR0:
497 vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
498 case SPRN_CCR1:
499 vcpu->arch.ccr1 = vcpu->arch.gpr[rs]; break;
500 case SPRN_DEAR:
501 vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
502 case SPRN_ESR:
503 vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
504 case SPRN_DBCR0:
505 vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
506 case SPRN_DBCR1:
507 vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
508
509 /* XXX We need to context-switch the timebase for
510 * watchdog and FIT. */
511 case SPRN_TBWL: break;
512 case SPRN_TBWU: break;
513
514 case SPRN_DEC:
515 vcpu->arch.dec = vcpu->arch.gpr[rs];
516 kvmppc_emulate_dec(vcpu);
517 break;
518
519 case SPRN_TSR:
520 vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
521
522 case SPRN_TCR:
523 vcpu->arch.tcr = vcpu->arch.gpr[rs];
524 kvmppc_emulate_dec(vcpu);
525 break;
526
527 case SPRN_SPRG0:
528 vcpu->arch.sprg0 = vcpu->arch.gpr[rs]; break;
529 case SPRN_SPRG1:
530 vcpu->arch.sprg1 = vcpu->arch.gpr[rs]; break;
531 case SPRN_SPRG2:
532 vcpu->arch.sprg2 = vcpu->arch.gpr[rs]; break;
533 case SPRN_SPRG3:
534 vcpu->arch.sprg3 = vcpu->arch.gpr[rs]; break;
535
536 /* Note: SPRG4-7 are user-readable. These values are
537 * loaded into the real SPRGs when resuming the
538 * guest. */
539 case SPRN_SPRG4:
540 vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
541 case SPRN_SPRG5:
542 vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
543 case SPRN_SPRG6:
544 vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
545 case SPRN_SPRG7:
546 vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
547
548 case SPRN_IVPR:
549 vcpu->arch.ivpr = vcpu->arch.gpr[rs]; break;
550 case SPRN_IVOR0:
551 vcpu->arch.ivor[0] = vcpu->arch.gpr[rs]; break;
552 case SPRN_IVOR1:
553 vcpu->arch.ivor[1] = vcpu->arch.gpr[rs]; break;
554 case SPRN_IVOR2:
555 vcpu->arch.ivor[2] = vcpu->arch.gpr[rs]; break;
556 case SPRN_IVOR3:
557 vcpu->arch.ivor[3] = vcpu->arch.gpr[rs]; break;
558 case SPRN_IVOR4:
559 vcpu->arch.ivor[4] = vcpu->arch.gpr[rs]; break;
560 case SPRN_IVOR5:
561 vcpu->arch.ivor[5] = vcpu->arch.gpr[rs]; break;
562 case SPRN_IVOR6:
563 vcpu->arch.ivor[6] = vcpu->arch.gpr[rs]; break;
564 case SPRN_IVOR7:
565 vcpu->arch.ivor[7] = vcpu->arch.gpr[rs]; break;
566 case SPRN_IVOR8:
567 vcpu->arch.ivor[8] = vcpu->arch.gpr[rs]; break;
568 case SPRN_IVOR9:
569 vcpu->arch.ivor[9] = vcpu->arch.gpr[rs]; break;
570 case SPRN_IVOR10:
571 vcpu->arch.ivor[10] = vcpu->arch.gpr[rs]; break;
572 case SPRN_IVOR11:
573 vcpu->arch.ivor[11] = vcpu->arch.gpr[rs]; break;
574 case SPRN_IVOR12:
575 vcpu->arch.ivor[12] = vcpu->arch.gpr[rs]; break;
576 case SPRN_IVOR13:
577 vcpu->arch.ivor[13] = vcpu->arch.gpr[rs]; break;
578 case SPRN_IVOR14:
579 vcpu->arch.ivor[14] = vcpu->arch.gpr[rs]; break;
580 case SPRN_IVOR15:
581 vcpu->arch.ivor[15] = vcpu->arch.gpr[rs]; break;
582
583 default:
584 printk("mtspr: unknown spr %x\n", sprn);
585 emulated = EMULATE_FAIL;
586 break;
587 }
588 break;
589
590 case 470: /* dcbi */
591 /* Do nothing. The guest is performing dcbi because
592 * hardware DMA is not snooped by the dcache, but
593 * emulated DMA either goes through the dcache as
594 * normal writes, or the host kernel has handled dcache
595 * coherence. */
596 break;
597
598 case 534: /* lwbrx */
599 rt = get_rt(inst);
600 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
601 break;
602
603 case 566: /* tlbsync */
604 break;
605
606 case 662: /* stwbrx */
607 rs = get_rs(inst);
608 ra = get_ra(inst);
609 rb = get_rb(inst);
610
611 emulated = kvmppc_handle_store(run, vcpu,
612 vcpu->arch.gpr[rs],
613 4, 0);
614 break;
615
616 case 978: /* tlbwe */
617 emulated = kvmppc_emul_tlbwe(vcpu, inst);
618 break;
619
620 case 914: { /* tlbsx */
621 int index;
622 unsigned int as = get_mmucr_sts(vcpu);
623 unsigned int pid = get_mmucr_stid(vcpu);
624
625 rt = get_rt(inst);
626 ra = get_ra(inst);
627 rb = get_rb(inst);
628 rc = get_rc(inst);
629
630 ea = vcpu->arch.gpr[rb];
631 if (ra)
632 ea += vcpu->arch.gpr[ra];
633
634 index = kvmppc_44x_tlb_index(vcpu, ea, pid, as);
635 if (rc) {
636 if (index < 0)
637 vcpu->arch.cr &= ~0x20000000;
638 else
639 vcpu->arch.cr |= 0x20000000;
640 }
641 vcpu->arch.gpr[rt] = index;
642
643 }
644 break;
645
646 case 790: /* lhbrx */
647 rt = get_rt(inst);
648 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
649 break;
650
651 case 918: /* sthbrx */
652 rs = get_rs(inst);
653 ra = get_ra(inst);
654 rb = get_rb(inst);
655
656 emulated = kvmppc_handle_store(run, vcpu,
657 vcpu->arch.gpr[rs],
658 2, 0);
659 break;
660
661 case 966: /* iccci */
662 break;
663
664 default:
665 printk("unknown: op %d xop %d\n", get_op(inst),
666 get_xop(inst));
667 emulated = EMULATE_FAIL;
668 break;
669 }
670 break;
671
672 case 32: /* lwz */
673 rt = get_rt(inst);
674 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
675 break;
676
677 case 33: /* lwzu */
678 ra = get_ra(inst);
679 rt = get_rt(inst);
680 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
681 vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
682 break;
683
684 case 34: /* lbz */
685 rt = get_rt(inst);
686 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
687 break;
688
689 case 35: /* lbzu */
690 ra = get_ra(inst);
691 rt = get_rt(inst);
692 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
693 vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
694 break;
695
696 case 36: /* stw */
697 rs = get_rs(inst);
698 emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
699 4, 1);
700 break;
701
702 case 37: /* stwu */
703 ra = get_ra(inst);
704 rs = get_rs(inst);
705 emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
706 4, 1);
707 vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
708 break;
709
710 case 38: /* stb */
711 rs = get_rs(inst);
712 emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
713 1, 1);
714 break;
715
716 case 39: /* stbu */
717 ra = get_ra(inst);
718 rs = get_rs(inst);
719 emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
720 1, 1);
721 vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
722 break;
723
724 case 40: /* lhz */
725 rt = get_rt(inst);
726 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
727 break;
728
729 case 41: /* lhzu */
730 ra = get_ra(inst);
731 rt = get_rt(inst);
732 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
733 vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
734 break;
735
736 case 44: /* sth */
737 rs = get_rs(inst);
738 emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
739 2, 1);
740 break;
741
742 case 45: /* sthu */
743 ra = get_ra(inst);
744 rs = get_rs(inst);
745 emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
746 2, 1);
747 vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
748 break;
749
750 default:
751 printk("unknown op %d\n", get_op(inst));
752 emulated = EMULATE_FAIL;
753 break;
754 }
755
756 if (advance)
757 vcpu->arch.pc += 4; /* Advance past emulated instruction. */
758
759 return emulated;
760}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
new file mode 100644
index 000000000000..bad40bd2d3ac
--- /dev/null
+++ b/arch/powerpc/kvm/powerpc.c
@@ -0,0 +1,436 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
19 */
20
21#include <linux/errno.h>
22#include <linux/err.h>
23#include <linux/kvm_host.h>
24#include <linux/module.h>
25#include <linux/vmalloc.h>
26#include <linux/fs.h>
27#include <asm/cputable.h>
28#include <asm/uaccess.h>
29#include <asm/kvm_ppc.h>
30
31
32gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
33{
34 return gfn;
35}
36
37int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
38{
39 /* XXX implement me */
40 return 0;
41}
42
43int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
44{
45 return 1;
46}
47
48
49int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
50{
51 enum emulation_result er;
52 int r;
53
54 er = kvmppc_emulate_instruction(run, vcpu);
55 switch (er) {
56 case EMULATE_DONE:
57 /* Future optimization: only reload non-volatiles if they were
58 * actually modified. */
59 r = RESUME_GUEST_NV;
60 break;
61 case EMULATE_DO_MMIO:
62 run->exit_reason = KVM_EXIT_MMIO;
63 /* We must reload nonvolatiles because "update" load/store
64 * instructions modify register state. */
65 /* Future optimization: only reload non-volatiles if they were
66 * actually modified. */
67 r = RESUME_HOST_NV;
68 break;
69 case EMULATE_FAIL:
70 /* XXX Deliver Program interrupt to guest. */
71 printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__,
72 vcpu->arch.last_inst);
73 r = RESUME_HOST;
74 break;
75 default:
76 BUG();
77 }
78
79 return r;
80}
81
82void kvm_arch_hardware_enable(void *garbage)
83{
84}
85
86void kvm_arch_hardware_disable(void *garbage)
87{
88}
89
90int kvm_arch_hardware_setup(void)
91{
92 return 0;
93}
94
95void kvm_arch_hardware_unsetup(void)
96{
97}
98
99void kvm_arch_check_processor_compat(void *rtn)
100{
101 int r;
102
103 if (strcmp(cur_cpu_spec->platform, "ppc440") == 0)
104 r = 0;
105 else
106 r = -ENOTSUPP;
107
108 *(int *)rtn = r;
109}
110
111struct kvm *kvm_arch_create_vm(void)
112{
113 struct kvm *kvm;
114
115 kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
116 if (!kvm)
117 return ERR_PTR(-ENOMEM);
118
119 return kvm;
120}
121
122static void kvmppc_free_vcpus(struct kvm *kvm)
123{
124 unsigned int i;
125
126 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
127 if (kvm->vcpus[i]) {
128 kvm_arch_vcpu_free(kvm->vcpus[i]);
129 kvm->vcpus[i] = NULL;
130 }
131 }
132}
133
134void kvm_arch_destroy_vm(struct kvm *kvm)
135{
136 kvmppc_free_vcpus(kvm);
137 kvm_free_physmem(kvm);
138 kfree(kvm);
139}
140
141int kvm_dev_ioctl_check_extension(long ext)
142{
143 int r;
144
145 switch (ext) {
146 case KVM_CAP_USER_MEMORY:
147 r = 1;
148 break;
149 default:
150 r = 0;
151 break;
152 }
153 return r;
154
155}
156
157long kvm_arch_dev_ioctl(struct file *filp,
158 unsigned int ioctl, unsigned long arg)
159{
160 return -EINVAL;
161}
162
163int kvm_arch_set_memory_region(struct kvm *kvm,
164 struct kvm_userspace_memory_region *mem,
165 struct kvm_memory_slot old,
166 int user_alloc)
167{
168 return 0;
169}
170
171struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
172{
173 struct kvm_vcpu *vcpu;
174 int err;
175
176 vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
177 if (!vcpu) {
178 err = -ENOMEM;
179 goto out;
180 }
181
182 err = kvm_vcpu_init(vcpu, kvm, id);
183 if (err)
184 goto free_vcpu;
185
186 return vcpu;
187
188free_vcpu:
189 kmem_cache_free(kvm_vcpu_cache, vcpu);
190out:
191 return ERR_PTR(err);
192}
193
194void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
195{
196 kvm_vcpu_uninit(vcpu);
197 kmem_cache_free(kvm_vcpu_cache, vcpu);
198}
199
200void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
201{
202 kvm_arch_vcpu_free(vcpu);
203}
204
205int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
206{
207 unsigned int priority = exception_priority[BOOKE_INTERRUPT_DECREMENTER];
208
209 return test_bit(priority, &vcpu->arch.pending_exceptions);
210}
211
212static void kvmppc_decrementer_func(unsigned long data)
213{
214 struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data;
215
216 kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_DECREMENTER);
217}
218
219int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
220{
221 setup_timer(&vcpu->arch.dec_timer, kvmppc_decrementer_func,
222 (unsigned long)vcpu);
223
224 return 0;
225}
226
227void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
228{
229}
230
231void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
232{
233}
234
235void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
236{
237}
238
239void decache_vcpus_on_cpu(int cpu)
240{
241}
242
243int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
244 struct kvm_debug_guest *dbg)
245{
246 return -ENOTSUPP;
247}
248
249static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
250 struct kvm_run *run)
251{
252 u32 *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr];
253 *gpr = run->dcr.data;
254}
255
256static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
257 struct kvm_run *run)
258{
259 u32 *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr];
260
261 if (run->mmio.len > sizeof(*gpr)) {
262 printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len);
263 return;
264 }
265
266 if (vcpu->arch.mmio_is_bigendian) {
267 switch (run->mmio.len) {
268 case 4: *gpr = *(u32 *)run->mmio.data; break;
269 case 2: *gpr = *(u16 *)run->mmio.data; break;
270 case 1: *gpr = *(u8 *)run->mmio.data; break;
271 }
272 } else {
273 /* Convert BE data from userland back to LE. */
274 switch (run->mmio.len) {
275 case 4: *gpr = ld_le32((u32 *)run->mmio.data); break;
276 case 2: *gpr = ld_le16((u16 *)run->mmio.data); break;
277 case 1: *gpr = *(u8 *)run->mmio.data; break;
278 }
279 }
280}
281
282int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
283 unsigned int rt, unsigned int bytes, int is_bigendian)
284{
285 if (bytes > sizeof(run->mmio.data)) {
286 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
287 run->mmio.len);
288 }
289
290 run->mmio.phys_addr = vcpu->arch.paddr_accessed;
291 run->mmio.len = bytes;
292 run->mmio.is_write = 0;
293
294 vcpu->arch.io_gpr = rt;
295 vcpu->arch.mmio_is_bigendian = is_bigendian;
296 vcpu->mmio_needed = 1;
297 vcpu->mmio_is_write = 0;
298
299 return EMULATE_DO_MMIO;
300}
301
302int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
303 u32 val, unsigned int bytes, int is_bigendian)
304{
305 void *data = run->mmio.data;
306
307 if (bytes > sizeof(run->mmio.data)) {
308 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
309 run->mmio.len);
310 }
311
312 run->mmio.phys_addr = vcpu->arch.paddr_accessed;
313 run->mmio.len = bytes;
314 run->mmio.is_write = 1;
315 vcpu->mmio_needed = 1;
316 vcpu->mmio_is_write = 1;
317
318 /* Store the value at the lowest bytes in 'data'. */
319 if (is_bigendian) {
320 switch (bytes) {
321 case 4: *(u32 *)data = val; break;
322 case 2: *(u16 *)data = val; break;
323 case 1: *(u8 *)data = val; break;
324 }
325 } else {
326 /* Store LE value into 'data'. */
327 switch (bytes) {
328 case 4: st_le32(data, val); break;
329 case 2: st_le16(data, val); break;
330 case 1: *(u8 *)data = val; break;
331 }
332 }
333
334 return EMULATE_DO_MMIO;
335}
336
337int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
338{
339 int r;
340 sigset_t sigsaved;
341
342 if (vcpu->sigset_active)
343 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
344
345 if (vcpu->mmio_needed) {
346 if (!vcpu->mmio_is_write)
347 kvmppc_complete_mmio_load(vcpu, run);
348 vcpu->mmio_needed = 0;
349 } else if (vcpu->arch.dcr_needed) {
350 if (!vcpu->arch.dcr_is_write)
351 kvmppc_complete_dcr_load(vcpu, run);
352 vcpu->arch.dcr_needed = 0;
353 }
354
355 kvmppc_check_and_deliver_interrupts(vcpu);
356
357 local_irq_disable();
358 kvm_guest_enter();
359 r = __kvmppc_vcpu_run(run, vcpu);
360 kvm_guest_exit();
361 local_irq_enable();
362
363 if (vcpu->sigset_active)
364 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
365
366 return r;
367}
368
369int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
370{
371 kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_EXTERNAL);
372 return 0;
373}
374
375int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
376 struct kvm_mp_state *mp_state)
377{
378 return -EINVAL;
379}
380
381int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
382 struct kvm_mp_state *mp_state)
383{
384 return -EINVAL;
385}
386
387long kvm_arch_vcpu_ioctl(struct file *filp,
388 unsigned int ioctl, unsigned long arg)
389{
390 struct kvm_vcpu *vcpu = filp->private_data;
391 void __user *argp = (void __user *)arg;
392 long r;
393
394 switch (ioctl) {
395 case KVM_INTERRUPT: {
396 struct kvm_interrupt irq;
397 r = -EFAULT;
398 if (copy_from_user(&irq, argp, sizeof(irq)))
399 goto out;
400 r = kvm_vcpu_ioctl_interrupt(vcpu, &irq);
401 break;
402 }
403 default:
404 r = -EINVAL;
405 }
406
407out:
408 return r;
409}
410
411int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
412{
413 return -ENOTSUPP;
414}
415
416long kvm_arch_vm_ioctl(struct file *filp,
417 unsigned int ioctl, unsigned long arg)
418{
419 long r;
420
421 switch (ioctl) {
422 default:
423 r = -EINVAL;
424 }
425
426 return r;
427}
428
429int kvm_arch_init(void *opaque)
430{
431 return 0;
432}
433
434void kvm_arch_exit(void)
435{
436}
diff --git a/include/asm-powerpc/kvm.h b/include/asm-powerpc/kvm.h
index d1b530fbf8dd..f993e4198d5c 100644
--- a/include/asm-powerpc/kvm.h
+++ b/include/asm-powerpc/kvm.h
@@ -1,6 +1,55 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
1#ifndef __LINUX_KVM_POWERPC_H 20#ifndef __LINUX_KVM_POWERPC_H
2#define __LINUX_KVM_POWERPC_H 21#define __LINUX_KVM_POWERPC_H
3 22
4/* powerpc does not support KVM */ 23#include <asm/types.h>
24
25struct kvm_regs {
26 __u64 pc;
27 __u64 cr;
28 __u64 ctr;
29 __u64 lr;
30 __u64 xer;
31 __u64 msr;
32 __u64 srr0;
33 __u64 srr1;
34 __u64 pid;
35
36 __u64 sprg0;
37 __u64 sprg1;
38 __u64 sprg2;
39 __u64 sprg3;
40 __u64 sprg4;
41 __u64 sprg5;
42 __u64 sprg6;
43 __u64 sprg7;
44
45 __u64 gpr[32];
46};
47
48struct kvm_sregs {
49};
50
51struct kvm_fpu {
52 __u64 fpr[32];
53};
5 54
6#endif 55#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/include/asm-powerpc/kvm_asm.h b/include/asm-powerpc/kvm_asm.h
new file mode 100644
index 000000000000..2197764796d9
--- /dev/null
+++ b/include/asm-powerpc/kvm_asm.h
@@ -0,0 +1,55 @@
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 IBM Corp. 2008
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#ifndef __POWERPC_KVM_ASM_H__
21#define __POWERPC_KVM_ASM_H__
22
23/* IVPR must be 64KiB-aligned. */
24#define VCPU_SIZE_ORDER 4
25#define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12)
26#define VCPU_TLB_PGSZ PPC44x_TLB_64K
27#define VCPU_SIZE_BYTES (1<<VCPU_SIZE_LOG)
28
29#define BOOKE_INTERRUPT_CRITICAL 0
30#define BOOKE_INTERRUPT_MACHINE_CHECK 1
31#define BOOKE_INTERRUPT_DATA_STORAGE 2
32#define BOOKE_INTERRUPT_INST_STORAGE 3
33#define BOOKE_INTERRUPT_EXTERNAL 4
34#define BOOKE_INTERRUPT_ALIGNMENT 5
35#define BOOKE_INTERRUPT_PROGRAM 6
36#define BOOKE_INTERRUPT_FP_UNAVAIL 7
37#define BOOKE_INTERRUPT_SYSCALL 8
38#define BOOKE_INTERRUPT_AP_UNAVAIL 9
39#define BOOKE_INTERRUPT_DECREMENTER 10
40#define BOOKE_INTERRUPT_FIT 11
41#define BOOKE_INTERRUPT_WATCHDOG 12
42#define BOOKE_INTERRUPT_DTLB_MISS 13
43#define BOOKE_INTERRUPT_ITLB_MISS 14
44#define BOOKE_INTERRUPT_DEBUG 15
45#define BOOKE_MAX_INTERRUPT 15
46
47#define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */
48#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
49
50#define RESUME_GUEST 0
51#define RESUME_GUEST_NV RESUME_FLAG_NV
52#define RESUME_HOST RESUME_FLAG_HOST
53#define RESUME_HOST_NV (RESUME_FLAG_HOST|RESUME_FLAG_NV)
54
55#endif /* __POWERPC_KVM_ASM_H__ */
diff --git a/include/asm-powerpc/kvm_host.h b/include/asm-powerpc/kvm_host.h
new file mode 100644
index 000000000000..04ffbb8e0a35
--- /dev/null
+++ b/include/asm-powerpc/kvm_host.h
@@ -0,0 +1,152 @@
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#ifndef __POWERPC_KVM_HOST_H__
21#define __POWERPC_KVM_HOST_H__
22
23#include <linux/mutex.h>
24#include <linux/timer.h>
25#include <linux/types.h>
26#include <linux/kvm_types.h>
27#include <asm/kvm_asm.h>
28
29#define KVM_MAX_VCPUS 1
30#define KVM_MEMORY_SLOTS 32
31/* memory slots that does not exposed to userspace */
32#define KVM_PRIVATE_MEM_SLOTS 4
33
34/* We don't currently support large pages. */
35#define KVM_PAGES_PER_HPAGE (1<<31)
36
37struct kvm;
38struct kvm_run;
39struct kvm_vcpu;
40
41struct kvm_vm_stat {
42 u32 remote_tlb_flush;
43};
44
45struct kvm_vcpu_stat {
46 u32 sum_exits;
47 u32 mmio_exits;
48 u32 dcr_exits;
49 u32 signal_exits;
50 u32 light_exits;
51 /* Account for special types of light exits: */
52 u32 itlb_real_miss_exits;
53 u32 itlb_virt_miss_exits;
54 u32 dtlb_real_miss_exits;
55 u32 dtlb_virt_miss_exits;
56 u32 syscall_exits;
57 u32 isi_exits;
58 u32 dsi_exits;
59 u32 emulated_inst_exits;
60 u32 dec_exits;
61 u32 ext_intr_exits;
62};
63
64struct tlbe {
65 u32 tid; /* Only the low 8 bits are used. */
66 u32 word0;
67 u32 word1;
68 u32 word2;
69};
70
71struct kvm_arch {
72};
73
74struct kvm_vcpu_arch {
75 /* Unmodified copy of the guest's TLB. */
76 struct tlbe guest_tlb[PPC44x_TLB_SIZE];
77 /* TLB that's actually used when the guest is running. */
78 struct tlbe shadow_tlb[PPC44x_TLB_SIZE];
79 /* Pages which are referenced in the shadow TLB. */
80 struct page *shadow_pages[PPC44x_TLB_SIZE];
81 /* Copy of the host's TLB. */
82 struct tlbe host_tlb[PPC44x_TLB_SIZE];
83
84 u32 host_stack;
85 u32 host_pid;
86
87 u64 fpr[32];
88 u32 gpr[32];
89
90 u32 pc;
91 u32 cr;
92 u32 ctr;
93 u32 lr;
94 u32 xer;
95
96 u32 msr;
97 u32 mmucr;
98 u32 sprg0;
99 u32 sprg1;
100 u32 sprg2;
101 u32 sprg3;
102 u32 sprg4;
103 u32 sprg5;
104 u32 sprg6;
105 u32 sprg7;
106 u32 srr0;
107 u32 srr1;
108 u32 csrr0;
109 u32 csrr1;
110 u32 dsrr0;
111 u32 dsrr1;
112 u32 dear;
113 u32 esr;
114 u32 dec;
115 u32 decar;
116 u32 tbl;
117 u32 tbu;
118 u32 tcr;
119 u32 tsr;
120 u32 ivor[16];
121 u32 ivpr;
122 u32 pir;
123 u32 pid;
124 u32 pvr;
125 u32 ccr0;
126 u32 ccr1;
127 u32 dbcr0;
128 u32 dbcr1;
129
130 u32 last_inst;
131 u32 fault_dear;
132 u32 fault_esr;
133 gpa_t paddr_accessed;
134
135 u8 io_gpr; /* GPR used as IO source/target */
136 u8 mmio_is_bigendian;
137 u8 dcr_needed;
138 u8 dcr_is_write;
139
140 u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */
141
142 struct timer_list dec_timer;
143 unsigned long pending_exceptions;
144};
145
146struct kvm_guest_debug {
147 int enabled;
148 unsigned long bp[4];
149 int singlestep;
150};
151
152#endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h
new file mode 100644
index 000000000000..2d48f6a63d0b
--- /dev/null
+++ b/include/asm-powerpc/kvm_para.h
@@ -0,0 +1,37 @@
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 IBM Corp. 2008
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#ifndef __POWERPC_KVM_PARA_H__
21#define __POWERPC_KVM_PARA_H__
22
23#ifdef __KERNEL__
24
25static inline int kvm_para_available(void)
26{
27 return 0;
28}
29
30static inline unsigned int kvm_arch_para_features(void)
31{
32 return 0;
33}
34
35#endif /* __KERNEL__ */
36
37#endif /* __POWERPC_KVM_PARA_H__ */
diff --git a/include/asm-powerpc/kvm_ppc.h b/include/asm-powerpc/kvm_ppc.h
new file mode 100644
index 000000000000..7ac820308a7e
--- /dev/null
+++ b/include/asm-powerpc/kvm_ppc.h
@@ -0,0 +1,88 @@
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 IBM Corp. 2008
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#ifndef __POWERPC_KVM_PPC_H__
21#define __POWERPC_KVM_PPC_H__
22
23/* This file exists just so we can dereference kvm_vcpu, avoiding nested header
24 * dependencies. */
25
26#include <linux/mutex.h>
27#include <linux/timer.h>
28#include <linux/types.h>
29#include <linux/kvm_types.h>
30#include <linux/kvm_host.h>
31
32struct kvm_tlb {
33 struct tlbe guest_tlb[PPC44x_TLB_SIZE];
34 struct tlbe shadow_tlb[PPC44x_TLB_SIZE];
35};
36
37enum emulation_result {
38 EMULATE_DONE, /* no further processing */
39 EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */
40 EMULATE_DO_DCR, /* kvm_run filled with DCR request */
41 EMULATE_FAIL, /* can't emulate this instruction */
42};
43
44extern const unsigned char exception_priority[];
45extern const unsigned char priority_exception[];
46
47extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
48extern char kvmppc_handlers_start[];
49extern unsigned long kvmppc_handler_len;
50
51extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
52extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
53 unsigned int rt, unsigned int bytes,
54 int is_bigendian);
55extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
56 u32 val, unsigned int bytes, int is_bigendian);
57
58extern int kvmppc_emulate_instruction(struct kvm_run *run,
59 struct kvm_vcpu *vcpu);
60
61extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn,
62 u64 asid, u32 flags);
63extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid);
64extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
65
66extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu);
67
68static inline void kvmppc_queue_exception(struct kvm_vcpu *vcpu, int exception)
69{
70 unsigned int priority = exception_priority[exception];
71 set_bit(priority, &vcpu->arch.pending_exceptions);
72}
73
74static inline void kvmppc_clear_exception(struct kvm_vcpu *vcpu, int exception)
75{
76 unsigned int priority = exception_priority[exception];
77 clear_bit(priority, &vcpu->arch.pending_exceptions);
78}
79
80static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
81{
82 if ((new_msr & MSR_PR) != (vcpu->arch.msr & MSR_PR))
83 kvmppc_mmu_priv_switch(vcpu, new_msr & MSR_PR);
84
85 vcpu->arch.msr = new_msr;
86}
87
88#endif /* __POWERPC_KVM_PPC_H__ */