Re: [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 01/04/21 15:54, Maxim Levitsky wrote:
KVM_GUESTDBG_BLOCKEVENTS is a guest debug feature that
will allow KVM to block all interrupts while running.
It is mostly intended to be used together with single stepping,
to make it more robust, and has the following benefits:

* Resuming from a breakpoint is much more reliable:
   When resuming execution from a breakpoint, with interrupts enabled,
   more often than not, KVM would inject an interrupt and make the CPU
   jump immediately to the interrupt handler and eventually return to
   the breakpoint, only to trigger it again.

   From the gdb's user point of view it looks like the CPU has never
   executed a single instruction and in some cases that can even
   prevent forward progress, for example, when the breakpoint
   is placed by an automated script (e.g lx-symbols), which does
   something in response to the breakpoint and then continues
   the guest automatically.
   If the script execution takes enough time for another interrupt to
   arrive, the guest will be stuck on the same breakpoint forever.

* Normal single stepping is much more predictable, since it won't
   land the debugger into an interrupt handler.

* Chances of RFLAGS.TF being leaked to the guest are reduced:

   KVM sets that flag behind the guest's back to single step it,
   but if the single step lands the vCPU into an
   interrupt/exception handler the RFLAGS.TF will be leaked to the
   guest in the form of being pushed to the stack.
   This doesn't completely eliminate this problem as exceptions
   can still happen, but at least this eliminates the common
   case.

Signed-off-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx>

The patch uses BLOCKIRQ instead of BLOCKEVENTS.

Paolo

---
  Documentation/virt/kvm/api.rst  | 1 +
  arch/x86/include/asm/kvm_host.h | 3 ++-
  arch/x86/include/uapi/asm/kvm.h | 1 +
  arch/x86/kvm/x86.c              | 4 ++++
  4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 9778b2434c03..a4f2dc84741f 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -3338,6 +3338,7 @@ flags which can include the following:
    - KVM_GUESTDBG_INJECT_DB:     inject DB type exception [x86]
    - KVM_GUESTDBG_INJECT_BP:     inject BP type exception [x86]
    - KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
+  - KVM_GUESTDBG_BLOCKIRQ:      avoid injecting interrupts/NMI/SMI [x86]
For example KVM_GUESTDBG_USE_SW_BP indicates that software breakpoints
  are enabled in memory so we need to ensure breakpoint exceptions are
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index cc7c82a449d5..8c529ae9dbbe 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -227,7 +227,8 @@ enum x86_intercept_stage;
  	KVM_GUESTDBG_USE_HW_BP | \
  	KVM_GUESTDBG_USE_SW_BP | \
  	KVM_GUESTDBG_INJECT_BP | \
-	KVM_GUESTDBG_INJECT_DB)
+	KVM_GUESTDBG_INJECT_DB | \
+	KVM_GUESTDBG_BLOCKIRQ)
#define PFERR_PRESENT_BIT 0
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index 5a3022c8af82..b0f9945067f7 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -282,6 +282,7 @@ struct kvm_debug_exit_arch {
  #define KVM_GUESTDBG_USE_HW_BP		0x00020000
  #define KVM_GUESTDBG_INJECT_DB		0x00040000
  #define KVM_GUESTDBG_INJECT_BP		0x00080000
+#define KVM_GUESTDBG_BLOCKIRQ		0x00100000
/* for KVM_SET_GUEST_DEBUG */
  struct kvm_guest_debug_arch {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 956e8e0bd6af..3627ce8fe5bb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8460,6 +8460,10 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit
  		can_inject = false;
  	}
+ /* Don't inject interrupts if the user asked to avoid doing so */
+	if (vcpu->guest_debug & KVM_GUESTDBG_BLOCKIRQ)
+		return;
+
  	/*
  	 * Finally, inject interrupt events.  If an event cannot be injected
  	 * due to architectural conditions (e.g. IF=0) a window-open exit


_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm



[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux