On Thu, Mar 10, 2022, Chenyi Qiang wrote: > In some fatal case, the target vcpu would run into unexpected behavior > and should get shutdown (e.g. VM context is corrupted and not valid in > VMCS). User space would be informed in such case. To kill the target > vcpu, extend KVM_SET_VCPU_EVENTS ioctl to inject a synthesized SHUTDOWN > event with a new bit set in flags field. KVM would accordingly make > KVM_REQ_TRIPLE_FAULT request to trigger the real shutdown exit. Noting > that the KVM_REQ_TRIPLE_FAULT request also applies to the nested case, > so that only the target L2 vcpu would be killed. > > Signed-off-by: Chenyi Qiang <chenyi.qiang@xxxxxxxxx> > --- > Documentation/virt/kvm/api.rst | 3 +++ > arch/x86/include/uapi/asm/kvm.h | 1 + > arch/x86/kvm/x86.c | 6 +++++- > 3 files changed, 9 insertions(+), 1 deletion(-) > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > index 691ff84444bd..d1971ef613e7 100644 > --- a/Documentation/virt/kvm/api.rst > +++ b/Documentation/virt/kvm/api.rst > @@ -1241,6 +1241,9 @@ can be set in the flags field to signal that the > exception_has_payload, exception_payload, and exception.pending fields > contain a valid state and shall be written into the VCPU. > > +KVM_VCPUEVENT_SHUTDOWN can be set in flags field to synthesize a SHUTDOWN > +event for a vcpu from user space. > + > ARM/ARM64: > ^^^^^^^^^^ > > diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h > index bf6e96011dfe..44757bd6122d 100644 > --- a/arch/x86/include/uapi/asm/kvm.h > +++ b/arch/x86/include/uapi/asm/kvm.h > @@ -325,6 +325,7 @@ struct kvm_reinject_control { > #define KVM_VCPUEVENT_VALID_SHADOW 0x00000004 > #define KVM_VCPUEVENT_VALID_SMM 0x00000008 > #define KVM_VCPUEVENT_VALID_PAYLOAD 0x00000010 > +#define KVM_VCPUEVENT_SHUTDOWN 0x00000020 > > /* Interrupt shadow states */ > #define KVM_X86_SHADOW_INT_MOV_SS 0x01 > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 4fa4d8269e5b..53c8592066c8 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -4903,7 +4903,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, > | KVM_VCPUEVENT_VALID_SIPI_VECTOR > | KVM_VCPUEVENT_VALID_SHADOW > | KVM_VCPUEVENT_VALID_SMM > - | KVM_VCPUEVENT_VALID_PAYLOAD)) > + | KVM_VCPUEVENT_VALID_PAYLOAD > + | KVM_VCPUEVENT_SHUTDOWN)) > return -EINVAL; > > if (events->flags & KVM_VCPUEVENT_VALID_PAYLOAD) { > @@ -4976,6 +4977,9 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, > } > } > > + if (events->flags & KVM_VCPUEVENT_SHUTDOWN) > + kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); Huh. I think we need to make this bidirection and add it to get_vcpu_events() as well, and treat it as a bug fix. In direct triple fault cases, i.e. hardware detected and morphed to VM-Exit, KVM will never lose the triple fault. But for triple faults sythesized by KVM, e.g. the RSM path or nested_vmx_abort(), if KVM exits to userspace before the request is serviced, userspace could migrate the VM and lose the triple fault.