aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h5
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h12
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_asm.h2
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h2
-rw-r--r--arch/powerpc/include/asm/reg.h1
-rw-r--r--arch/powerpc/include/asm/tm.h4
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c9
-rw-r--r--arch/powerpc/kvm/book3s_64_vio_hv.c28
-rw-r--r--arch/powerpc/kvm/book3s_hv.c159
-rw-r--r--arch/powerpc/kvm/book3s_hv_interrupts.S22
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c6
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S187
-rw-r--r--arch/powerpc/kvm/book3s_rtas.c7
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
307static 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 */
299static 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);
130extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, 130extern 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);
132extern long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
133 unsigned long ioba);
132extern struct kvm_rma_info *kvm_alloc_rma(void); 134extern struct kvm_rma_info *kvm_alloc_rma(void);
133extern void kvm_release_rma(struct kvm_rma_info *ri); 135extern void kvm_release_rma(struct kvm_rma_info *ri);
134extern struct page *kvm_alloc_hpt(unsigned long nr_pages); 136extern 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
11extern void do_load_up_transact_fpu(struct thread_struct *thread); 13extern void do_load_up_transact_fpu(struct thread_struct *thread);
12extern void do_load_up_transact_altivec(struct thread_struct *thread); 14extern void do_load_up_transact_altivec(struct thread_struct *thread);
@@ -21,3 +23,5 @@ extern void tm_recheckpoint(struct thread_struct *thread,
21extern void tm_abort(uint8_t cause); 23extern void tm_abort(uint8_t cause);
22extern void tm_save_sprs(struct thread_struct *thread); 24extern void tm_save_sprs(struct thread_struct *thread);
23extern void tm_restore_sprs(struct thread_struct *thread); 25extern 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
263static void kvmppc_mmu_book3s_64_hv_reset_msr(struct kvm_vcpu *vcpu) 263static 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}
77EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); 77EXPORT_SYMBOL_GPL(kvmppc_h_put_tce);
78
79long 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}
105EXPORT_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