Commit 73554b2
KVM: x86/pmu: Synthesize at most one PMI per VM-exit
When the irq_work callback, kvm_pmi_trigger_fn(), is invoked during a
VM-exit that also invokes __kvm_perf_overflow() as a result of
instruction emulation, kvm_pmu_deliver_pmi() will be called twice
before the next VM-entry.
Calling kvm_pmu_deliver_pmi() twice is unlikely to be problematic now that
KVM sets the LVTPC mask bit when delivering a PMI. But using IRQ work to
trigger the PMI is still broken, albeit very theoretically.
E.g. if the self-IPI to trigger IRQ work is be delayed long enough for the
vCPU to be migrated to a different pCPU, then it's possible for
kvm_pmi_trigger_fn() to race with the kvm_pmu_deliver_pmi() from
KVM_REQ_PMI and still generate two PMIs.
KVM could set the mask bit using an atomic operation, but that'd just be
piling on unnecessary code to workaround what is effectively a hack. The
*only* reason KVM uses IRQ work is to ensure the PMI is treated as a wake
event, e.g. if the vCPU just executed HLT.
Remove the irq_work callback for synthesizing a PMI, and all of the
logic for invoking it. Instead, to prevent a vcpu from leaving C0 with
a PMI pending, add a check for KVM_REQ_PMI to kvm_vcpu_has_events().
Fixes: 9cd803d ("KVM: x86: Update vPMCs when retiring instructions")
Signed-off-by: Jim Mattson <[email protected]>
Tested-by: Mingwei Zhang <[email protected]>
Tested-by: Dapeng Mi <[email protected]>
Signed-off-by: Mingwei Zhang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
[sean: massage changelog]
Signed-off-by: Sean Christopherson <[email protected]>1 parent a16eb25 commit 73554b2
3 files changed
+4
-27
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
528 | 528 | | |
529 | 529 | | |
530 | 530 | | |
531 | | - | |
532 | 531 | | |
533 | 532 | | |
534 | 533 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | 96 | | |
105 | 97 | | |
106 | 98 | | |
| |||
124 | 116 | | |
125 | 117 | | |
126 | 118 | | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
| 119 | + | |
141 | 120 | | |
142 | 121 | | |
143 | 122 | | |
| |||
675 | 654 | | |
676 | 655 | | |
677 | 656 | | |
678 | | - | |
679 | | - | |
680 | | - | |
681 | 657 | | |
682 | 658 | | |
683 | 659 | | |
| |||
687 | 663 | | |
688 | 664 | | |
689 | 665 | | |
690 | | - | |
691 | 666 | | |
692 | 667 | | |
693 | 668 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12843 | 12843 | | |
12844 | 12844 | | |
12845 | 12845 | | |
| 12846 | + | |
| 12847 | + | |
| 12848 | + | |
12846 | 12849 | | |
12847 | 12850 | | |
12848 | 12851 | | |
| |||
0 commit comments