1 From foo@baz Thu Feb 1 13:45:42 CET 2018
2 From: Liran Alon <liran.alon@oracle.com>
3 Date: Sun, 5 Nov 2017 16:07:43 +0200
4 Subject: KVM: nVMX: Fix vmx_check_nested_events() return value in case an event was reinjected to L2
6 From: Liran Alon <liran.alon@oracle.com>
9 [ Upstream commit 917dc6068bc12a2dafffcf0e9d405ddb1b8780cb ]
11 vmx_check_nested_events() should return -EBUSY only in case there is a
12 pending L1 event which requires a VMExit from L2 to L1 but such a
13 VMExit is currently blocked. Such VMExits are blocked either
14 because nested_run_pending=1 or an event was reinjected to L2.
15 vmx_check_nested_events() should return 0 in case there are no
16 pending L1 events which requires a VMExit from L2 to L1 or if
17 a VMExit from L2 to L1 was done internally.
19 However, upstream commit which introduced blocking in case an event was
20 reinjected to L2 (commit acc9ab601327 ("KVM: nVMX: Fix pending events
21 injection")) contains a bug: It returns -EBUSY even if there are no
22 pending L1 events which requires VMExit from L2 to L1.
24 This commit fix this issue.
26 Fixes: acc9ab601327 ("KVM: nVMX: Fix pending events injection")
28 Signed-off-by: Liran Alon <liran.alon@oracle.com>
29 Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
30 Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
31 Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
32 Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
33 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35 arch/x86/kvm/vmx.c | 13 ++++++-------
36 1 file changed, 6 insertions(+), 7 deletions(-)
38 --- a/arch/x86/kvm/vmx.c
39 +++ b/arch/x86/kvm/vmx.c
40 @@ -11114,13 +11114,12 @@ static int vmx_check_nested_events(struc
42 struct vcpu_vmx *vmx = to_vmx(vcpu);
43 unsigned long exit_qual;
45 - if (kvm_event_needs_reinjection(vcpu))
47 + bool block_nested_events =
48 + vmx->nested.nested_run_pending || kvm_event_needs_reinjection(vcpu);
50 if (vcpu->arch.exception.pending &&
51 nested_vmx_check_exception(vcpu, &exit_qual)) {
52 - if (vmx->nested.nested_run_pending)
53 + if (block_nested_events)
55 nested_vmx_inject_exception_vmexit(vcpu, exit_qual);
56 vcpu->arch.exception.pending = false;
57 @@ -11129,14 +11128,14 @@ static int vmx_check_nested_events(struc
59 if (nested_cpu_has_preemption_timer(get_vmcs12(vcpu)) &&
60 vmx->nested.preemption_timer_expired) {
61 - if (vmx->nested.nested_run_pending)
62 + if (block_nested_events)
64 nested_vmx_vmexit(vcpu, EXIT_REASON_PREEMPTION_TIMER, 0, 0);
68 if (vcpu->arch.nmi_pending && nested_exit_on_nmi(vcpu)) {
69 - if (vmx->nested.nested_run_pending)
70 + if (block_nested_events)
72 nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
73 NMI_VECTOR | INTR_TYPE_NMI_INTR |
74 @@ -11152,7 +11151,7 @@ static int vmx_check_nested_events(struc
76 if ((kvm_cpu_has_interrupt(vcpu) || external_intr) &&
77 nested_exit_on_intr(vcpu)) {
78 - if (vmx->nested.nested_run_pending)
79 + if (block_nested_events)
81 nested_vmx_vmexit(vcpu, EXIT_REASON_EXTERNAL_INTERRUPT, 0, 0);