aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 20:43:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 20:43:43 -0400
commit69def9f05dfce3281bb06599057e6b8097385d39 (patch)
tree7d826b22924268ddbfad101993b248996d40e2ec /arch/powerpc
parent353f6dd2dec992ddd34620a94b051b0f76227379 (diff)
parent8e616fc8d343bd7f0f0a0c22407fdcb77f6d22b1 (diff)
Merge branch 'kvm-updates/2.6.32' of git://git.kernel.org/pub/scm/virt/kvm/kvm
* 'kvm-updates/2.6.32' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (202 commits) MAINTAINERS: update KVM entry KVM: correct error-handling code KVM: fix compile warnings on s390 KVM: VMX: Check cpl before emulating debug register access KVM: fix misreporting of coalesced interrupts by kvm tracer KVM: x86: drop duplicate kvm_flush_remote_tlb calls KVM: VMX: call vmx_load_host_state() only if msr is cached KVM: VMX: Conditionally reload debug register 6 KVM: Use thread debug register storage instead of kvm specific data KVM guest: do not batch pte updates from interrupt context KVM: Fix coalesced interrupt reporting in IOAPIC KVM guest: fix bogus wallclock physical address calculation KVM: VMX: Fix cr8 exiting control clobbering by EPT KVM: Optimize kvm_mmu_unprotect_page_virt() for tdp KVM: Document KVM_CAP_IRQCHIP KVM: Protect update_cr8_intercept() when running without an apic KVM: VMX: Fix EPT with WP bit change during paging KVM: Use kvm_{read,write}_guest_virt() to read and write segment descriptors KVM: x86 emulator: Add adc and sbb missing decoder flags KVM: Add missing #include ...
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_host.h4
-rw-r--r--arch/powerpc/kvm/44x.c4
-rw-r--r--arch/powerpc/kvm/44x_tlb.c11
-rw-r--r--arch/powerpc/kvm/Kconfig14
-rw-r--r--arch/powerpc/kvm/Makefile4
-rw-r--r--arch/powerpc/kvm/booke.c2
-rw-r--r--arch/powerpc/kvm/e500.c7
-rw-r--r--arch/powerpc/kvm/e500_emulate.c3
-rw-r--r--arch/powerpc/kvm/e500_tlb.c26
-rw-r--r--arch/powerpc/kvm/e500_tlb.h6
-rw-r--r--arch/powerpc/kvm/emulate.c7
-rw-r--r--arch/powerpc/kvm/powerpc.c32
-rw-r--r--arch/powerpc/kvm/trace.h104
13 files changed, 158 insertions, 66 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index fddc3ed715fa..c9c930ed11d7 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -34,7 +34,8 @@
34#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 34#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
35 35
36/* We don't currently support large pages. */ 36/* We don't currently support large pages. */
37#define KVM_PAGES_PER_HPAGE (1UL << 31) 37#define KVM_NR_PAGE_SIZES 1
38#define KVM_PAGES_PER_HPAGE(x) (1UL<<31)
38 39
39struct kvm; 40struct kvm;
40struct kvm_run; 41struct kvm_run;
@@ -153,7 +154,6 @@ struct kvm_vcpu_arch {
153 u32 pid; 154 u32 pid;
154 u32 swap_pid; 155 u32 swap_pid;
155 156
156 u32 pvr;
157 u32 ccr0; 157 u32 ccr0;
158 u32 ccr1; 158 u32 ccr1;
159 u32 dbcr0; 159 u32 dbcr0;
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 0cef809cec21..f4d1b55aa70b 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -138,7 +138,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
138 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 138 kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
139} 139}
140 140
141static int kvmppc_44x_init(void) 141static int __init kvmppc_44x_init(void)
142{ 142{
143 int r; 143 int r;
144 144
@@ -149,7 +149,7 @@ static int kvmppc_44x_init(void)
149 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE); 149 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE);
150} 150}
151 151
152static void kvmppc_44x_exit(void) 152static void __exit kvmppc_44x_exit(void)
153{ 153{
154 kvmppc_booke_exit(); 154 kvmppc_booke_exit();
155} 155}
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 4a16f472cc18..ff3cb63b8117 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -30,6 +30,7 @@
30#include "timing.h" 30#include "timing.h"
31 31
32#include "44x_tlb.h" 32#include "44x_tlb.h"
33#include "trace.h"
33 34
34#ifndef PPC44x_TLBE_SIZE 35#ifndef PPC44x_TLBE_SIZE
35#define PPC44x_TLBE_SIZE PPC44x_TLB_4K 36#define PPC44x_TLBE_SIZE PPC44x_TLB_4K
@@ -263,7 +264,7 @@ static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x,
263 264
264 /* XXX set tlb_44x_index to stlb_index? */ 265 /* XXX set tlb_44x_index to stlb_index? */
265 266
266 KVMTRACE_1D(STLB_INVAL, &vcpu_44x->vcpu, stlb_index, handler); 267 trace_kvm_stlb_inval(stlb_index);
267} 268}
268 269
269void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) 270void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
@@ -365,8 +366,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
365 /* Insert shadow mapping into hardware TLB. */ 366 /* Insert shadow mapping into hardware TLB. */
366 kvmppc_44x_tlbe_set_modified(vcpu_44x, victim); 367 kvmppc_44x_tlbe_set_modified(vcpu_44x, victim);
367 kvmppc_44x_tlbwe(victim, &stlbe); 368 kvmppc_44x_tlbwe(victim, &stlbe);
368 KVMTRACE_5D(STLB_WRITE, vcpu, victim, stlbe.tid, stlbe.word0, stlbe.word1, 369 trace_kvm_stlb_write(victim, stlbe.tid, stlbe.word0, stlbe.word1,
369 stlbe.word2, handler); 370 stlbe.word2);
370} 371}
371 372
372/* For a particular guest TLB entry, invalidate the corresponding host TLB 373/* For a particular guest TLB entry, invalidate the corresponding host TLB
@@ -485,8 +486,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
485 kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); 486 kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
486 } 487 }
487 488
488 KVMTRACE_5D(GTLB_WRITE, vcpu, gtlb_index, tlbe->tid, tlbe->word0, 489 trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1,
489 tlbe->word1, tlbe->word2, handler); 490 tlbe->word2);
490 491
491 kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); 492 kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS);
492 return EMULATE_DONE; 493 return EMULATE_DONE;
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 5a152a52796f..c29926846613 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -2,8 +2,7 @@
2# KVM configuration 2# KVM configuration
3# 3#
4 4
5config HAVE_KVM_IRQCHIP 5source "virt/kvm/Kconfig"
6 bool
7 6
8menuconfig VIRTUALIZATION 7menuconfig VIRTUALIZATION
9 bool "Virtualization" 8 bool "Virtualization"
@@ -59,17 +58,6 @@ config KVM_E500
59 58
60 If unsure, say N. 59 If unsure, say N.
61 60
62config KVM_TRACE
63 bool "KVM trace support"
64 depends on KVM && MARKERS && SYSFS
65 select RELAY
66 select DEBUG_FS
67 default n
68 ---help---
69 This option allows reading a trace of kvm-related events through
70 relayfs. Note the ABI is not considered stable and will be
71 modified in future updates.
72
73source drivers/virtio/Kconfig 61source drivers/virtio/Kconfig
74 62
75endif # VIRTUALIZATION 63endif # VIRTUALIZATION
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 459c7ee580f7..37655fe19f2f 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -8,7 +8,9 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm
8 8
9common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) 9common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
10 10
11common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) 11CFLAGS_44x_tlb.o := -I.
12CFLAGS_e500_tlb.o := -I.
13CFLAGS_emulate.o := -I.
12 14
13kvm-objs := $(common-objs-y) powerpc.o emulate.o 15kvm-objs := $(common-objs-y) powerpc.o emulate.o
14obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o 16obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 642e4204cf25..e7bf4d029484 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -520,7 +520,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
520 return kvmppc_core_vcpu_translate(vcpu, tr); 520 return kvmppc_core_vcpu_translate(vcpu, tr);
521} 521}
522 522
523int kvmppc_booke_init(void) 523int __init kvmppc_booke_init(void)
524{ 524{
525 unsigned long ivor[16]; 525 unsigned long ivor[16];
526 unsigned long max_ivor = 0; 526 unsigned long max_ivor = 0;
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index d8067fd81cdd..64949eef43f1 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -60,9 +60,6 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
60 60
61 kvmppc_e500_tlb_setup(vcpu_e500); 61 kvmppc_e500_tlb_setup(vcpu_e500);
62 62
63 /* Use the same core vertion as host's */
64 vcpu->arch.pvr = mfspr(SPRN_PVR);
65
66 return 0; 63 return 0;
67} 64}
68 65
@@ -132,7 +129,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
132 kmem_cache_free(kvm_vcpu_cache, vcpu_e500); 129 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
133} 130}
134 131
135static int kvmppc_e500_init(void) 132static int __init kvmppc_e500_init(void)
136{ 133{
137 int r, i; 134 int r, i;
138 unsigned long ivor[3]; 135 unsigned long ivor[3];
@@ -160,7 +157,7 @@ static int kvmppc_e500_init(void)
160 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); 157 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
161} 158}
162 159
163static void kvmppc_e500_exit(void) 160static void __init kvmppc_e500_exit(void)
164{ 161{
165 kvmppc_booke_exit(); 162 kvmppc_booke_exit();
166} 163}
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 3f760414b9f8..be95b8d8e3b7 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -180,6 +180,9 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
180 case SPRN_MMUCSR0: 180 case SPRN_MMUCSR0:
181 vcpu->arch.gpr[rt] = 0; break; 181 vcpu->arch.gpr[rt] = 0; break;
182 182
183 case SPRN_MMUCFG:
184 vcpu->arch.gpr[rt] = mfspr(SPRN_MMUCFG); break;
185
183 /* extra exceptions */ 186 /* extra exceptions */
184 case SPRN_IVOR32: 187 case SPRN_IVOR32:
185 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; 188 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 0e773fc2d5e4..fb1e1dc11ba5 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -22,6 +22,7 @@
22 22
23#include "../mm/mmu_decl.h" 23#include "../mm/mmu_decl.h"
24#include "e500_tlb.h" 24#include "e500_tlb.h"
25#include "trace.h"
25 26
26#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1) 27#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
27 28
@@ -224,9 +225,8 @@ static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
224 225
225 kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel); 226 kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
226 stlbe->mas1 = 0; 227 stlbe->mas1 = 0;
227 KVMTRACE_5D(STLB_INVAL, &vcpu_e500->vcpu, index_of(tlbsel, esel), 228 trace_kvm_stlb_inval(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
228 stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7, 229 stlbe->mas3, stlbe->mas7);
229 handler);
230} 230}
231 231
232static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, 232static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
@@ -269,7 +269,7 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
269 tlbsel = (vcpu_e500->mas4 >> 28) & 0x1; 269 tlbsel = (vcpu_e500->mas4 >> 28) & 0x1;
270 victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0; 270 victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
271 pidsel = (vcpu_e500->mas4 >> 16) & 0xf; 271 pidsel = (vcpu_e500->mas4 >> 16) & 0xf;
272 tsized = (vcpu_e500->mas4 >> 8) & 0xf; 272 tsized = (vcpu_e500->mas4 >> 7) & 0x1f;
273 273
274 vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim) 274 vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
275 | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]); 275 | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
@@ -309,7 +309,7 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
309 vcpu_e500->shadow_pages[tlbsel][esel] = new_page; 309 vcpu_e500->shadow_pages[tlbsel][esel] = new_page;
310 310
311 /* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */ 311 /* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */
312 stlbe->mas1 = MAS1_TSIZE(BOOKE_PAGESZ_4K) 312 stlbe->mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K)
313 | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID; 313 | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID;
314 stlbe->mas2 = (gvaddr & MAS2_EPN) 314 stlbe->mas2 = (gvaddr & MAS2_EPN)
315 | e500_shadow_mas2_attrib(gtlbe->mas2, 315 | e500_shadow_mas2_attrib(gtlbe->mas2,
@@ -319,9 +319,8 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
319 vcpu_e500->vcpu.arch.msr & MSR_PR); 319 vcpu_e500->vcpu.arch.msr & MSR_PR);
320 stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN; 320 stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN;
321 321
322 KVMTRACE_5D(STLB_WRITE, &vcpu_e500->vcpu, index_of(tlbsel, esel), 322 trace_kvm_stlb_write(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
323 stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7, 323 stlbe->mas3, stlbe->mas7);
324 handler);
325} 324}
326 325
327/* XXX only map the one-one case, for now use TLB0 */ 326/* XXX only map the one-one case, for now use TLB0 */
@@ -535,9 +534,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
535 gtlbe->mas3 = vcpu_e500->mas3; 534 gtlbe->mas3 = vcpu_e500->mas3;
536 gtlbe->mas7 = vcpu_e500->mas7; 535 gtlbe->mas7 = vcpu_e500->mas7;
537 536
538 KVMTRACE_5D(GTLB_WRITE, vcpu, vcpu_e500->mas0, 537 trace_kvm_gtlb_write(vcpu_e500->mas0, gtlbe->mas1, gtlbe->mas2,
539 gtlbe->mas1, gtlbe->mas2, gtlbe->mas3, gtlbe->mas7, 538 gtlbe->mas3, gtlbe->mas7);
540 handler);
541 539
542 /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ 540 /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
543 if (tlbe_is_host_safe(vcpu, gtlbe)) { 541 if (tlbe_is_host_safe(vcpu, gtlbe)) {
@@ -545,7 +543,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
545 case 0: 543 case 0:
546 /* TLB0 */ 544 /* TLB0 */
547 gtlbe->mas1 &= ~MAS1_TSIZE(~0); 545 gtlbe->mas1 &= ~MAS1_TSIZE(~0);
548 gtlbe->mas1 |= MAS1_TSIZE(BOOKE_PAGESZ_4K); 546 gtlbe->mas1 |= MAS1_TSIZE(BOOK3E_PAGESZ_4K);
549 547
550 stlbsel = 0; 548 stlbsel = 0;
551 sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel); 549 sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel);
@@ -679,14 +677,14 @@ void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
679 677
680 /* Insert large initial mapping for guest. */ 678 /* Insert large initial mapping for guest. */
681 tlbe = &vcpu_e500->guest_tlb[1][0]; 679 tlbe = &vcpu_e500->guest_tlb[1][0];
682 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_256M); 680 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_256M);
683 tlbe->mas2 = 0; 681 tlbe->mas2 = 0;
684 tlbe->mas3 = E500_TLB_SUPER_PERM_MASK; 682 tlbe->mas3 = E500_TLB_SUPER_PERM_MASK;
685 tlbe->mas7 = 0; 683 tlbe->mas7 = 0;
686 684
687 /* 4K map for serial output. Used by kernel wrapper. */ 685 /* 4K map for serial output. Used by kernel wrapper. */
688 tlbe = &vcpu_e500->guest_tlb[1][1]; 686 tlbe = &vcpu_e500->guest_tlb[1][1];
689 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_4K); 687 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_4K);
690 tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G; 688 tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G;
691 tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK; 689 tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK;
692 tlbe->mas7 = 0; 690 tlbe->mas7 = 0;
diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h
index 45b064b76906..d28e3010a5e2 100644
--- a/arch/powerpc/kvm/e500_tlb.h
+++ b/arch/powerpc/kvm/e500_tlb.h
@@ -16,7 +16,7 @@
16#define __KVM_E500_TLB_H__ 16#define __KVM_E500_TLB_H__
17 17
18#include <linux/kvm_host.h> 18#include <linux/kvm_host.h>
19#include <asm/mmu-fsl-booke.h> 19#include <asm/mmu-book3e.h>
20#include <asm/tlb.h> 20#include <asm/tlb.h>
21#include <asm/kvm_e500.h> 21#include <asm/kvm_e500.h>
22 22
@@ -59,7 +59,7 @@ extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *);
59/* TLB helper functions */ 59/* TLB helper functions */
60static inline unsigned int get_tlb_size(const struct tlbe *tlbe) 60static inline unsigned int get_tlb_size(const struct tlbe *tlbe)
61{ 61{
62 return (tlbe->mas1 >> 8) & 0xf; 62 return (tlbe->mas1 >> 7) & 0x1f;
63} 63}
64 64
65static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe) 65static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
@@ -70,7 +70,7 @@ static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
70static inline u64 get_tlb_bytes(const struct tlbe *tlbe) 70static inline u64 get_tlb_bytes(const struct tlbe *tlbe)
71{ 71{
72 unsigned int pgsize = get_tlb_size(tlbe); 72 unsigned int pgsize = get_tlb_size(tlbe);
73 return 1ULL << 10 << (pgsize << 1); 73 return 1ULL << 10 << pgsize;
74} 74}
75 75
76static inline gva_t get_tlb_end(const struct tlbe *tlbe) 76static inline gva_t get_tlb_end(const struct tlbe *tlbe)
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index a561d6e8da1c..7737146af3fb 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -29,6 +29,7 @@
29#include <asm/kvm_ppc.h> 29#include <asm/kvm_ppc.h>
30#include <asm/disassemble.h> 30#include <asm/disassemble.h>
31#include "timing.h" 31#include "timing.h"
32#include "trace.h"
32 33
33#define OP_TRAP 3 34#define OP_TRAP 3
34 35
@@ -187,7 +188,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
187 case SPRN_SRR1: 188 case SPRN_SRR1:
188 vcpu->arch.gpr[rt] = vcpu->arch.srr1; break; 189 vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
189 case SPRN_PVR: 190 case SPRN_PVR:
190 vcpu->arch.gpr[rt] = vcpu->arch.pvr; break; 191 vcpu->arch.gpr[rt] = mfspr(SPRN_PVR); break;
192 case SPRN_PIR:
193 vcpu->arch.gpr[rt] = mfspr(SPRN_PIR); break;
191 194
192 /* Note: mftb and TBRL/TBWL are user-accessible, so 195 /* Note: mftb and TBRL/TBWL are user-accessible, so
193 * the guest can always access the real TB anyways. 196 * the guest can always access the real TB anyways.
@@ -417,7 +420,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
417 } 420 }
418 } 421 }
419 422
420 KVMTRACE_3D(PPC_INSTR, vcpu, inst, (int)vcpu->arch.pc, emulated, entryexit); 423 trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated);
421 424
422 if (advance) 425 if (advance)
423 vcpu->arch.pc += 4; /* Advance past emulated instruction. */ 426 vcpu->arch.pc += 4; /* Advance past emulated instruction. */
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2cf915e51e7e..2a4551f78f60 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -31,25 +31,17 @@
31#include "timing.h" 31#include "timing.h"
32#include "../mm/mmu_decl.h" 32#include "../mm/mmu_decl.h"
33 33
34#define CREATE_TRACE_POINTS
35#include "trace.h"
36
34gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) 37gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
35{ 38{
36 return gfn; 39 return gfn;
37} 40}
38 41
39int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
40{
41 return !!(v->arch.pending_exceptions);
42}
43
44int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
45{
46 /* do real check here */
47 return 1;
48}
49
50int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) 42int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
51{ 43{
52 return !(v->arch.msr & MSR_WE); 44 return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions);
53} 45}
54 46
55 47
@@ -122,13 +114,17 @@ struct kvm *kvm_arch_create_vm(void)
122static void kvmppc_free_vcpus(struct kvm *kvm) 114static void kvmppc_free_vcpus(struct kvm *kvm)
123{ 115{
124 unsigned int i; 116 unsigned int i;
117 struct kvm_vcpu *vcpu;
125 118
126 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 119 kvm_for_each_vcpu(i, vcpu, kvm)
127 if (kvm->vcpus[i]) { 120 kvm_arch_vcpu_free(vcpu);
128 kvm_arch_vcpu_free(kvm->vcpus[i]); 121
129 kvm->vcpus[i] = NULL; 122 mutex_lock(&kvm->lock);
130 } 123 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
131 } 124 kvm->vcpus[i] = NULL;
125
126 atomic_set(&kvm->online_vcpus, 0);
127 mutex_unlock(&kvm->lock);
132} 128}
133 129
134void kvm_arch_sync_events(struct kvm *kvm) 130void kvm_arch_sync_events(struct kvm *kvm)
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h
new file mode 100644
index 000000000000..67f219de0455
--- /dev/null
+++ b/arch/powerpc/kvm/trace.h
@@ -0,0 +1,104 @@
1#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
2#define _TRACE_KVM_H
3
4#include <linux/tracepoint.h>
5
6#undef TRACE_SYSTEM
7#define TRACE_SYSTEM kvm
8#define TRACE_INCLUDE_PATH .
9#define TRACE_INCLUDE_FILE trace
10
11/*
12 * Tracepoint for guest mode entry.
13 */
14TRACE_EVENT(kvm_ppc_instr,
15 TP_PROTO(unsigned int inst, unsigned long pc, unsigned int emulate),
16 TP_ARGS(inst, pc, emulate),
17
18 TP_STRUCT__entry(
19 __field( unsigned int, inst )
20 __field( unsigned long, pc )
21 __field( unsigned int, emulate )
22 ),
23
24 TP_fast_assign(
25 __entry->inst = inst;
26 __entry->pc = pc;
27 __entry->emulate = emulate;
28 ),
29
30 TP_printk("inst %u pc 0x%lx emulate %u\n",
31 __entry->inst, __entry->pc, __entry->emulate)
32);
33
34TRACE_EVENT(kvm_stlb_inval,
35 TP_PROTO(unsigned int stlb_index),
36 TP_ARGS(stlb_index),
37
38 TP_STRUCT__entry(
39 __field( unsigned int, stlb_index )
40 ),
41
42 TP_fast_assign(
43 __entry->stlb_index = stlb_index;
44 ),
45
46 TP_printk("stlb_index %u", __entry->stlb_index)
47);
48
49TRACE_EVENT(kvm_stlb_write,
50 TP_PROTO(unsigned int victim, unsigned int tid, unsigned int word0,
51 unsigned int word1, unsigned int word2),
52 TP_ARGS(victim, tid, word0, word1, word2),
53
54 TP_STRUCT__entry(
55 __field( unsigned int, victim )
56 __field( unsigned int, tid )
57 __field( unsigned int, word0 )
58 __field( unsigned int, word1 )
59 __field( unsigned int, word2 )
60 ),
61
62 TP_fast_assign(
63 __entry->victim = victim;
64 __entry->tid = tid;
65 __entry->word0 = word0;
66 __entry->word1 = word1;
67 __entry->word2 = word2;
68 ),
69
70 TP_printk("victim %u tid %u w0 %u w1 %u w2 %u",
71 __entry->victim, __entry->tid, __entry->word0,
72 __entry->word1, __entry->word2)
73);
74
75TRACE_EVENT(kvm_gtlb_write,
76 TP_PROTO(unsigned int gtlb_index, unsigned int tid, unsigned int word0,
77 unsigned int word1, unsigned int word2),
78 TP_ARGS(gtlb_index, tid, word0, word1, word2),
79
80 TP_STRUCT__entry(
81 __field( unsigned int, gtlb_index )
82 __field( unsigned int, tid )
83 __field( unsigned int, word0 )
84 __field( unsigned int, word1 )
85 __field( unsigned int, word2 )
86 ),
87
88 TP_fast_assign(
89 __entry->gtlb_index = gtlb_index;
90 __entry->tid = tid;
91 __entry->word0 = word0;
92 __entry->word1 = word1;
93 __entry->word2 = word2;
94 ),
95
96 TP_printk("gtlb_index %u tid %u w0 %u w1 %u w2 %u",
97 __entry->gtlb_index, __entry->tid, __entry->word0,
98 __entry->word1, __entry->word2)
99);
100
101#endif /* _TRACE_KVM_H */
102
103/* This part must be outside protection */
104#include <trace/define_trace.h>