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…
Reference in a new issue