diff options
-rw-r--r-- | arch/powerpc/include/asm/cputable.h | 6 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_fsl_booke.S | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 46 | ||||
-rw-r--r-- | arch/powerpc/kvm/Kconfig | 17 | ||||
-rw-r--r-- | arch/powerpc/kvm/Makefile | 11 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500.h | 13 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 24 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_tlb.c | 21 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500mc.c | 342 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 6 |
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 */ |
282 | struct kvm_create_spapr_tce { | 283 | struct 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 | ||
384 | BEGIN_FTR_SECTION | ||
385 | mfspr r11, SPRN_SRR1 | ||
386 | END_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 | ||
478 | BEGIN_FTR_SECTION | ||
479 | mfspr r11, SPRN_SRR1 | ||
480 | END_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 | ||
926 | skip_hv_ivors: | ||
886 | sync | 927 | sync |
887 | blr | 928 | blr |
929 | no_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 | ||
110 | config KVM_EXIT_TIMING | 110 | config 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 | ||
135 | config 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 | |||
135 | source drivers/vhost/Kconfig | 150 | source drivers/vhost/Kconfig |
136 | 151 | ||
137 | endif # VIRTUALIZATION | 152 | endif # 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 |
39 | kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs) | 39 | kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs) |
40 | 40 | ||
41 | kvm-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 | ||
49 | kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs) | ||
50 | |||
41 | kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \ | 51 | kvm-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 | ||
90 | obj-$(CONFIG_KVM_440) += kvm.o | 100 | obj-$(CONFIG_KVM_440) += kvm.o |
91 | obj-$(CONFIG_KVM_E500) += kvm.o | 101 | obj-$(CONFIG_KVM_E500) += kvm.o |
102 | obj-$(CONFIG_KVM_E500MC) += kvm.o | ||
92 | obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o | 103 | obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o |
93 | obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o | 104 | obj-$(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); |
275 | void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500); | 280 | void 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 | ||
278 | unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu, | 287 | unsigned 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 | ||
78 | static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode) | 82 | static 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 | ||
389 | static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, | 406 | static 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 | |||
29 | void 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 */ | ||
56 | void 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 | |||
90 | void 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 | |||
101 | void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid) | ||
102 | { | ||
103 | vcpu->arch.pid = pid; | ||
104 | } | ||
105 | |||
106 | void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | ||
107 | { | ||
108 | } | ||
109 | |||
110 | void 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 | |||
144 | void 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 | |||
166 | int 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 | |||
180 | int 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 | |||
198 | void 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 | |||
221 | int 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 | |||
254 | struct 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 | |||
284 | uninit_tlb: | ||
285 | kvmppc_e500_tlb_uninit(vcpu_e500); | ||
286 | uninit_vcpu: | ||
287 | kvm_vcpu_uninit(vcpu); | ||
288 | |||
289 | free_vcpu: | ||
290 | kmem_cache_free(kvm_vcpu_cache, vcpu_e500); | ||
291 | out: | ||
292 | return ERR_PTR(err); | ||
293 | } | ||
294 | |||
295 | void 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 | |||
305 | int 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 | |||
317 | void kvmppc_core_destroy_vm(struct kvm *kvm) | ||
318 | { | ||
319 | kvmppc_free_lpid(kvm->arch.lpid); | ||
320 | } | ||
321 | |||
322 | static 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 | |||
336 | static void __exit kvmppc_e500mc_exit(void) | ||
337 | { | ||
338 | kvmppc_booke_exit(); | ||
339 | } | ||
340 | |||
341 | module_init(kvmppc_e500mc_init); | ||
342 | module_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; |