]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
KVM: SVM: Add enable_ipiv param, never set IsRunning if disabled
authorMaxim Levitsky <mlevitsk@redhat.com>
Wed, 11 Jun 2025 22:45:20 +0000 (15:45 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 20 Jun 2025 20:53:02 +0000 (13:53 -0700)
commitd921665e01ba86212bdace238bdff123bceffd46
tree669cb0f54a11e86204c8241092d540a30ccf2565
parentbafddc70001d1834b2f2e490e108bbb8812b4bed
KVM: SVM: Add enable_ipiv param, never set IsRunning if disabled

Let userspace "disable" IPI virtualization for AVIC via the enable_ipiv
module param, by never setting IsRunning.  SVM doesn't provide a way to
disable IPI virtualization in hardware, but by ensuring CPUs never see
IsRunning=1, every IPI in the guest (except for self-IPIs) will generate a
VM-Exit.

To avoid setting the real IsRunning bit, while still allowing KVM to use
each vCPU's entry to update GA log entries, simply maintain a shadow of
the entry, without propagating IsRunning updates to the real table when
IPI virtualization is disabled.

Providing a way to effectively disable IPI virtualization will allow KVM
to safely enable AVIC on hardware that is susceptible to erratum #1235,
which causes hardware to sometimes fail to detect that the IsRunning bit
has been cleared by software.

Note, the table _must_ be fully populated, as broadcast IPIs skip invalid
entries, i.e. won't generate VM-Exit if every entry is invalid, and so
simply pointing the VMCB at a common dummy table won't work.

Alternatively, KVM could allocate a shadow of the entire table, but that'd
be a waste of 4KiB since the per-vCPU entry doesn't actually consume an
additional 8 bytes of memory (vCPU structures are large enough that they
are backed by order-N pages).

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
[sean: keep "entry" variables, reuse enable_ipiv, split from erratum]
Link: https://lore.kernel.org/r/20250611224604.313496-19-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/svm/avic.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h