aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/asm-offsets.c3
-rw-r--r--arch/powerpc/kvm/book3s_hv.c51
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c16
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S22
4 files changed, 70 insertions, 22 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 0d07efbe3fa7..0034b6b3556a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -37,6 +37,7 @@
37#include <asm/thread_info.h> 37#include <asm/thread_info.h>
38#include <asm/rtas.h> 38#include <asm/rtas.h>
39#include <asm/vdso_datapage.h> 39#include <asm/vdso_datapage.h>
40#include <asm/dbell.h>
40#ifdef CONFIG_PPC64 41#ifdef CONFIG_PPC64
41#include <asm/paca.h> 42#include <asm/paca.h>
42#include <asm/lppaca.h> 43#include <asm/lppaca.h>
@@ -759,5 +760,7 @@ int main(void)
759 offsetof(struct paca_struct, subcore_sibling_mask)); 760 offsetof(struct paca_struct, subcore_sibling_mask));
760#endif 761#endif
761 762
763 DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
764
762 return 0; 765 return 0;
763} 766}
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index ea1600ff52b2..48d3c5d2ecc9 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -51,6 +51,7 @@
51#include <asm/hvcall.h> 51#include <asm/hvcall.h>
52#include <asm/switch_to.h> 52#include <asm/switch_to.h>
53#include <asm/smp.h> 53#include <asm/smp.h>
54#include <asm/dbell.h>
54#include <linux/gfp.h> 55#include <linux/gfp.h>
55#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
56#include <linux/highmem.h> 57#include <linux/highmem.h>
@@ -84,9 +85,35 @@ static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1);
84static void kvmppc_end_cede(struct kvm_vcpu *vcpu); 85static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
85static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); 86static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
86 87
88static bool kvmppc_ipi_thread(int cpu)
89{
90 /* On POWER8 for IPIs to threads in the same core, use msgsnd */
91 if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
92 preempt_disable();
93 if (cpu_first_thread_sibling(cpu) ==
94 cpu_first_thread_sibling(smp_processor_id())) {
95 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
96 msg |= cpu_thread_in_core(cpu);
97 smp_mb();
98 __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
99 preempt_enable();
100 return true;
101 }
102 preempt_enable();
103 }
104
105#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP)
106 if (cpu >= 0 && cpu < nr_cpu_ids && paca[cpu].kvm_hstate.xics_phys) {
107 xics_wake_cpu(cpu);
108 return true;
109 }
110#endif
111
112 return false;
113}
114
87static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu) 115static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
88{ 116{
89 int me;
90 int cpu = vcpu->cpu; 117 int cpu = vcpu->cpu;
91 wait_queue_head_t *wqp; 118 wait_queue_head_t *wqp;
92 119
@@ -96,20 +123,12 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
96 ++vcpu->stat.halt_wakeup; 123 ++vcpu->stat.halt_wakeup;
97 } 124 }
98 125
99 me = get_cpu(); 126 if (kvmppc_ipi_thread(cpu + vcpu->arch.ptid))
127 return;
100 128
101 /* CPU points to the first thread of the core */ 129 /* CPU points to the first thread of the core */
102 if (cpu != me && cpu >= 0 && cpu < nr_cpu_ids) { 130 if (cpu >= 0 && cpu < nr_cpu_ids && cpu_online(cpu))
103#ifdef CONFIG_PPC_ICP_NATIVE 131 smp_send_reschedule(cpu);
104 int real_cpu = cpu + vcpu->arch.ptid;
105 if (paca[real_cpu].kvm_hstate.xics_phys)
106 xics_wake_cpu(real_cpu);
107 else
108#endif
109 if (cpu_online(cpu))
110 smp_send_reschedule(cpu);
111 }
112 put_cpu();
113} 132}
114 133
115/* 134/*
@@ -1781,10 +1800,8 @@ static void kvmppc_start_thread(struct kvm_vcpu *vcpu)
1781 /* Order stores to hstate.kvm_vcore etc. before store to kvm_vcpu */ 1800 /* Order stores to hstate.kvm_vcore etc. before store to kvm_vcpu */
1782 smp_wmb(); 1801 smp_wmb();
1783 tpaca->kvm_hstate.kvm_vcpu = vcpu; 1802 tpaca->kvm_hstate.kvm_vcpu = vcpu;
1784#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP)
1785 if (cpu != smp_processor_id()) 1803 if (cpu != smp_processor_id())
1786 xics_wake_cpu(cpu); 1804 kvmppc_ipi_thread(cpu);
1787#endif
1788} 1805}
1789 1806
1790static void kvmppc_wait_for_nap(void) 1807static void kvmppc_wait_for_nap(void)
@@ -1933,7 +1950,7 @@ static void post_guest_process(struct kvmppc_vcore *vc)
1933 * Run a set of guest threads on a physical core. 1950 * Run a set of guest threads on a physical core.
1934 * Called with vc->lock held. 1951 * Called with vc->lock held.
1935 */ 1952 */
1936static void kvmppc_run_core(struct kvmppc_vcore *vc) 1953static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
1937{ 1954{
1938 struct kvm_vcpu *vcpu; 1955 struct kvm_vcpu *vcpu;
1939 int i; 1956 int i;
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index c42aa55b885f..ed2589d4593f 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -23,6 +23,8 @@
23#include <asm/kvm_book3s.h> 23#include <asm/kvm_book3s.h>
24#include <asm/archrandom.h> 24#include <asm/archrandom.h>
25#include <asm/xics.h> 25#include <asm/xics.h>
26#include <asm/dbell.h>
27#include <asm/cputhreads.h>
26 28
27#define KVM_CMA_CHUNK_ORDER 18 29#define KVM_CMA_CHUNK_ORDER 18
28 30
@@ -193,7 +195,7 @@ static inline void rm_writeb(unsigned long paddr, u8 val)
193} 195}
194 196
195/* 197/*
196 * Send an interrupt to another CPU. 198 * Send an interrupt or message to another CPU.
197 * This can only be called in real mode. 199 * This can only be called in real mode.
198 * The caller needs to include any barrier needed to order writes 200 * The caller needs to include any barrier needed to order writes
199 * to memory vs. the IPI/message. 201 * to memory vs. the IPI/message.
@@ -202,7 +204,17 @@ void kvmhv_rm_send_ipi(int cpu)
202{ 204{
203 unsigned long xics_phys; 205 unsigned long xics_phys;
204 206
205 /* Poke the target */ 207 /* On POWER8 for IPIs to threads in the same core, use msgsnd */
208 if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
209 cpu_first_thread_sibling(cpu) ==
210 cpu_first_thread_sibling(raw_smp_processor_id())) {
211 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
212 msg |= cpu_thread_in_core(cpu);
213 __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
214 return;
215 }
216
217 /* Else poke the target with an IPI */
206 xics_phys = paca[cpu].kvm_hstate.xics_phys; 218 xics_phys = paca[cpu].kvm_hstate.xics_phys;
207 rm_writeb(xics_phys + XICS_MFRR, IPI_PRIORITY); 219 rm_writeb(xics_phys + XICS_MFRR, IPI_PRIORITY);
208} 220}
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index fcf3a617cc8a..4d70df26c402 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1123,6 +1123,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
1123 cmpwi r12,BOOK3S_INTERRUPT_SYSCALL 1123 cmpwi r12,BOOK3S_INTERRUPT_SYSCALL
1124 beq hcall_try_real_mode 1124 beq hcall_try_real_mode
1125 1125
1126 /* Hypervisor doorbell - exit only if host IPI flag set */
1127 cmpwi r12, BOOK3S_INTERRUPT_H_DOORBELL
1128 bne 3f
1129 lbz r0, HSTATE_HOST_IPI(r13)
1130 beq 4f
1131 b guest_exit_cont
11323:
1126 /* External interrupt ? */ 1133 /* External interrupt ? */
1127 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL 1134 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
1128 bne+ guest_exit_cont 1135 bne+ guest_exit_cont
@@ -1135,7 +1142,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
1135 bgt guest_exit_cont 1142 bgt guest_exit_cont
1136 1143
1137 /* Check if any CPU is heading out to the host, if so head out too */ 1144 /* Check if any CPU is heading out to the host, if so head out too */
1138 ld r5, HSTATE_KVM_VCORE(r13) 11454: ld r5, HSTATE_KVM_VCORE(r13)
1139 lwz r0, VCORE_ENTRY_EXIT(r5) 1146 lwz r0, VCORE_ENTRY_EXIT(r5)
1140 cmpwi r0, 0x100 1147 cmpwi r0, 0x100
1141 mr r4, r9 1148 mr r4, r9
@@ -2148,7 +2155,7 @@ _GLOBAL(kvmppc_h_cede) /* r3 = vcpu pointer, r11 = msr, r13 = paca */
2148 /* 2155 /*
2149 * Take a nap until a decrementer or external or doobell interrupt 2156 * Take a nap until a decrementer or external or doobell interrupt
2150 * occurs, with PECE1 and PECE0 set in LPCR. 2157 * occurs, with PECE1 and PECE0 set in LPCR.
2151 * On POWER8, if we are ceding, also set PECEDP. 2158 * On POWER8, set PECEDH, and if we are ceding, also set PECEDP.
2152 * Also clear the runlatch bit before napping. 2159 * Also clear the runlatch bit before napping.
2153 */ 2160 */
2154kvm_do_nap: 2161kvm_do_nap:
@@ -2161,6 +2168,7 @@ kvm_do_nap:
2161 mfspr r5,SPRN_LPCR 2168 mfspr r5,SPRN_LPCR
2162 ori r5,r5,LPCR_PECE0 | LPCR_PECE1 2169 ori r5,r5,LPCR_PECE0 | LPCR_PECE1
2163BEGIN_FTR_SECTION 2170BEGIN_FTR_SECTION
2171 ori r5, r5, LPCR_PECEDH
2164 rlwimi r5, r3, 0, LPCR_PECEDP 2172 rlwimi r5, r3, 0, LPCR_PECEDP
2165END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) 2173END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
2166 mtspr SPRN_LPCR,r5 2174 mtspr SPRN_LPCR,r5
@@ -2299,7 +2307,7 @@ machine_check_realmode:
2299 * Returns (in r3): 2307 * Returns (in r3):
2300 * 0 if nothing needs to be done 2308 * 0 if nothing needs to be done
2301 * 1 if something happened that needs to be handled by the host 2309 * 1 if something happened that needs to be handled by the host
2302 * -1 if there was a guest wakeup (IPI) 2310 * -1 if there was a guest wakeup (IPI or msgsnd)
2303 * 2311 *
2304 * Also sets r12 to the interrupt vector for any interrupt that needs 2312 * Also sets r12 to the interrupt vector for any interrupt that needs
2305 * to be handled now by the host (0x500 for external interrupt), or zero. 2313 * to be handled now by the host (0x500 for external interrupt), or zero.
@@ -2330,7 +2338,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
2330 2338
2331 /* hypervisor doorbell */ 2339 /* hypervisor doorbell */
23323: li r12, BOOK3S_INTERRUPT_H_DOORBELL 23403: li r12, BOOK3S_INTERRUPT_H_DOORBELL
2341 /* see if it's a host IPI */
2333 li r3, 1 2342 li r3, 1
2343 lbz r0, HSTATE_HOST_IPI(r13)
2344 cmpwi r0, 0
2345 bnelr
2346 /* if not, clear it and return -1 */
2347 lis r6, (PPC_DBELL_SERVER << (63-36))@h
2348 PPC_MSGCLR(6)
2349 li r3, -1
2334 blr 2350 blr
2335 2351
2336/* 2352/*