From: Mihai Donțu <[email protected]>

The introspection requests (KVM_REQ_INTROSPECTION) are checked by any
introspected vCPU in two places:

  * on its way to guest - vcpu_enter_guest()
  * when halted - kvm_vcpu_block()

In kvm_vcpu_block(), we check to see if there are any introspection
requests during the swait loop, handle them outside of swait loop and
start swait again.

Signed-off-by: Mihai Donțu <[email protected]>
Co-developed-by: Mircea Cîrjaliu <[email protected]>
Signed-off-by: Mircea Cîrjaliu <[email protected]>
Signed-off-by: Adalbert Lazăr <[email protected]>
---
 arch/x86/kvm/x86.c   |  3 +++
 include/linux/kvmi.h |  2 ++
 virt/kvm/kvm_main.c  | 28 ++++++++++++++++++++++------
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0163e1ad1aaa..adbdb1ceb618 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7742,6 +7742,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                 */
                if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
                        kvm_hv_process_stimers(vcpu);
+
+               if (kvm_check_request(KVM_REQ_INTROSPECTION, vcpu))
+                       kvmi_handle_requests(vcpu);
        }
 
        if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
diff --git a/include/linux/kvmi.h b/include/linux/kvmi.h
index e8d25d7da751..ae5de1905b55 100644
--- a/include/linux/kvmi.h
+++ b/include/linux/kvmi.h
@@ -16,6 +16,7 @@ int kvmi_ioctl_event(struct kvm *kvm, void __user *argp);
 int kvmi_ioctl_unhook(struct kvm *kvm, bool force_reset);
 int kvmi_vcpu_init(struct kvm_vcpu *vcpu);
 void kvmi_vcpu_uninit(struct kvm_vcpu *vcpu);
+void kvmi_handle_requests(struct kvm_vcpu *vcpu);
 
 #else
 
@@ -25,6 +26,7 @@ static inline void kvmi_create_vm(struct kvm *kvm) { }
 static inline void kvmi_destroy_vm(struct kvm *kvm) { }
 static inline int kvmi_vcpu_init(struct kvm_vcpu *vcpu) { return 0; }
 static inline void kvmi_vcpu_uninit(struct kvm_vcpu *vcpu) { }
+static inline void kvmi_handle_requests(struct kvm_vcpu *vcpu) { }
 
 #endif /* CONFIG_KVM_INTROSPECTION */
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 94f15f393e37..2e11069b9565 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2282,16 +2282,32 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
        kvm_arch_vcpu_blocking(vcpu);
 
        for (;;) {
-               prepare_to_swait_exclusive(&vcpu->wq, &wait, 
TASK_INTERRUPTIBLE);
+               bool do_kvmi_work = false;
 
-               if (kvm_vcpu_check_block(vcpu) < 0)
-                       break;
+               for (;;) {
+                       prepare_to_swait_exclusive(&vcpu->wq, &wait,
+                                                  TASK_INTERRUPTIBLE);
+
+                       if (kvm_vcpu_check_block(vcpu) < 0)
+                               break;
+
+                       waited = true;
+                       schedule();
+
+                       if (kvm_check_request(KVM_REQ_INTROSPECTION, vcpu)) {
+                               do_kvmi_work = true;
+                               break;
+                       }
+               }
 
-               waited = true;
-               schedule();
+               finish_swait(&vcpu->wq, &wait);
+
+               if (do_kvmi_work)
+                       kvmi_handle_requests(vcpu);
+               else
+                       break;
        }
 
-       finish_swait(&vcpu->wq, &wait);
        cur = ktime_get();
 
        kvm_arch_vcpu_unblocking(vcpu);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to