From: Nicușor Cîțu <ncitu@xxxxxxxxxxxxxxx> This event is sent when the current instruction has been single stepped as a result of a KVMI_EVENT_PF event to which the introspection tool set the singlestep field and responded with CONTINUE. Signed-off-by: Nicușor Cîțu <ncitu@xxxxxxxxxxxxxxx> Signed-off-by: Adalbert Lazăr <alazar@xxxxxxxxxxxxxxx> --- Documentation/virtual/kvm/kvmi.rst | 25 +++++++++++++++++++ virt/kvm/kvmi.c | 40 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/Documentation/virtual/kvm/kvmi.rst b/Documentation/virtual/kvm/kvmi.rst index 8721a470de87..572abab1f6ef 100644 --- a/Documentation/virtual/kvm/kvmi.rst +++ b/Documentation/virtual/kvm/kvmi.rst @@ -1574,3 +1574,28 @@ introspection has been enabled for this event (see **KVMI_CONTROL_EVENTS**). KVMI_DESC_TR ``write`` is 1 if the descriptor was written, 0 otherwise. + +12. KVMI_EVENT_SINGLESTEP +------------------------- + +:Architectures: x86 +:Versions: >= 1 +:Actions: CONTINUE, CRASH +:Parameters: + +:: + + struct kvmi_event; + +:Returns: + +:: + + struct kvmi_vcpu_hdr; + struct kvmi_event_reply; + +This event is sent when the current instruction has been executed +(as a result of a *KVMI_EVENT_PF* event to which the introspection +tool set the ``singlestep`` field and responded with *CONTINUE*) +and the introspection has been enabled for this event +(see **KVMI_CONTROL_EVENTS**). diff --git a/virt/kvm/kvmi.c b/virt/kvm/kvmi.c index a3a5af9080a9..3dfedf3ae739 100644 --- a/virt/kvm/kvmi.c +++ b/virt/kvm/kvmi.c @@ -1182,6 +1182,44 @@ void kvmi_trap_event(struct kvm_vcpu *vcpu) kvmi_put(vcpu->kvm); } +static u32 kvmi_send_singlestep(struct kvm_vcpu *vcpu) +{ + int err, action; + + err = kvmi_send_event(vcpu, KVMI_EVENT_SINGLESTEP, NULL, 0, + NULL, 0, &action); + if (err) + return KVMI_EVENT_ACTION_CONTINUE; + + return action; +} + +static void __kvmi_singlestep_event(struct kvm_vcpu *vcpu) +{ + u32 action; + + action = kvmi_send_singlestep(vcpu); + switch (action) { + case KVMI_EVENT_ACTION_CONTINUE: + break; + default: + kvmi_handle_common_event_actions(vcpu, action, "SINGLESTEP"); + } +} + +static void kvmi_singlestep_event(struct kvm_vcpu *vcpu) +{ + struct kvmi_vcpu *ivcpu = IVCPU(vcpu); + + if (!ivcpu->ss_requested) + return; + + if (is_event_enabled(vcpu, KVMI_EVENT_SINGLESTEP)) + __kvmi_singlestep_event(vcpu); + + ivcpu->ss_requested = false; +} + static bool __kvmi_create_vcpu_event(struct kvm_vcpu *vcpu) { u32 action; @@ -1616,6 +1654,8 @@ void kvmi_stop_ss(struct kvm_vcpu *vcpu) ivcpu->ss_owner = false; + kvmi_singlestep_event(vcpu); + out: kvmi_put(kvm); }