aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/cputable.h6
-rw-r--r--arch/powerpc/include/asm/kvm.h1
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S1
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S46
-rw-r--r--arch/powerpc/kvm/Kconfig17
-rw-r--r--arch/powerpc/kvm/Makefile11
-rw-r--r--arch/powerpc/kvm/e500.h13
-rw-r--r--arch/powerpc/kvm/e500_emulate.c24
-rw-r--r--arch/powerpc/kvm/e500_tlb.c21
-rw-r--r--arch/powerpc/kvm/e500mc.c342
-rw-r--r--arch/powerpc/kvm/powerpc.c6
11 files changed, 476 insertions, 12 deletions
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 7108a9c490a3..67c34afc6b5d 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -168,6 +168,7 @@ extern const char *powerpc_base_platform;
168#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000) 168#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000)
169#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000010000000) 169#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000010000000)
170#define CPU_FTR_INDEXED_DCR ASM_CONST(0x0000000020000000) 170#define CPU_FTR_INDEXED_DCR ASM_CONST(0x0000000020000000)
171#define CPU_FTR_EMB_HV ASM_CONST(0x0000000040000000)
171 172
172/* 173/*
173 * Add the 64-bit processor unique features in the top half of the word; 174 * Add the 64-bit processor unique features in the top half of the word;
@@ -386,11 +387,11 @@ extern const char *powerpc_base_platform;
386 CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) 387 CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
387#define CPU_FTRS_E500MC (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 388#define CPU_FTRS_E500MC (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
388 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 389 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
389 CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC) 390 CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
390#define CPU_FTRS_E5500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 391#define CPU_FTRS_E5500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
391 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 392 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
392 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 393 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
393 CPU_FTR_DEBUG_LVL_EXC) 394 CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
394#define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 395#define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
395 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 396 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
396 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 397 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
@@ -539,6 +540,7 @@ enum {
539#ifdef CONFIG_PPC_E500MC 540#ifdef CONFIG_PPC_E500MC
540 CPU_FTRS_E500MC & CPU_FTRS_E5500 & CPU_FTRS_E6500 & 541 CPU_FTRS_E500MC & CPU_FTRS_E5500 & CPU_FTRS_E6500 &
541#endif 542#endif
543 ~CPU_FTR_EMB_HV & /* can be removed at runtime */
542 CPU_FTRS_POSSIBLE, 544 CPU_FTRS_POSSIBLE,
543}; 545};
544#endif /* __powerpc64__ */ 546#endif /* __powerpc64__ */
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index b921c3f48928..1bea4d8ea6f4 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -277,6 +277,7 @@ struct kvm_sync_regs {
277#define KVM_CPU_E500V2 2 277#define KVM_CPU_E500V2 2
278#define KVM_CPU_3S_32 3 278#define KVM_CPU_3S_32 3
279#define KVM_CPU_3S_64 4 279#define KVM_CPU_3S_64 4
280#define KVM_CPU_E500MC 5
280 281
281/* for KVM_CAP_SPAPR_TCE */ 282/* for KVM_CAP_SPAPR_TCE */
282struct kvm_create_spapr_tce { 283struct kvm_create_spapr_tce {
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 8053db02b85e..69fdd2322a66 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -73,6 +73,7 @@ _GLOBAL(__setup_cpu_e500v2)
73 mtlr r4 73 mtlr r4
74 blr 74 blr
75_GLOBAL(__setup_cpu_e500mc) 75_GLOBAL(__setup_cpu_e500mc)
76 mr r5, r4
76 mflr r4 77 mflr r4
77 bl __e500_icache_setup 78 bl __e500_icache_setup
78 bl __e500_dcache_setup 79 bl __e500_dcache_setup
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 7c406dd9fea6..89c6d6f36785 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -380,10 +380,16 @@ interrupt_base:
380 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ 380 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
381 mfspr r10, SPRN_SPRG_THREAD 381 mfspr r10, SPRN_SPRG_THREAD
382 stw r11, THREAD_NORMSAVE(0)(r10) 382 stw r11, THREAD_NORMSAVE(0)(r10)
383#ifdef CONFIG_KVM_BOOKE_HV
384BEGIN_FTR_SECTION
385 mfspr r11, SPRN_SRR1
386END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
387#endif
383 stw r12, THREAD_NORMSAVE(1)(r10) 388 stw r12, THREAD_NORMSAVE(1)(r10)
384 stw r13, THREAD_NORMSAVE(2)(r10) 389 stw r13, THREAD_NORMSAVE(2)(r10)
385 mfcr r13 390 mfcr r13
386 stw r13, THREAD_NORMSAVE(3)(r10) 391 stw r13, THREAD_NORMSAVE(3)(r10)
392 DO_KVM BOOKE_INTERRUPT_DTLB_MISS SPRN_SRR1
387 mfspr r10, SPRN_DEAR /* Get faulting address */ 393 mfspr r10, SPRN_DEAR /* Get faulting address */
388 394
389 /* If we are faulting a kernel address, we have to use the 395 /* If we are faulting a kernel address, we have to use the
@@ -468,10 +474,16 @@ interrupt_base:
468 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ 474 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
469 mfspr r10, SPRN_SPRG_THREAD 475 mfspr r10, SPRN_SPRG_THREAD
470 stw r11, THREAD_NORMSAVE(0)(r10) 476 stw r11, THREAD_NORMSAVE(0)(r10)
477#ifdef CONFIG_KVM_BOOKE_HV
478BEGIN_FTR_SECTION
479 mfspr r11, SPRN_SRR1
480END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
481#endif
471 stw r12, THREAD_NORMSAVE(1)(r10) 482 stw r12, THREAD_NORMSAVE(1)(r10)
472 stw r13, THREAD_NORMSAVE(2)(r10) 483 stw r13, THREAD_NORMSAVE(2)(r10)
473 mfcr r13 484 mfcr r13
474 stw r13, THREAD_NORMSAVE(3)(r10) 485 stw r13, THREAD_NORMSAVE(3)(r10)
486 DO_KVM BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR1
475 mfspr r10, SPRN_SRR0 /* Get faulting address */ 487 mfspr r10, SPRN_SRR0 /* Get faulting address */
476 488
477 /* If we are faulting a kernel address, we have to use the 489 /* If we are faulting a kernel address, we have to use the
@@ -580,6 +592,17 @@ interrupt_base:
580 DEBUG_DEBUG_EXCEPTION 592 DEBUG_DEBUG_EXCEPTION
581 DEBUG_CRIT_EXCEPTION 593 DEBUG_CRIT_EXCEPTION
582 594
595 GUEST_DOORBELL_EXCEPTION
596
597 CRITICAL_EXCEPTION(0, GUEST_DBELL_CRIT, CriticalGuestDoorbell, \
598 unknown_exception)
599
600 /* Hypercall */
601 EXCEPTION(0, HV_SYSCALL, Hypercall, unknown_exception, EXC_XFER_EE)
602
603 /* Embedded Hypervisor Privilege */
604 EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_EE)
605
583/* 606/*
584 * Local functions 607 * Local functions
585 */ 608 */
@@ -883,8 +906,31 @@ _GLOBAL(__setup_e500mc_ivors)
883 mtspr SPRN_IVOR36,r3 906 mtspr SPRN_IVOR36,r3
884 li r3,CriticalDoorbell@l 907 li r3,CriticalDoorbell@l
885 mtspr SPRN_IVOR37,r3 908 mtspr SPRN_IVOR37,r3
909
910 /*
911 * We only want to touch IVOR38-41 if we're running on hardware
912 * that supports category E.HV. The architectural way to determine
913 * this is MMUCFG[LPIDSIZE].
914 */
915 mfspr r3, SPRN_MMUCFG
916 andis. r3, r3, MMUCFG_LPIDSIZE@h
917 beq no_hv
918 li r3,GuestDoorbell@l
919 mtspr SPRN_IVOR38,r3
920 li r3,CriticalGuestDoorbell@l
921 mtspr SPRN_IVOR39,r3
922 li r3,Hypercall@l
923 mtspr SPRN_IVOR40,r3
924 li r3,Ehvpriv@l
925 mtspr SPRN_IVOR41,r3
926skip_hv_ivors:
886 sync 927 sync
887 blr 928 blr
929no_hv:
930 lwz r3, CPU_SPEC_FEATURES(r5)
931 rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV
932 stw r3, CPU_SPEC_FEATURES(r5)
933 b skip_hv_ivors
888 934
889/* 935/*
890 * extern void giveup_altivec(struct task_struct *prev) 936 * extern void giveup_altivec(struct task_struct *prev)
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 2c33cd336434..58f6e6817924 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -109,7 +109,7 @@ config KVM_440
109 109
110config KVM_EXIT_TIMING 110config KVM_EXIT_TIMING
111 bool "Detailed exit timing" 111 bool "Detailed exit timing"
112 depends on KVM_440 || KVM_E500 112 depends on KVM_440 || KVM_E500 || KVM_E500MC
113 ---help--- 113 ---help---
114 Calculate elapsed time for every exit/enter cycle. A per-vcpu 114 Calculate elapsed time for every exit/enter cycle. A per-vcpu
115 report is available in debugfs kvm/vm#_vcpu#_timing. 115 report is available in debugfs kvm/vm#_vcpu#_timing.
@@ -132,6 +132,21 @@ config KVM_E500
132 132
133 If unsure, say N. 133 If unsure, say N.
134 134
135config KVM_E500MC
136 bool "KVM support for PowerPC E500MC/E5500 processors"
137 depends on EXPERIMENTAL && PPC_E500MC
138 select KVM
139 select KVM_MMIO
140 select KVM_BOOKE_HV
141 ---help---
142 Support running unmodified E500MC/E5500 (32-bit) guest kernels in
143 virtual machines on E500MC/E5500 host processors.
144
145 This module provides access to the hardware capabilities through
146 a character device node named /dev/kvm.
147
148 If unsure, say N.
149
135source drivers/vhost/Kconfig 150source drivers/vhost/Kconfig
136 151
137endif # VIRTUALIZATION 152endif # VIRTUALIZATION
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 3688aeecc4b2..62febd730ba4 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -38,6 +38,16 @@ kvm-e500-objs := \
38 e500_emulate.o 38 e500_emulate.o
39kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs) 39kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs)
40 40
41kvm-e500mc-objs := \
42 $(common-objs-y) \
43 booke.o \
44 booke_emulate.o \
45 bookehv_interrupts.o \
46 e500mc.o \
47 e500_tlb.o \
48 e500_emulate.o
49kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs)
50
41kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \ 51kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \
42 ../../../virt/kvm/coalesced_mmio.o \ 52 ../../../virt/kvm/coalesced_mmio.o \
43 fpu.o \ 53 fpu.o \
@@ -89,6 +99,7 @@ kvm-objs := $(kvm-objs-m) $(kvm-objs-y)
89 99
90obj-$(CONFIG_KVM_440) += kvm.o 100obj-$(CONFIG_KVM_440) += kvm.o
91obj-$(CONFIG_KVM_E500) += kvm.o 101obj-$(CONFIG_KVM_E500) += kvm.o
102obj-$(CONFIG_KVM_E500MC) += kvm.o
92obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o 103obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o
93obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o 104obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o
94 105
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index ce3f163f702e..31430852ba74 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -2,7 +2,9 @@
2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved. 2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Author: Yu Liu <yu.liu@freescale.com> 4 * Author: Yu Liu <yu.liu@freescale.com>
5 * Scott Wood <scottwood@freescale.com>
5 * Ashish Kalra <ashish.kalra@freescale.com> 6 * Ashish Kalra <ashish.kalra@freescale.com>
7 * Varun Sethi <varun.sethi@freescale.com>
6 * 8 *
7 * Description: 9 * Description:
8 * This file is based on arch/powerpc/kvm/44x_tlb.h and 10 * This file is based on arch/powerpc/kvm/44x_tlb.h and
@@ -100,6 +102,7 @@ static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
100 return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu); 102 return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
101} 103}
102 104
105
103/* This geometry is the legacy default -- can be overridden by userspace */ 106/* This geometry is the legacy default -- can be overridden by userspace */
104#define KVM_E500_TLB0_WAY_SIZE 128 107#define KVM_E500_TLB0_WAY_SIZE 128
105#define KVM_E500_TLB0_WAY_NUM 2 108#define KVM_E500_TLB0_WAY_NUM 2
@@ -250,10 +253,12 @@ static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
250 if (!get_tlb_v(tlbe)) 253 if (!get_tlb_v(tlbe))
251 return 0; 254 return 0;
252 255
256#ifndef CONFIG_KVM_BOOKE_HV
253 /* Does it match current guest AS? */ 257 /* Does it match current guest AS? */
254 /* XXX what about IS != DS? */ 258 /* XXX what about IS != DS? */
255 if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS)) 259 if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS))
256 return 0; 260 return 0;
261#endif
257 262
258 gpa = get_tlb_raddr(tlbe); 263 gpa = get_tlb_raddr(tlbe);
259 if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT)) 264 if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
@@ -274,7 +279,11 @@ void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
274 struct kvm_book3e_206_tlb_entry *gtlbe); 279 struct kvm_book3e_206_tlb_entry *gtlbe);
275void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500); 280void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500);
276 281
277#ifdef CONFIG_KVM_E500 282#ifdef CONFIG_KVM_BOOKE_HV
283#define kvmppc_e500_get_tlb_stid(vcpu, gtlbe) get_tlb_tid(gtlbe)
284#define get_tlbmiss_tid(vcpu) get_cur_pid(vcpu)
285#define get_tlb_sts(gtlbe) (gtlbe->mas1 & MAS1_TS)
286#else
278unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu, 287unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu,
279 struct kvm_book3e_206_tlb_entry *gtlbe); 288 struct kvm_book3e_206_tlb_entry *gtlbe);
280 289
@@ -288,6 +297,6 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
288 297
289/* Force TS=1 for all guest mappings. */ 298/* Force TS=1 for all guest mappings. */
290#define get_tlb_sts(gtlbe) (MAS1_TS) 299#define get_tlb_sts(gtlbe) (MAS1_TS)
291#endif /* CONFIG_KVM_E500 */ 300#endif /* !BOOKE_HV */
292 301
293#endif /* KVM_E500_H */ 302#endif /* KVM_E500_H */
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index af02c18fc798..98b6c1cd6b82 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -85,6 +85,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
85 ulong spr_val = kvmppc_get_gpr(vcpu, rs); 85 ulong spr_val = kvmppc_get_gpr(vcpu, rs);
86 86
87 switch (sprn) { 87 switch (sprn) {
88#ifndef CONFIG_KVM_BOOKE_HV
88 case SPRN_PID: 89 case SPRN_PID:
89 kvmppc_set_pid(vcpu, spr_val); 90 kvmppc_set_pid(vcpu, spr_val);
90 break; 91 break;
@@ -114,6 +115,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
114 vcpu->arch.shared->mas7_3 &= (u64)0xffffffff; 115 vcpu->arch.shared->mas7_3 &= (u64)0xffffffff;
115 vcpu->arch.shared->mas7_3 |= (u64)spr_val << 32; 116 vcpu->arch.shared->mas7_3 |= (u64)spr_val << 32;
116 break; 117 break;
118#endif
117 case SPRN_L1CSR0: 119 case SPRN_L1CSR0:
118 vcpu_e500->l1csr0 = spr_val; 120 vcpu_e500->l1csr0 = spr_val;
119 vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC); 121 vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC);
@@ -143,7 +145,14 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
143 case SPRN_IVOR35: 145 case SPRN_IVOR35:
144 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val; 146 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
145 break; 147 break;
146 148#ifdef CONFIG_KVM_BOOKE_HV
149 case SPRN_IVOR36:
150 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL] = spr_val;
151 break;
152 case SPRN_IVOR37:
153 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT] = spr_val;
154 break;
155#endif
147 default: 156 default:
148 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs); 157 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
149 } 158 }
@@ -155,9 +164,11 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
155{ 164{
156 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 165 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
157 int emulated = EMULATE_DONE; 166 int emulated = EMULATE_DONE;
158 unsigned long val;
159 167
160 switch (sprn) { 168 switch (sprn) {
169#ifndef CONFIG_KVM_BOOKE_HV
170 unsigned long val;
171
161 case SPRN_PID: 172 case SPRN_PID:
162 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break; 173 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break;
163 case SPRN_PID1: 174 case SPRN_PID1:
@@ -182,6 +193,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
182 val = vcpu->arch.shared->mas7_3 >> 32; 193 val = vcpu->arch.shared->mas7_3 >> 32;
183 kvmppc_set_gpr(vcpu, rt, val); 194 kvmppc_set_gpr(vcpu, rt, val);
184 break; 195 break;
196#endif
185 case SPRN_TLB0CFG: 197 case SPRN_TLB0CFG:
186 kvmppc_set_gpr(vcpu, rt, vcpu->arch.tlbcfg[0]); break; 198 kvmppc_set_gpr(vcpu, rt, vcpu->arch.tlbcfg[0]); break;
187 case SPRN_TLB1CFG: 199 case SPRN_TLB1CFG:
@@ -216,6 +228,14 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
216 case SPRN_IVOR35: 228 case SPRN_IVOR35:
217 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]); 229 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]);
218 break; 230 break;
231#ifdef CONFIG_KVM_BOOKE_HV
232 case SPRN_IVOR36:
233 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL]);
234 break;
235 case SPRN_IVOR37:
236 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT]);
237 break;
238#endif
219 default: 239 default:
220 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt); 240 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
221 } 241 }
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 6eb5d655bdb4..e232bb464a80 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -2,7 +2,9 @@
2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved. 2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Author: Yu Liu, yu.liu@freescale.com 4 * Author: Yu Liu, yu.liu@freescale.com
5 * Scott Wood, scottwood@freescale.com
5 * Ashish Kalra, ashish.kalra@freescale.com 6 * Ashish Kalra, ashish.kalra@freescale.com
7 * Varun Sethi, varun.sethi@freescale.com
6 * 8 *
7 * Description: 9 * Description:
8 * This file is based on arch/powerpc/kvm/44x_tlb.c, 10 * This file is based on arch/powerpc/kvm/44x_tlb.c,
@@ -64,6 +66,7 @@ static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
64 /* Mask off reserved bits. */ 66 /* Mask off reserved bits. */
65 mas3 &= MAS3_ATTRIB_MASK; 67 mas3 &= MAS3_ATTRIB_MASK;
66 68
69#ifndef CONFIG_KVM_BOOKE_HV
67 if (!usermode) { 70 if (!usermode) {
68 /* Guest is in supervisor mode, 71 /* Guest is in supervisor mode,
69 * so we need to translate guest 72 * so we need to translate guest
@@ -71,8 +74,9 @@ static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
71 mas3 &= ~E500_TLB_USER_PERM_MASK; 74 mas3 &= ~E500_TLB_USER_PERM_MASK;
72 mas3 |= (mas3 & E500_TLB_SUPER_PERM_MASK) << 1; 75 mas3 |= (mas3 & E500_TLB_SUPER_PERM_MASK) << 1;
73 } 76 }
74 77 mas3 |= E500_TLB_SUPER_PERM_MASK;
75 return mas3 | E500_TLB_SUPER_PERM_MASK; 78#endif
79 return mas3;
76} 80}
77 81
78static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode) 82static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode)
@@ -98,7 +102,16 @@ static inline void __write_host_tlbe(struct kvm_book3e_206_tlb_entry *stlbe,
98 mtspr(SPRN_MAS2, (unsigned long)stlbe->mas2); 102 mtspr(SPRN_MAS2, (unsigned long)stlbe->mas2);
99 mtspr(SPRN_MAS3, (u32)stlbe->mas7_3); 103 mtspr(SPRN_MAS3, (u32)stlbe->mas7_3);
100 mtspr(SPRN_MAS7, (u32)(stlbe->mas7_3 >> 32)); 104 mtspr(SPRN_MAS7, (u32)(stlbe->mas7_3 >> 32));
105#ifdef CONFIG_KVM_BOOKE_HV
106 mtspr(SPRN_MAS8, stlbe->mas8);
107#endif
101 asm volatile("isync; tlbwe" : : : "memory"); 108 asm volatile("isync; tlbwe" : : : "memory");
109
110#ifdef CONFIG_KVM_BOOKE_HV
111 /* Must clear mas8 for other host tlbwe's */
112 mtspr(SPRN_MAS8, 0);
113 isync();
114#endif
102 local_irq_restore(flags); 115 local_irq_restore(flags);
103 116
104 trace_kvm_booke206_stlb_write(mas0, stlbe->mas8, stlbe->mas1, 117 trace_kvm_booke206_stlb_write(mas0, stlbe->mas8, stlbe->mas1,
@@ -384,6 +397,10 @@ static inline void kvmppc_e500_setup_stlbe(
384 e500_shadow_mas2_attrib(gtlbe->mas2, pr); 397 e500_shadow_mas2_attrib(gtlbe->mas2, pr);
385 stlbe->mas7_3 = ((u64)pfn << PAGE_SHIFT) | 398 stlbe->mas7_3 = ((u64)pfn << PAGE_SHIFT) |
386 e500_shadow_mas3_attrib(gtlbe->mas7_3, pr); 399 e500_shadow_mas3_attrib(gtlbe->mas7_3, pr);
400
401#ifdef CONFIG_KVM_BOOKE_HV
402 stlbe->mas8 = MAS8_TGS | vcpu->kvm->arch.lpid;
403#endif
387} 404}
388 405
389static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, 406static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
new file mode 100644
index 000000000000..fe6c1de6b701
--- /dev/null
+++ b/arch/powerpc/kvm/e500mc.c
@@ -0,0 +1,342 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: Varun Sethi, <varun.sethi@freescale.com>
5 *
6 * Description:
7 * This file is derived from arch/powerpc/kvm/e500.c,
8 * by Yu Liu <yu.liu@freescale.com>.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License, version 2, as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kvm_host.h>
16#include <linux/slab.h>
17#include <linux/err.h>
18#include <linux/export.h>
19
20#include <asm/reg.h>
21#include <asm/cputable.h>
22#include <asm/tlbflush.h>
23#include <asm/kvm_ppc.h>
24#include <asm/dbell.h>
25
26#include "booke.h"
27#include "e500.h"
28
29void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type)
30{
31 enum ppc_dbell dbell_type;
32 unsigned long tag;
33
34 switch (type) {
35 case INT_CLASS_NONCRIT:
36 dbell_type = PPC_G_DBELL;
37 break;
38 case INT_CLASS_CRIT:
39 dbell_type = PPC_G_DBELL_CRIT;
40 break;
41 case INT_CLASS_MC:
42 dbell_type = PPC_G_DBELL_MC;
43 break;
44 default:
45 WARN_ONCE(1, "%s: unknown int type %d\n", __func__, type);
46 return;
47 }
48
49
50 tag = PPC_DBELL_LPID(vcpu->kvm->arch.lpid) | vcpu->vcpu_id;
51 mb();
52 ppc_msgsnd(dbell_type, 0, tag);
53}
54
55/* gtlbe must not be mapped by more than one host tlb entry */
56void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
57 struct kvm_book3e_206_tlb_entry *gtlbe)
58{
59 unsigned int tid, ts;
60 u32 val, eaddr, lpid;
61 unsigned long flags;
62
63 ts = get_tlb_ts(gtlbe);
64 tid = get_tlb_tid(gtlbe);
65 lpid = vcpu_e500->vcpu.kvm->arch.lpid;
66
67 /* We search the host TLB to invalidate its shadow TLB entry */
68 val = (tid << 16) | ts;
69 eaddr = get_tlb_eaddr(gtlbe);
70
71 local_irq_save(flags);
72
73 mtspr(SPRN_MAS6, val);
74 mtspr(SPRN_MAS5, MAS5_SGS | lpid);
75
76 asm volatile("tlbsx 0, %[eaddr]\n" : : [eaddr] "r" (eaddr));
77 val = mfspr(SPRN_MAS1);
78 if (val & MAS1_VALID) {
79 mtspr(SPRN_MAS1, val & ~MAS1_VALID);
80 asm volatile("tlbwe");
81 }
82 mtspr(SPRN_MAS5, 0);
83 /* NOTE: tlbsx also updates mas8, so clear it for host tlbwe */
84 mtspr(SPRN_MAS8, 0);
85 isync();
86
87 local_irq_restore(flags);
88}
89
90void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500)
91{
92 unsigned long flags;
93
94 local_irq_save(flags);
95 mtspr(SPRN_MAS5, MAS5_SGS | vcpu_e500->vcpu.kvm->arch.lpid);
96 asm volatile("tlbilxlpid");
97 mtspr(SPRN_MAS5, 0);
98 local_irq_restore(flags);
99}
100
101void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
102{
103 vcpu->arch.pid = pid;
104}
105
106void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
107{
108}
109
110void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
111{
112 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
113
114 kvmppc_booke_vcpu_load(vcpu, cpu);
115
116 mtspr(SPRN_LPID, vcpu->kvm->arch.lpid);
117 mtspr(SPRN_EPCR, vcpu->arch.shadow_epcr);
118 mtspr(SPRN_GPIR, vcpu->vcpu_id);
119 mtspr(SPRN_MSRP, vcpu->arch.shadow_msrp);
120 mtspr(SPRN_EPLC, vcpu->arch.eplc);
121 mtspr(SPRN_EPSC, vcpu->arch.epsc);
122
123 mtspr(SPRN_GIVPR, vcpu->arch.ivpr);
124 mtspr(SPRN_GIVOR2, vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]);
125 mtspr(SPRN_GIVOR8, vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]);
126 mtspr(SPRN_GSPRG0, (unsigned long)vcpu->arch.shared->sprg0);
127 mtspr(SPRN_GSPRG1, (unsigned long)vcpu->arch.shared->sprg1);
128 mtspr(SPRN_GSPRG2, (unsigned long)vcpu->arch.shared->sprg2);
129 mtspr(SPRN_GSPRG3, (unsigned long)vcpu->arch.shared->sprg3);
130
131 mtspr(SPRN_GSRR0, vcpu->arch.shared->srr0);
132 mtspr(SPRN_GSRR1, vcpu->arch.shared->srr1);
133
134 mtspr(SPRN_GEPR, vcpu->arch.epr);
135 mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
136 mtspr(SPRN_GESR, vcpu->arch.shared->esr);
137
138 if (vcpu->arch.oldpir != mfspr(SPRN_PIR))
139 kvmppc_e500_tlbil_all(vcpu_e500);
140
141 kvmppc_load_guest_fp(vcpu);
142}
143
144void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
145{
146 vcpu->arch.eplc = mfspr(SPRN_EPLC);
147 vcpu->arch.epsc = mfspr(SPRN_EPSC);
148
149 vcpu->arch.shared->sprg0 = mfspr(SPRN_GSPRG0);
150 vcpu->arch.shared->sprg1 = mfspr(SPRN_GSPRG1);
151 vcpu->arch.shared->sprg2 = mfspr(SPRN_GSPRG2);
152 vcpu->arch.shared->sprg3 = mfspr(SPRN_GSPRG3);
153
154 vcpu->arch.shared->srr0 = mfspr(SPRN_GSRR0);
155 vcpu->arch.shared->srr1 = mfspr(SPRN_GSRR1);
156
157 vcpu->arch.epr = mfspr(SPRN_GEPR);
158 vcpu->arch.shared->dar = mfspr(SPRN_GDEAR);
159 vcpu->arch.shared->esr = mfspr(SPRN_GESR);
160
161 vcpu->arch.oldpir = mfspr(SPRN_PIR);
162
163 kvmppc_booke_vcpu_put(vcpu);
164}
165
166int kvmppc_core_check_processor_compat(void)
167{
168 int r;
169
170 if (strcmp(cur_cpu_spec->cpu_name, "e500mc") == 0)
171 r = 0;
172 else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0)
173 r = 0;
174 else
175 r = -ENOTSUPP;
176
177 return r;
178}
179
180int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
181{
182 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
183
184 vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \
185 SPRN_EPCR_DUVD;
186 vcpu->arch.shadow_msrp = MSRP_UCLEP | MSRP_DEP | MSRP_PMMP;
187 vcpu->arch.eplc = EPC_EGS | (vcpu->kvm->arch.lpid << EPC_ELPID_SHIFT);
188 vcpu->arch.epsc = vcpu->arch.eplc;
189
190 vcpu->arch.pvr = mfspr(SPRN_PVR);
191 vcpu_e500->svr = mfspr(SPRN_SVR);
192
193 vcpu->arch.cpu_type = KVM_CPU_E500MC;
194
195 return 0;
196}
197
198void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
199{
200 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
201
202 sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_PM |
203 KVM_SREGS_E_PC;
204 sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
205
206 sregs->u.e.impl.fsl.features = 0;
207 sregs->u.e.impl.fsl.svr = vcpu_e500->svr;
208 sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
209 sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
210
211 kvmppc_get_sregs_e500_tlb(vcpu, sregs);
212
213 sregs->u.e.ivor_high[3] =
214 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
215 sregs->u.e.ivor_high[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL];
216 sregs->u.e.ivor_high[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT];
217
218 kvmppc_get_sregs_ivor(vcpu, sregs);
219}
220
221int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
222{
223 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
224 int ret;
225
226 if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
227 vcpu_e500->svr = sregs->u.e.impl.fsl.svr;
228 vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0;
229 vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar;
230 }
231
232 ret = kvmppc_set_sregs_e500_tlb(vcpu, sregs);
233 if (ret < 0)
234 return ret;
235
236 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
237 return 0;
238
239 if (sregs->u.e.features & KVM_SREGS_E_PM) {
240 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] =
241 sregs->u.e.ivor_high[3];
242 }
243
244 if (sregs->u.e.features & KVM_SREGS_E_PC) {
245 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL] =
246 sregs->u.e.ivor_high[4];
247 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT] =
248 sregs->u.e.ivor_high[5];
249 }
250
251 return kvmppc_set_sregs_ivor(vcpu, sregs);
252}
253
254struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
255{
256 struct kvmppc_vcpu_e500 *vcpu_e500;
257 struct kvm_vcpu *vcpu;
258 int err;
259
260 vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
261 if (!vcpu_e500) {
262 err = -ENOMEM;
263 goto out;
264 }
265 vcpu = &vcpu_e500->vcpu;
266
267 /* Invalid PIR value -- this LPID dosn't have valid state on any cpu */
268 vcpu->arch.oldpir = 0xffffffff;
269
270 err = kvm_vcpu_init(vcpu, kvm, id);
271 if (err)
272 goto free_vcpu;
273
274 err = kvmppc_e500_tlb_init(vcpu_e500);
275 if (err)
276 goto uninit_vcpu;
277
278 vcpu->arch.shared = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
279 if (!vcpu->arch.shared)
280 goto uninit_tlb;
281
282 return vcpu;
283
284uninit_tlb:
285 kvmppc_e500_tlb_uninit(vcpu_e500);
286uninit_vcpu:
287 kvm_vcpu_uninit(vcpu);
288
289free_vcpu:
290 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
291out:
292 return ERR_PTR(err);
293}
294
295void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
296{
297 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
298
299 free_page((unsigned long)vcpu->arch.shared);
300 kvmppc_e500_tlb_uninit(vcpu_e500);
301 kvm_vcpu_uninit(vcpu);
302 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
303}
304
305int kvmppc_core_init_vm(struct kvm *kvm)
306{
307 int lpid;
308
309 lpid = kvmppc_alloc_lpid();
310 if (lpid < 0)
311 return lpid;
312
313 kvm->arch.lpid = lpid;
314 return 0;
315}
316
317void kvmppc_core_destroy_vm(struct kvm *kvm)
318{
319 kvmppc_free_lpid(kvm->arch.lpid);
320}
321
322static int __init kvmppc_e500mc_init(void)
323{
324 int r;
325
326 r = kvmppc_booke_init();
327 if (r)
328 return r;
329
330 kvmppc_init_lpid(64);
331 kvmppc_claim_lpid(0); /* host */
332
333 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
334}
335
336static void __exit kvmppc_e500mc_exit(void)
337{
338 kvmppc_booke_exit();
339}
340
341module_init(kvmppc_e500mc_init);
342module_exit(kvmppc_e500mc_exit);
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 6a530e4b3e7c..14bf8d59bc2a 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -235,7 +235,7 @@ int kvm_dev_ioctl_check_extension(long ext)
235 case KVM_CAP_PPC_PAIRED_SINGLES: 235 case KVM_CAP_PPC_PAIRED_SINGLES:
236 case KVM_CAP_PPC_OSI: 236 case KVM_CAP_PPC_OSI:
237 case KVM_CAP_PPC_GET_PVINFO: 237 case KVM_CAP_PPC_GET_PVINFO:
238#ifdef CONFIG_KVM_E500 238#if defined(CONFIG_KVM_E500) || defined(CONFIG_KVM_E500MC)
239 case KVM_CAP_SW_TLB: 239 case KVM_CAP_SW_TLB:
240#endif 240#endif
241 r = 1; 241 r = 1;
@@ -629,7 +629,7 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
629 r = 0; 629 r = 0;
630 vcpu->arch.papr_enabled = true; 630 vcpu->arch.papr_enabled = true;
631 break; 631 break;
632#ifdef CONFIG_KVM_E500 632#if defined(CONFIG_KVM_E500) || defined(CONFIG_KVM_E500MC)
633 case KVM_CAP_SW_TLB: { 633 case KVM_CAP_SW_TLB: {
634 struct kvm_config_tlb cfg; 634 struct kvm_config_tlb cfg;
635 void __user *user_ptr = (void __user *)(uintptr_t)cap->args[0]; 635 void __user *user_ptr = (void __user *)(uintptr_t)cap->args[0];
@@ -706,7 +706,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
706 break; 706 break;
707 } 707 }
708 708
709#ifdef CONFIG_KVM_E500 709#if defined(CONFIG_KVM_E500) || defined(CONFIG_KVM_E500MC)
710 case KVM_DIRTY_TLB: { 710 case KVM_DIRTY_TLB: {
711 struct kvm_dirty_tlb dirty; 711 struct kvm_dirty_tlb dirty;
712 r = -EFAULT; 712 r = -EFAULT;