On Sat, Sep 5, 2026 at 11:40 PM Tina Zhang <[email protected]> wrote: > > > > On 9/5/2026 8:39 AM, Jim Mattson wrote: > > On Mon, Aug 24, 2026 at 5:40 AM Tina Zhang <[email protected]> wrote: > >> > >> For a synthesized #NPF, the emulator fetch cache is not guaranteed to > >> contain the full architected 15-byte DecodeAssist window, e.g. it may > >> contain only the bytes needed to decode the instruction. > >> > >> Keep preparation of synthesized state limited to capturing a matching > >> emulator fetch cache for #NPF. When constructing VMCB12, copy those bytes > >> and fetch any missing tail through L2 guest page tables. If no emulator > >> bytes are available, fetch the full window from L2 RIP, including for a > >> queued or synthesized #PF VM-Exit. Stop at a translation fault, read > >> failure, non-canonical address, or CS limit overrun. > >> > >> For a non-64-bit L2, truncate each incremented linear address to 32 bits > >> so that a fetch whose CS.base makes it cross the 4GB boundary wraps as > >> required. > >> > >> Do not perform tail or fallback reads for SEV guests. KVM cannot read > >> plaintext instruction bytes from encrypted guest memory, and the existing > >> SEV emulation path treats missing hardware DecodeAssist bytes as > >> unavailable instead of decoding guest memory. For nested SEV, report only > >> matching emulator bytes already captured for a synthesized #NPF, > >> potentially a zero instruction-byte count. > >> > >> Signed-off-by: Tina Zhang <[email protected]> > >> --- > >> arch/x86/kvm/svm/nested.c | 58 ++++++++++++++++++++++++++++++++++++++- > >> 1 file changed, 57 insertions(+), 1 deletion(-) > >> > >> diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c > >> index 635ff20cc431..c677ad5df8d6 100644 > >> --- a/arch/x86/kvm/svm/nested.c > >> +++ b/arch/x86/kvm/svm/nested.c > >> @@ -87,6 +87,54 @@ static void > >> nested_svm_clear_synthesized_insn_bytes(struct vcpu_svm *svm) > >> svm->nested.synthesized_insn_bytes.insn_len = 0; > >> } > >> > >> +static u8 nested_svm_fetch_insn_bytes(struct kvm_vcpu *vcpu, u8 *bytes, > >> + u8 count, u8 max_bytes) > >> +{ > >> + struct kvm_pagewalk *gva_walk = &vcpu->arch.gva_walk; > >> + u64 access = PFERR_FETCH_MASK; > >> + gva_t rip = kvm_get_linear_rip(vcpu); > >> + struct x86_exception e; > >> + > >> + if (kvm_x86_call(get_cpl)(vcpu) == 3) > >> + access |= PFERR_USER_MASK; > >> + > >> + if (!is_64_bit_mode(vcpu)) { > >> + u32 eip = kvm_rip_read(vcpu); > >> + u32 limit = to_svm(vcpu)->vmcb->save.cs.limit; > >> + > >> + if (eip > limit) > >> + return 0; > >> + max_bytes = min_t(u64, max_bytes, (u64)limit - eip + 1); > >> + } > >> + > >> + count = min(count, max_bytes); > > > > Ugh. Pasting together two partial reads performed at different times > > is egregious. This function should read all 15 bytes in one go. That > > pretty much renders the emulator's fetch cache useless, except when it > > contains the necessary 15 bytes. > > This patch was based on the discussion from the first version of this > series[1]. My understanding from that exchange was that preserving the > bytes used by the emulator and fetching the missing tail later was the > intended approach, as it retains the bytes actually used to decode the > instruction. > > Did I misunderstand the conclusion of that discussion? If the > preference is now to avoid combining reads performed at different times, > I can change the next version to use the emulator fetch cache only when > it contains the full 15-byte window, and otherwise fetch all 15 bytes in > one operation. > > [1] > https://lore.kernel.org/kvm/[email protected]/T/#m3fa3f64ddd3284b312d3ddb44fd30a2e26708037
I still don't like it, but Sean overruled me, so I will be quiet now. :)

