forked from mirrors/linux
		
	KVM: PPC: Book3S HV: POWER9 does not require secondary thread management
POWER9 CPUs have independent MMU contexts per thread, so KVM does not need to quiesce secondary threads, so the hwthread_req/hwthread_state protocol does not have to be used. So patch it away on POWER9, and patch away the branch from the Linux idle wakeup to kvm_start_guest that is never used. Add a warning and error out of kvmppc_grab_hwthread in case it is ever called on POWER9. This avoids a hwsync in the idle wakeup path on POWER9. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Acked-by: Paul Mackerras <paulus@ozlabs.org> [mpe: Use WARN(...) instead of WARN_ON()/pr_err(...)] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
		
							parent
							
								
									94171b19c3
								
							
						
					
					
						commit
						94a04bc25a
					
				
					 4 changed files with 48 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -104,6 +104,10 @@ struct kvmppc_host_state {
 | 
			
		|||
	u8 napping;
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 | 
			
		||||
	/*
 | 
			
		||||
	 * hwthread_req/hwthread_state pair is used to pull sibling threads
 | 
			
		||||
	 * out of guest on pre-ISAv3.0B CPUs where threads share MMU.
 | 
			
		||||
	 */
 | 
			
		||||
	u8 hwthread_req;
 | 
			
		||||
	u8 hwthread_state;
 | 
			
		||||
	u8 host_ipi;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -242,13 +242,20 @@ enter_winkle:
 | 
			
		|||
/*
 | 
			
		||||
 * r3 - PSSCR value corresponding to the requested stop state.
 | 
			
		||||
 */
 | 
			
		||||
power_enter_stop:
 | 
			
		||||
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 | 
			
		||||
	/* Tell KVM we're entering idle */
 | 
			
		||||
power_enter_stop_kvm_rm:
 | 
			
		||||
	/*
 | 
			
		||||
	 * This is currently unused because POWER9 KVM does not have to
 | 
			
		||||
	 * gather secondary threads into sibling mode, but the code is
 | 
			
		||||
	 * here in case that function is required.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Tell KVM we're entering idle.
 | 
			
		||||
	 */
 | 
			
		||||
	li	r4,KVM_HWTHREAD_IN_IDLE
 | 
			
		||||
	/* DO THIS IN REAL MODE!  See comment above. */
 | 
			
		||||
	stb	r4,HSTATE_HWTHREAD_STATE(r13)
 | 
			
		||||
#endif
 | 
			
		||||
power_enter_stop:
 | 
			
		||||
/*
 | 
			
		||||
 * Check if we are executing the lite variant with ESL=EC=0
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -411,6 +418,18 @@ pnv_powersave_wakeup_mce:
 | 
			
		|||
 | 
			
		||||
	b	pnv_powersave_wakeup
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 | 
			
		||||
kvm_start_guest_check:
 | 
			
		||||
	li	r0,KVM_HWTHREAD_IN_KERNEL
 | 
			
		||||
	stb	r0,HSTATE_HWTHREAD_STATE(r13)
 | 
			
		||||
	/* Order setting hwthread_state vs. testing hwthread_req */
 | 
			
		||||
	sync
 | 
			
		||||
	lbz	r0,HSTATE_HWTHREAD_REQ(r13)
 | 
			
		||||
	cmpwi	r0,0
 | 
			
		||||
	beqlr
 | 
			
		||||
	b	kvm_start_guest
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called from reset vector for powersave wakeups.
 | 
			
		||||
 * cr3 - set to gt if waking up with partial/complete hypervisor state loss
 | 
			
		||||
| 
						 | 
				
			
			@ -435,15 +454,9 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
 | 
			
		|||
	mr	r3,r12
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 | 
			
		||||
	li	r0,KVM_HWTHREAD_IN_KERNEL
 | 
			
		||||
	stb	r0,HSTATE_HWTHREAD_STATE(r13)
 | 
			
		||||
	/* Order setting hwthread_state vs. testing hwthread_req */
 | 
			
		||||
	sync
 | 
			
		||||
	lbz	r0,HSTATE_HWTHREAD_REQ(r13)
 | 
			
		||||
	cmpwi	r0,0
 | 
			
		||||
	beq	1f
 | 
			
		||||
	b	kvm_start_guest
 | 
			
		||||
1:
 | 
			
		||||
BEGIN_FTR_SECTION
 | 
			
		||||
	bl	kvm_start_guest_check
 | 
			
		||||
END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Return SRR1 from power7_nap() */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2111,6 +2111,15 @@ static int kvmppc_grab_hwthread(int cpu)
 | 
			
		|||
	struct paca_struct *tpaca;
 | 
			
		||||
	long timeout = 10000;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * ISA v3.0 idle routines do not set hwthread_state or test
 | 
			
		||||
	 * hwthread_req, so they can not grab idle threads.
 | 
			
		||||
	 */
 | 
			
		||||
	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
 | 
			
		||||
		WARN(1, "KVM: can not control sibling threads\n");
 | 
			
		||||
		return -EBUSY;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tpaca = &paca[cpu];
 | 
			
		||||
 | 
			
		||||
	/* Ensure the thread won't go into the kernel if it wakes */
 | 
			
		||||
| 
						 | 
				
			
			@ -2145,10 +2154,12 @@ static void kvmppc_release_hwthread(int cpu)
 | 
			
		|||
	struct paca_struct *tpaca;
 | 
			
		||||
 | 
			
		||||
	tpaca = &paca[cpu];
 | 
			
		||||
	tpaca->kvm_hstate.hwthread_req = 0;
 | 
			
		||||
	tpaca->kvm_hstate.kvm_vcpu = NULL;
 | 
			
		||||
	tpaca->kvm_hstate.kvm_vcore = NULL;
 | 
			
		||||
	tpaca->kvm_hstate.kvm_split_mode = NULL;
 | 
			
		||||
	if (!cpu_has_feature(CPU_FTR_ARCH_300))
 | 
			
		||||
		tpaca->kvm_hstate.hwthread_req = 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,9 +149,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 | 
			
		|||
	subf	r4, r4, r3
 | 
			
		||||
	mtspr	SPRN_DEC, r4
 | 
			
		||||
 | 
			
		||||
BEGIN_FTR_SECTION
 | 
			
		||||
	/* hwthread_req may have got set by cede or no vcpu, so clear it */
 | 
			
		||||
	li	r0, 0
 | 
			
		||||
	stb	r0, HSTATE_HWTHREAD_REQ(r13)
 | 
			
		||||
END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * For external interrupts we need to call the Linux
 | 
			
		||||
| 
						 | 
				
			
			@ -314,6 +316,7 @@ kvm_novcpu_exit:
 | 
			
		|||
 * Relocation is off and most register values are lost.
 | 
			
		||||
 * r13 points to the PACA.
 | 
			
		||||
 * r3 contains the SRR1 wakeup value, SRR1 is trashed.
 | 
			
		||||
 * This is not used by ISAv3.0B processors.
 | 
			
		||||
 */
 | 
			
		||||
	.globl	kvm_start_guest
 | 
			
		||||
kvm_start_guest:
 | 
			
		||||
| 
						 | 
				
			
			@ -432,6 +435,9 @@ kvm_secondary_got_guest:
 | 
			
		|||
 * While waiting we also need to check if we get given a vcpu to run.
 | 
			
		||||
 */
 | 
			
		||||
kvm_no_guest:
 | 
			
		||||
BEGIN_FTR_SECTION
 | 
			
		||||
	twi	31,0,0
 | 
			
		||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 | 
			
		||||
	lbz	r3, HSTATE_HWTHREAD_REQ(r13)
 | 
			
		||||
	cmpwi	r3, 0
 | 
			
		||||
	bne	53f
 | 
			
		||||
| 
						 | 
				
			
			@ -2466,8 +2472,10 @@ kvm_do_nap:
 | 
			
		|||
	clrrdi	r0, r0, 1
 | 
			
		||||
	mtspr	SPRN_CTRLT, r0
 | 
			
		||||
 | 
			
		||||
BEGIN_FTR_SECTION
 | 
			
		||||
	li	r0,1
 | 
			
		||||
	stb	r0,HSTATE_HWTHREAD_REQ(r13)
 | 
			
		||||
END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
 | 
			
		||||
	mfspr	r5,SPRN_LPCR
 | 
			
		||||
	ori	r5,r5,LPCR_PECE0 | LPCR_PECE1
 | 
			
		||||
BEGIN_FTR_SECTION
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue