diff options
| -rw-r--r-- | arch/powerpc/include/asm/kvm_book3s.h | 5 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_book3s_64.h | 12 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_book3s_asm.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/reg.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/tm.h | 4 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu_hv.c | 9 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_64_vio_hv.c | 28 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 159 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_hv_interrupts.S | 22 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_hv_rm_mmu.c | 6 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_hv_rmhandlers.S | 187 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_rtas.c | 7 |
13 files changed, 377 insertions, 67 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 83851aabfdc8..bb1e38a23ac7 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
| @@ -304,6 +304,11 @@ static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | |||
| 304 | return vcpu->arch.fault_dar; | 304 | return vcpu->arch.fault_dar; |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | static inline bool is_kvmppc_resume_guest(int r) | ||
| 308 | { | ||
| 309 | return (r == RESUME_GUEST || r == RESUME_GUEST_NV); | ||
| 310 | } | ||
| 311 | |||
| 307 | /* Magic register values loaded into r3 and r4 before the 'sc' assembly | 312 | /* Magic register values loaded into r3 and r4 before the 'sc' assembly |
| 308 | * instruction for the OSI hypercalls */ | 313 | * instruction for the OSI hypercalls */ |
| 309 | #define OSI_SC_MAGIC_R3 0x113724FA | 314 | #define OSI_SC_MAGIC_R3 0x113724FA |
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index bf0fa8b0a883..51388befeddb 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h | |||
| @@ -289,6 +289,18 @@ static inline void note_hpte_modification(struct kvm *kvm, | |||
| 289 | if (atomic_read(&kvm->arch.hpte_mod_interest)) | 289 | if (atomic_read(&kvm->arch.hpte_mod_interest)) |
| 290 | rev->guest_rpte |= HPTE_GR_MODIFIED; | 290 | rev->guest_rpte |= HPTE_GR_MODIFIED; |
| 291 | } | 291 | } |
| 292 | |||
| 293 | /* | ||
| 294 | * Like kvm_memslots(), but for use in real mode when we can't do | ||
| 295 | * any RCU stuff (since the secondary threads are offline from the | ||
| 296 | * kernel's point of view), and we can't print anything. | ||
| 297 | * Thus we use rcu_dereference_raw() rather than rcu_dereference_check(). | ||
| 298 | */ | ||
| 299 | static inline struct kvm_memslots *kvm_memslots_raw(struct kvm *kvm) | ||
| 300 | { | ||
| 301 | return rcu_dereference_raw_notrace(kvm->memslots); | ||
| 302 | } | ||
| 303 | |||
| 292 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ | 304 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ |
| 293 | 305 | ||
| 294 | #endif /* __ASM_KVM_BOOK3S_64_H__ */ | 306 | #endif /* __ASM_KVM_BOOK3S_64_H__ */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index f3a91dc02c98..821725c1bf46 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h | |||
| @@ -94,7 +94,7 @@ struct kvmppc_host_state { | |||
| 94 | unsigned long xics_phys; | 94 | unsigned long xics_phys; |
| 95 | u32 saved_xirr; | 95 | u32 saved_xirr; |
| 96 | u64 dabr; | 96 | u64 dabr; |
| 97 | u64 host_mmcr[3]; | 97 | u64 host_mmcr[7]; /* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */ |
| 98 | u32 host_pmc[8]; | 98 | u32 host_pmc[8]; |
| 99 | u64 host_purr; | 99 | u64 host_purr; |
| 100 | u64 host_spurr; | 100 | u64 host_spurr; |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index fcd53f0d34ba..4096f16502a9 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
| @@ -129,6 +129,8 @@ extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, | |||
| 129 | struct kvm_create_spapr_tce *args); | 129 | struct kvm_create_spapr_tce *args); |
| 130 | extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, | 130 | extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, |
| 131 | unsigned long ioba, unsigned long tce); | 131 | unsigned long ioba, unsigned long tce); |
| 132 | extern long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn, | ||
| 133 | unsigned long ioba); | ||
| 132 | extern struct kvm_rma_info *kvm_alloc_rma(void); | 134 | extern struct kvm_rma_info *kvm_alloc_rma(void); |
| 133 | extern void kvm_release_rma(struct kvm_rma_info *ri); | 135 | extern void kvm_release_rma(struct kvm_rma_info *ri); |
| 134 | extern struct page *kvm_alloc_hpt(unsigned long nr_pages); | 136 | extern struct page *kvm_alloc_hpt(unsigned long nr_pages); |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 90c06ec6eff5..ce17815b8b55 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
| @@ -213,6 +213,7 @@ | |||
| 213 | #define SPRN_ACOP 0x1F /* Available Coprocessor Register */ | 213 | #define SPRN_ACOP 0x1F /* Available Coprocessor Register */ |
| 214 | #define SPRN_TFIAR 0x81 /* Transaction Failure Inst Addr */ | 214 | #define SPRN_TFIAR 0x81 /* Transaction Failure Inst Addr */ |
| 215 | #define SPRN_TEXASR 0x82 /* Transaction EXception & Summary */ | 215 | #define SPRN_TEXASR 0x82 /* Transaction EXception & Summary */ |
| 216 | #define TEXASR_FS __MASK(63-36) /* Transaction Failure Summary */ | ||
| 216 | #define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */ | 217 | #define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */ |
| 217 | #define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */ | 218 | #define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */ |
| 218 | #define SPRN_CTRLF 0x088 | 219 | #define SPRN_CTRLF 0x088 |
diff --git a/arch/powerpc/include/asm/tm.h b/arch/powerpc/include/asm/tm.h index 0c9f8b74dd97..c22d704b6d41 100644 --- a/arch/powerpc/include/asm/tm.h +++ b/arch/powerpc/include/asm/tm.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | 7 | ||
| 8 | #include <uapi/asm/tm.h> | 8 | #include <uapi/asm/tm.h> |
| 9 | 9 | ||
| 10 | #ifndef __ASSEMBLY__ | ||
| 11 | |||
| 10 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 12 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
| 11 | extern void do_load_up_transact_fpu(struct thread_struct *thread); | 13 | extern void do_load_up_transact_fpu(struct thread_struct *thread); |
| 12 | extern void do_load_up_transact_altivec(struct thread_struct *thread); | 14 | extern void do_load_up_transact_altivec(struct thread_struct *thread); |
| @@ -21,3 +23,5 @@ extern void tm_recheckpoint(struct thread_struct *thread, | |||
| 21 | extern void tm_abort(uint8_t cause); | 23 | extern void tm_abort(uint8_t cause); |
| 22 | extern void tm_save_sprs(struct thread_struct *thread); | 24 | extern void tm_save_sprs(struct thread_struct *thread); |
| 23 | extern void tm_restore_sprs(struct thread_struct *thread); | 25 | extern void tm_restore_sprs(struct thread_struct *thread); |
| 26 | |||
| 27 | #endif /* __ASSEMBLY__ */ | ||
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 303ece75b8e4..fb25ebc0af0c 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
| @@ -262,7 +262,14 @@ int kvmppc_mmu_hv_init(void) | |||
| 262 | 262 | ||
| 263 | static void kvmppc_mmu_book3s_64_hv_reset_msr(struct kvm_vcpu *vcpu) | 263 | static void kvmppc_mmu_book3s_64_hv_reset_msr(struct kvm_vcpu *vcpu) |
| 264 | { | 264 | { |
| 265 | kvmppc_set_msr(vcpu, vcpu->arch.intr_msr); | 265 | unsigned long msr = vcpu->arch.intr_msr; |
| 266 | |||
| 267 | /* If transactional, change to suspend mode on IRQ delivery */ | ||
| 268 | if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr)) | ||
| 269 | msr |= MSR_TS_S; | ||
| 270 | else | ||
| 271 | msr |= vcpu->arch.shregs.msr & MSR_TS_MASK; | ||
| 272 | kvmppc_set_msr(vcpu, msr); | ||
| 266 | } | 273 | } |
| 267 | 274 | ||
| 268 | /* | 275 | /* |
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index 2c25f5412bdb..89e96b3e0039 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c | |||
| @@ -75,3 +75,31 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, | |||
| 75 | return H_TOO_HARD; | 75 | return H_TOO_HARD; |
| 76 | } | 76 | } |
| 77 | EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); | 77 | EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); |
| 78 | |||
| 79 | long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn, | ||
| 80 | unsigned long ioba) | ||
| 81 | { | ||
| 82 | struct kvm *kvm = vcpu->kvm; | ||
| 83 | struct kvmppc_spapr_tce_table *stt; | ||
| 84 | |||
| 85 | list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) { | ||
| 86 | if (stt->liobn == liobn) { | ||
| 87 | unsigned long idx = ioba >> SPAPR_TCE_SHIFT; | ||
| 88 | struct page *page; | ||
| 89 | u64 *tbl; | ||
| 90 | |||
| 91 | if (ioba >= stt->window_size) | ||
| 92 | return H_PARAMETER; | ||
| 93 | |||
| 94 | page = stt->pages[idx / TCES_PER_PAGE]; | ||
| 95 | tbl = (u64 *)page_address(page); | ||
| 96 | |||
| 97 | vcpu->arch.gpr[4] = tbl[idx % TCES_PER_PAGE]; | ||
| 98 | return H_SUCCESS; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | /* Didn't find the liobn, punt it to userspace */ | ||
| 103 | return H_TOO_HARD; | ||
| 104 | } | ||
| 105 | EXPORT_SYMBOL_GPL(kvmppc_h_get_tce); | ||
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 17fc9496b6ac..8227dba5af0f 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
| @@ -86,7 +86,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu) | |||
| 86 | 86 | ||
| 87 | /* CPU points to the first thread of the core */ | 87 | /* CPU points to the first thread of the core */ |
| 88 | if (cpu != me && cpu >= 0 && cpu < nr_cpu_ids) { | 88 | if (cpu != me && cpu >= 0 && cpu < nr_cpu_ids) { |
| 89 | #ifdef CONFIG_KVM_XICS | 89 | #ifdef CONFIG_PPC_ICP_NATIVE |
| 90 | int real_cpu = cpu + vcpu->arch.ptid; | 90 | int real_cpu = cpu + vcpu->arch.ptid; |
| 91 | if (paca[real_cpu].kvm_hstate.xics_phys) | 91 | if (paca[real_cpu].kvm_hstate.xics_phys) |
| 92 | xics_wake_cpu(real_cpu); | 92 | xics_wake_cp |
