[PATCH v7 0/8] KVM: nSVM: Enable DecodeAssists for nested guests

From: Tina Zhang

Date: Fri Sep 18 2026 - 05:02:14 EST


The SVM DecodeAssists feature provides decode state for selected
VM-Exits. KVM currently does not expose this feature to L1. Some L1
hypervisors may therefore treat the platform's SVM support as
incomplete.

In practice, this was observed with Hyper-V running on top of KVM.
Hyper-V appears to require DecodeAssists before enabling nested SVM for
its guests. Virtualizing the feature lets users enable Hyper-V
virtualization features inside a Windows VM when needed, e.g. to run
QEMU/KVM in WSL.

Virtualize both parts of DecodeAssists for nested SVM. For emulated
MOV CR/DR, INTn, INVLPG, and related intercepts, populate EXITINFO1 as
specified by the architecture. Preserve MOV-to-CR0 decode information
for selective CR0 write intercepts. INVLPGA's address remains in saved
guest rAX. Leave EXITINFO1 unchanged when DecodeAssists is not exposed.

For data #NPF and intercepted data #PF exits, propagate current hardware
instruction bytes when available. For an emulator-generated #NPF, keep
the bytes used to decode the instruction and fetch any missing tail.
Queued #PF exits, including userspace-injected exceptions, use an
on-demand fetch from the current L2 CS:RIP. Instruction-fetch faults
report zero bytes, and SEV guests do not use the memory-fetch fallback.

The selftest checks hardware and forced-emulation instruction intercepts
against the same expected values, including selective CR0 writes. It
also covers hardware and synthesized instruction bytes, truncated
fetches, cache preservation after instruction memory changes during
MMIO, and userspace-injected #PF after MMIO completion.

Before rebasing, the updated selftest passed with
kvm.force_emulation_prefix both disabled and enabled in an isolated VM
using the v7 implementation. The non-FEP cases also passed on the
physical host. After rebasing onto the base commit below, the affected
KVM objects and selftest build successfully; runtime validation on the
new base is still pending. SEV paths have not been tested.

Changes since v6:
- Rebase onto kvm-x86/next at the base commit listed below and use
cpu_feature_enabled() in place of the removed static_cpu_has() API.
- Document why get_invlpg_linear_addr() ignores __linearize() failures:
the address is computed before a failure and matches em_invlpg().
- Use CR_VALID and SVM_EXITINFO_REG_MASK for MOV CR/DR decode state,
and retain MOV-to-CR0 information for selective CR0 write intercepts.
- Use the common VMCB02 invalidation helper for synthesized exits that
do not provide instruction bytes.
- Extend kvm_read_guest_virt_helper() with an optional bytes_read output
and make kvm_fetch_guest_virt() return the number of bytes read.
Remove the nSVM page loop and handle instruction-fetch address wrapping
and canonicality checks in the generic helper's existing loop.
- Run instruction-intercept tests without FEP as well as with FEP when
enabled. Add a MOV-to-CR0 selective-intercept case and poison insn_len
and insn_bytes before each run. Keep the CLTS check limited to bit 63.
- Add Jim's Reviewed-by tags for hardware-byte propagation and emulator
cache reuse.

Previous versions (including earlier changelogs):
v6:
https://lore.kernel.org/r/cover.1789281096.git.zhang_wei@xxxxxxxxxxxxxx
v5:
https://lore.kernel.org/r/20260824123954.315112-1-zhang_wei@xxxxxxxxxxxxxx
v4:
https://lore.kernel.org/r/cover.1787116250.git.zhang_wei@xxxxxxxxxxxxxx
v3:
https://lore.kernel.org/r/cover.1785411877.git.zhang_wei@xxxxxxxxxxxxxx
v2:
https://lore.kernel.org/r/cover.1783999988.git.zhang_wei@xxxxxxxxxxxxxx
v1:
https://lore.kernel.org/r/20260629125205.52394-1-zhang_wei@xxxxxxxxxxxxxx

Tina Zhang (8):
KVM: x86: Provide INVLPG linear address to intercept handlers
KVM: nSVM: Synthesize DecodeAssists EXITINFO for emulated intercepts
KVM: nSVM: Track valid hardware DecodeAssist bytes
KVM: nSVM: Propagate hardware DecodeAssist bytes to VMCB12
KVM: nSVM: Fetch DecodeAssist bytes for synthesized faults
KVM: nSVM: Use emulator bytes for synthesized nested #NPF
KVM: nSVM: Advertise DecodeAssists to L1
KVM: selftests: Add nested SVM DecodeAssists test

arch/x86/kvm/cpuid.c | 1 +
arch/x86/kvm/emulate.c | 45 ++
arch/x86/kvm/kvm_emulate.h | 4 +
arch/x86/kvm/svm/nested.c | 142 ++++-
arch/x86/kvm/svm/svm.c | 29 +
arch/x86/kvm/svm/svm.h | 3 +
arch/x86/kvm/x86.c | 56 +-
arch/x86/kvm/x86.h | 2 +
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../selftests/kvm/include/x86/processor.h | 1 +
.../kvm/x86/svm_nested_decode_assists_test.c | 590 ++++++++++++++++++
11 files changed, 862 insertions(+), 12 deletions(-)
create mode 100644 tools/testing/selftests/kvm/x86/svm_nested_decode_assists_test.c


base-commit: 70c944caf570fda2d79baa71435589a8db39f048
--
2.43.7