KVM: VMX: Fold __vmx_vcpu_run() into vmx_vcpu_run()
cea15c2 ("KVM: Move KVM context switch into own function") split vmx_vcpu_run()
to prevent multiple copies of the context switch from being generated (causing
problems due to a label).  This patch folds them back together again and adds
the __noclone attribute to prevent the label from being duplicated.
Signed-off-by: Avi Kivity <avi@redhat.com>
	
	
This commit is contained in:
		
					parent
					
						
							
								30b31ab682
							
						
					
				
			
			
				commit
				
					
						104f226bfd
					
				
			
		
					 1 changed files with 25 additions and 38 deletions
				
			
		|  | @ -3904,17 +3904,33 @@ static void vmx_cancel_injection(struct kvm_vcpu *vcpu) | ||||||
| #define Q "l" | #define Q "l" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /*
 | static void vmx_vcpu_run(struct kvm_vcpu *vcpu) | ||||||
|  * We put this into a separate noinline function to prevent the compiler |  | ||||||
|  * from duplicating the code. This is needed because this code |  | ||||||
|  * uses non local labels that cannot be duplicated. |  | ||||||
|  * Do not put any flow control into this function. |  | ||||||
|  * Better would be to put this whole monstrosity into a .S file. |  | ||||||
|  */ |  | ||||||
| static void noinline do_vmx_vcpu_run(struct kvm_vcpu *vcpu) |  | ||||||
| { | { | ||||||
| 	struct vcpu_vmx *vmx = to_vmx(vcpu); | 	struct vcpu_vmx *vmx = to_vmx(vcpu); | ||||||
| 	asm volatile( | 
 | ||||||
|  | 	/* Record the guest's net vcpu time for enforced NMI injections. */ | ||||||
|  | 	if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) | ||||||
|  | 		vmx->entry_time = ktime_get(); | ||||||
|  | 
 | ||||||
|  | 	/* Don't enter VMX if guest state is invalid, let the exit handler
 | ||||||
|  | 	   start emulation until we arrive back to a valid state */ | ||||||
|  | 	if (vmx->emulation_required && emulate_invalid_guest_state) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty)) | ||||||
|  | 		vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]); | ||||||
|  | 	if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) | ||||||
|  | 		vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); | ||||||
|  | 
 | ||||||
|  | 	/* When single-stepping over STI and MOV SS, we must clear the
 | ||||||
|  | 	 * corresponding interruptibility bits in the guest state. Otherwise | ||||||
|  | 	 * vmentry fails as it then expects bit 14 (BS) in pending debug | ||||||
|  | 	 * exceptions being set, but that's not correct for the guest debugging | ||||||
|  | 	 * case. */ | ||||||
|  | 	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | ||||||
|  | 		vmx_set_interrupt_shadow(vcpu, 0); | ||||||
|  | 
 | ||||||
|  | 	asm( | ||||||
| 		/* Store host registers */ | 		/* Store host registers */ | ||||||
| 		"push %%"R"dx; push %%"R"bp;" | 		"push %%"R"dx; push %%"R"bp;" | ||||||
| 		"push %%"R"cx \n\t" | 		"push %%"R"cx \n\t" | ||||||
|  | @ -4009,35 +4025,6 @@ static void noinline do_vmx_vcpu_run(struct kvm_vcpu *vcpu) | ||||||
| 		, "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" | 		, "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" | ||||||
| #endif | #endif | ||||||
| 	      ); | 	      ); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void vmx_vcpu_run(struct kvm_vcpu *vcpu) |  | ||||||
| { |  | ||||||
| 	struct vcpu_vmx *vmx = to_vmx(vcpu); |  | ||||||
| 
 |  | ||||||
| 	/* Record the guest's net vcpu time for enforced NMI injections. */ |  | ||||||
| 	if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) |  | ||||||
| 		vmx->entry_time = ktime_get(); |  | ||||||
| 
 |  | ||||||
| 	/* Don't enter VMX if guest state is invalid, let the exit handler
 |  | ||||||
| 	   start emulation until we arrive back to a valid state */ |  | ||||||
| 	if (vmx->emulation_required && emulate_invalid_guest_state) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty)) |  | ||||||
| 		vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]); |  | ||||||
| 	if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) |  | ||||||
| 		vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); |  | ||||||
| 
 |  | ||||||
| 	/* When single-stepping over STI and MOV SS, we must clear the
 |  | ||||||
| 	 * corresponding interruptibility bits in the guest state. Otherwise |  | ||||||
| 	 * vmentry fails as it then expects bit 14 (BS) in pending debug |  | ||||||
| 	 * exceptions being set, but that's not correct for the guest debugging |  | ||||||
| 	 * case. */ |  | ||||||
| 	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) |  | ||||||
| 		vmx_set_interrupt_shadow(vcpu, 0); |  | ||||||
| 
 |  | ||||||
| 	do_vmx_vcpu_run(vcpu); |  | ||||||
| 
 | 
 | ||||||
| 	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) | 	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) | ||||||
| 				  | (1 << VCPU_EXREG_PDPTR)); | 				  | (1 << VCPU_EXREG_PDPTR)); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Avi Kivity
				Avi Kivity