Ping Thanks Hou On 2021/11/2 17:15, Hou Wenlong wrote: > From: Hou Wenlong <houwenlong93@xxxxxxxxxxxxxxxxx> > > When KVM_CAP_X86_USER_SPACE_MSR cap is enabled, userspace can control > MSR accesses. In normal scenario, RDMSR/WRMSR can be interceped, but > when kvm.force_emulation_prefix is enabled, RDMSR/WRMSR with kvm prefix > would trigger an UD and cause instruction emulation. If MSR accesses is > filtered, em_rdmsr()/em_wrmsr() returns X86EMUL_IO_NEEDED, but it is > ignored by x86_emulate_instruction(). Then guest continues execution, > but RIP has been updated to point to RDMSR/WRMSR in handle_ud(), so > RDMSR/WRMSR can be interceped and guest exits to userspace finnaly by > mistake. Such behaviour leads to two vm exits and wastes one instruction > emulation. > > After let x86_emulate_instruction() returns 0 for RDMSR/WRMSR emulation, > if it needs to exit to userspace, its complete_userspace_io callback > would call kvm_skip_instruction() to skip instruction. But for vmx, > VMX_EXIT_INSTRUCTION_LEN in vmcs is invalid for UD, it can't be used to > update RIP, kvm_emulate_instruction() should be used instead. As for > svm, nRIP in vmcb is 0 for UD, so kvm_emulate_instruction() is used. > But for nested svm, I'm not sure, since svm_check_intercept() would > change nRIP. > > Changed from v1: > As Sean suggested, fix the problem within the emulator > instead of routing to the vendor callback. > Add a new emulation type to handle completion of user exits. > Attach a different callback for msr access emulation in the > emulator. > > Hou Wenlong (3): > KVM: x86: Add an emulation type to handle completion of user exits > KVM: x86: Use different callback if msr access comes from the emulator > KVM: x86: Exit to userspace if RDMSR/WRMSR emulation returns > X86EMUL_IO_NEEDED > > Sean Christopherson (1): > KVM: x86: Handle 32-bit wrap of EIP for EMULTYPE_SKIP with flat code > seg > > arch/x86/include/asm/kvm_host.h | 8 ++- > arch/x86/kvm/x86.c | 108 ++++++++++++++++++++------------ > 2 files changed, 76 insertions(+), 40 deletions(-) >