diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:43:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:43:43 -0400 |
commit | 69def9f05dfce3281bb06599057e6b8097385d39 (patch) | |
tree | 7d826b22924268ddbfad101993b248996d40e2ec /arch/powerpc | |
parent | 353f6dd2dec992ddd34620a94b051b0f76227379 (diff) | |
parent | 8e616fc8d343bd7f0f0a0c22407fdcb77f6d22b1 (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.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/44x.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/44x_tlb.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kvm/Kconfig | 14 | ||||
-rw-r--r-- | arch/powerpc/kvm/Makefile | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_tlb.c | 26 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_tlb.h | 6 | ||||
-rw-r--r-- | arch/powerpc/kvm/emulate.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 32 | ||||
-rw-r--r-- | arch/powerpc/kvm/trace.h | 104 |
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 | ||
39 | struct kvm; | 40 | struct kvm; |
40 | struct kvm_run; | 41 | struct 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 | ||
141 | static int kvmppc_44x_init(void) | 141 | static 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 | ||
152 | static void kvmppc_44x_exit(void) | 152 | static 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 | ||
269 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) | 270 | void 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 | ||
5 | config HAVE_KVM_IRQCHIP | 5 | source "virt/kvm/Kconfig" |
6 | bool | ||
7 | 6 | ||
8 | menuconfig VIRTUALIZATION | 7 | menuconfig 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 | ||
62 | config 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 | |||
73 | source drivers/virtio/Kconfig | 61 | source drivers/virtio/Kconfig |
74 | 62 | ||
75 | endif # VIRTUALIZATION | 63 | endif # 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 | ||
9 | common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) | 9 | common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) |
10 | 10 | ||
11 | common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) | 11 | CFLAGS_44x_tlb.o := -I. |
12 | CFLAGS_e500_tlb.o := -I. | ||
13 | CFLAGS_emulate.o := -I. | ||
12 | 14 | ||
13 | kvm-objs := $(common-objs-y) powerpc.o emulate.o | 15 | kvm-objs := $(common-objs-y) powerpc.o emulate.o |
14 | obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o | 16 | obj-$(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 | ||
523 | int kvmppc_booke_init(void) | 523 | int __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 | ||
135 | static int kvmppc_e500_init(void) | 132 | static 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 | ||
163 | static void kvmppc_e500_exit(void) | 160 | static 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 | ||
232 | static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, | 232 | static 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 */ |
60 | static inline unsigned int get_tlb_size(const struct tlbe *tlbe) | 60 | static 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 | ||
65 | static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe) | 65 | static 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) | |||
70 | static inline u64 get_tlb_bytes(const struct tlbe *tlbe) | 70 | static 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 | ||
76 | static inline gva_t get_tlb_end(const struct tlbe *tlbe) | 76 | static 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 | |||
34 | gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | 37 | gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) |
35 | { | 38 | { |
36 | return gfn; | 39 | return gfn; |
37 | } | 40 | } |
38 | 41 | ||
39 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v) | ||
40 | { | ||
41 | return !!(v->arch.pending_exceptions); | ||
42 | } | ||
43 | |||
44 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | ||
45 | { | ||
46 | /* do real check here */ | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) | 42 | int 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) | |||
122 | static void kvmppc_free_vcpus(struct kvm *kvm) | 114 | static 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 | ||
134 | void kvm_arch_sync_events(struct kvm *kvm) | 130 | void 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 | */ | ||
14 | TRACE_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 | |||
34 | TRACE_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 | |||
49 | TRACE_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 | |||
75 | TRACE_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> | ||