linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/9] KVM: my debug patch queue
@ 2021-04-01 13:54 Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 1/9] scripts/gdb: rework lx-symbols gdb script Maxim Levitsky
                   ` (9 more replies)
  0 siblings, 10 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

Hi!

I would like to publish two debug features which were needed for other stuff
I work on.

One is the reworked lx-symbols script which now actually works on at least
gdb 9.1 (gdb 9.2 was reported to fail to load the debug symbols from the kernel
for some reason, not related to this patch) and upstream qemu.

The other feature is the ability to trap all guest exceptions (on SVM for now)
and see them in kvmtrace prior to potential merge to double/triple fault.

This can be very useful and I already had to manually patch KVM a few
times for this.
I will, once time permits, implement this feature on Intel as well.

V2:

 * Some more refactoring and workarounds for lx-symbols script

 * added KVM_GUESTDBG_BLOCKEVENTS flag to enable 'block interrupts on
   single step' together with KVM_CAP_SET_GUEST_DEBUG2 capability
   to indicate which guest debug flags are supported.

   This is a replacement for unconditional block of interrupts on single
   step that was done in previous version of this patch set.
   Patches to qemu to use that feature will be sent soon.

 * Reworked the the 'intercept all exceptions for debug' feature according
   to the review feedback:

   - renamed the parameter that enables the feature and
     moved it to common kvm module.
     (only SVM part is currently implemented though)

   - disable the feature for SEV guests as was suggested during the review
   - made the vmexit table const again, as was suggested in the review as well.

Best regards,
	Maxim Levitsky

Maxim Levitsky (9):
  scripts/gdb: rework lx-symbols gdb script
  KVM: introduce KVM_CAP_SET_GUEST_DEBUG2
  KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2
  KVM: aarch64: implement KVM_CAP_SET_GUEST_DEBUG2
  KVM: s390x: implement KVM_CAP_SET_GUEST_DEBUG2
  KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS
  KVM: SVM: split svm_handle_invalid_exit
  KVM: x86: add force_intercept_exceptions_mask
  KVM: SVM: implement force_intercept_exceptions_mask

 Documentation/virt/kvm/api.rst    |   4 +
 arch/arm64/include/asm/kvm_host.h |   4 +
 arch/arm64/kvm/arm.c              |   2 +
 arch/arm64/kvm/guest.c            |   5 -
 arch/s390/include/asm/kvm_host.h  |   4 +
 arch/s390/kvm/kvm-s390.c          |   3 +
 arch/x86/include/asm/kvm_host.h   |  12 ++
 arch/x86/include/uapi/asm/kvm.h   |   1 +
 arch/x86/kvm/svm/svm.c            |  87 +++++++++++--
 arch/x86/kvm/svm/svm.h            |   6 +-
 arch/x86/kvm/x86.c                |  14 ++-
 arch/x86/kvm/x86.h                |   2 +
 include/uapi/linux/kvm.h          |   1 +
 kernel/module.c                   |   8 +-
 scripts/gdb/linux/symbols.py      | 203 ++++++++++++++++++++----------
 15 files changed, 272 insertions(+), 84 deletions(-)

-- 
2.26.2



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 1/9] scripts/gdb: rework lx-symbols gdb script
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 2/9] KVM: introduce KVM_CAP_SET_GUEST_DEBUG2 Maxim Levitsky
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

Fix several issues that are present in lx-symbols script:

* Track module unloads by placing another software breakpoint at
  'free_module'
  (force uninline this symbol just in case), and use remove-symbol-file
  gdb command to unload the symobls of the module that is unloading.

  That gives the gdb a chance to mark all software breakpoints from
  this module as pending again.
  Also remove the module from the 'known' module list once it is unloaded.

* Since we now track module unload, we don't need to reload all
  symbols anymore when 'known' module loaded again
  (that can't happen anymore).
  This allows reloading a module in the debugged kernel to finish
  much faster, while lx-symbols tracks module loads and unloads.

* Disable/enable all gdb breakpoints on both module load and unload
  breakpoint hits, and not only in 'load_all_symbols' as was done before.
  (load_all_symbols is no longer called on breakpoint hit)
  That allows gdb to avoid getting confused about the state of the
  (now two) internal breakpoints we place.
  Otherwise it will leave them in the kernel code segment, when
  continuing which triggers a guest kernel panic as soon as it skips
  over the 'int3' instruction and executes the garbage tail of the optcode
  on which the breakpoint was placed.

* Block SIGINT while symbols are reloading as this seems to crash gdb.
  (new in V2)

* Add a basic check that kernel is already loaded into the guest memory
  to avoid confusing errors.
  (new in V2)

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 kernel/module.c              |   8 +-
 scripts/gdb/linux/symbols.py | 203 +++++++++++++++++++++++------------
 2 files changed, 143 insertions(+), 68 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 30479355ab85..ea81fc06ea1f 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -901,8 +901,12 @@ int module_refcount(struct module *mod)
 }
 EXPORT_SYMBOL(module_refcount);
 
-/* This exists whether we can unload or not */
-static void free_module(struct module *mod);
+/* This exists whether we can unload or not
+ * Keep it uninlined to provide a reliable breakpoint target,
+ * e.g. for the gdb helper command 'lx-symbols'.
+ */
+
+static noinline void free_module(struct module *mod);
 
 SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
 		unsigned int, flags)
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
index 1be9763cf8bb..e1374a6e06f7 100644
--- a/scripts/gdb/linux/symbols.py
+++ b/scripts/gdb/linux/symbols.py
@@ -14,45 +14,23 @@
 import gdb
 import os
 import re
+import signal
 
 from linux import modules, utils
 
 
 if hasattr(gdb, 'Breakpoint'):
-    class LoadModuleBreakpoint(gdb.Breakpoint):
-        def __init__(self, spec, gdb_command):
-            super(LoadModuleBreakpoint, self).__init__(spec, internal=True)
+
+    class BreakpointWrapper(gdb.Breakpoint):
+        def __init__(self, callback, **kwargs):
+            super(BreakpointWrapper, self).__init__(internal=True, **kwargs)
             self.silent = True
-            self.gdb_command = gdb_command
+            self.callback = callback
 
         def stop(self):
-            module = gdb.parse_and_eval("mod")
-            module_name = module['name'].string()
-            cmd = self.gdb_command
-
-            # enforce update if object file is not found
-            cmd.module_files_updated = False
-
-            # Disable pagination while reporting symbol (re-)loading.
-            # The console input is blocked in this context so that we would
-            # get stuck waiting for the user to acknowledge paged output.
-            show_pagination = gdb.execute("show pagination", to_string=True)
-            pagination = show_pagination.endswith("on.\n")
-            gdb.execute("set pagination off")
-
-            if module_name in cmd.loaded_modules:
-                gdb.write("refreshing all symbols to reload module "
-                          "'{0}'\n".format(module_name))
-                cmd.load_all_symbols()
-            else:
-                cmd.load_module_symbols(module)
-
-            # restore pagination state
-            gdb.execute("set pagination %s" % ("on" if pagination else "off"))
-
+            self.callback()
             return False
 
-
 class LxSymbols(gdb.Command):
     """(Re-)load symbols of Linux kernel and currently loaded modules.
 
@@ -61,15 +39,52 @@ are scanned recursively, starting in the same directory. Optionally, the module
 search path can be extended by a space separated list of paths passed to the
 lx-symbols command."""
 
-    module_paths = []
-    module_files = []
-    module_files_updated = False
-    loaded_modules = []
-    breakpoint = None
-
     def __init__(self):
         super(LxSymbols, self).__init__("lx-symbols", gdb.COMMAND_FILES,
                                         gdb.COMPLETE_FILENAME)
+        self.module_paths = []
+        self.module_files = []
+        self.module_files_updated = False
+        self.loaded_modules = {}
+        self.internal_breakpoints = []
+
+    # prepare GDB for loading/unloading a module
+    def _prepare_for_module_load_unload(self):
+
+        self.blocked_sigint = False
+
+        # block SIGINT during execution to avoid gdb crash
+        sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, [])
+        if not signal.SIGINT in sigmask:
+            self.blocked_sigint = True
+            signal.pthread_sigmask(signal.SIG_BLOCK, {signal.SIGINT})
+
+        # disable all breakpoints to workaround a GDB bug where it would
+        # not correctly resume from an internal breakpoint we placed
+        # in do_module_init/free_module (it leaves the int3
+        self.saved_breakpoints = []
+        if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None:
+            for bp in gdb.breakpoints():
+                self.saved_breakpoints.append({'breakpoint': bp, 'enabled': bp.enabled})
+                bp.enabled = False
+
+        # disable pagination to avoid asking user for continue
+        show_pagination = gdb.execute("show pagination", to_string=True)
+        self.saved_pagination = show_pagination.endswith("on.\n")
+        gdb.execute("set pagination off")
+
+    def _unprepare_for_module_load_unload(self):
+        # restore breakpoint state
+        for breakpoint in self.saved_breakpoints:
+            breakpoint['breakpoint'].enabled = breakpoint['enabled']
+
+        # restore pagination state
+        gdb.execute("set pagination %s" % ("on" if self.saved_pagination else "off"))
+
+        # unblock SIGINT
+        if self.blocked_sigint:
+            sigmask = signal.pthread_sigmask(signal.SIG_UNBLOCK, {signal.SIGINT})
+            self.blocked_sigint = False
 
     def _update_module_files(self):
         self.module_files = []
@@ -107,7 +122,7 @@ lx-symbols command."""
                     name=section_name, addr=str(address)))
         return "".join(args)
 
-    def load_module_symbols(self, module):
+    def _do_load_module_symbols(self, module):
         module_name = module['name'].string()
         module_addr = str(module['core_layout']['base']).split()[0]
 
@@ -130,55 +145,111 @@ lx-symbols command."""
                 addr=module_addr,
                 sections=self._section_arguments(module))
             gdb.execute(cmdline, to_string=True)
-            if module_name not in self.loaded_modules:
-                self.loaded_modules.append(module_name)
+
+            self.loaded_modules[module_name] = {"module_file": module_file,
+                                                "module_addr": module_addr}
         else:
             gdb.write("no module object found for '{0}'\n".format(module_name))
 
+
+    def load_module_symbols(self):
+        module = gdb.parse_and_eval("mod")
+
+                # module already loaded, false alarm
+        # can happen if 'do_init_module' breakpoint is hit multiple times
+        # due to interrupts
+        module_name = module['name'].string()
+        if module_name in self.loaded_modules:
+            gdb.write("spurious module load breakpoint\n")
+            return
+
+        # enforce update if object file is not found
+        self.module_files_updated = False
+        self._prepare_for_module_load_unload()
+        try:
+            self._do_load_module_symbols(module)
+        finally:
+            self._unprepare_for_module_load_unload()
+
+
+    def unload_module_symbols(self):
+        module = gdb.parse_and_eval("mod")
+        module_name = module['name'].string()
+
+        # module already unloaded, false alarm
+        # can happen if 'free_module' breakpoint is hit multiple times
+        # due to interrupts
+        if not module_name in self.loaded_modules:
+            gdb.write("spurious module unload breakpoint\n")
+            return
+
+        module_file = self.loaded_modules[module_name]["module_file"]
+        module_addr = self.loaded_modules[module_name]["module_addr"]
+
+        self._prepare_for_module_load_unload()
+        try:
+            gdb.write("unloading @{addr}: {filename}\n".format(
+                addr=module_addr, filename=module_file))
+            cmdline = "remove-symbol-file {filename}".format(
+                filename=module_file)
+            gdb.execute(cmdline, to_string=True)
+            del self.loaded_modules[module_name]
+
+        finally:
+            self._unprepare_for_module_load_unload()
+
     def load_all_symbols(self):
         gdb.write("loading vmlinux\n")
 
-        # Dropping symbols will disable all breakpoints. So save their states
-        # and restore them afterward.
-        saved_states = []
-        if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None:
-            for bp in gdb.breakpoints():
-                saved_states.append({'breakpoint': bp, 'enabled': bp.enabled})
-
-        # drop all current symbols and reload vmlinux
-        orig_vmlinux = 'vmlinux'
-        for obj in gdb.objfiles():
-            if obj.filename.endswith('vmlinux'):
-                orig_vmlinux = obj.filename
-        gdb.execute("symbol-file", to_string=True)
-        gdb.execute("symbol-file {0}".format(orig_vmlinux))
-
-        self.loaded_modules = []
-        module_list = modules.module_list()
-        if not module_list:
-            gdb.write("no modules found\n")
-        else:
-            [self.load_module_symbols(module) for module in module_list]
+        self._prepare_for_module_load_unload()
+        try:
+            # drop all current symbols and reload vmlinux
+            orig_vmlinux = 'vmlinux'
+            for obj in gdb.objfiles():
+                if obj.filename.endswith('vmlinux'):
+                    orig_vmlinux = obj.filename
+            gdb.execute("symbol-file", to_string=True)
+            gdb.execute("symbol-file {0}".format(orig_vmlinux))
+            self.loaded_modules = {}
+            module_list = modules.module_list()
+            if not module_list:
+                gdb.write("no modules found\n")
+            else:
+                [self._do_load_module_symbols(module) for module in module_list]
+        finally:
+            self._unprepare_for_module_load_unload()
 
-        for saved_state in saved_states:
-            saved_state['breakpoint'].enabled = saved_state['enabled']
+        self._unprepare_for_module_load_unload()
 
     def invoke(self, arg, from_tty):
         self.module_paths = [os.path.expanduser(p) for p in arg.split()]
         self.module_paths.append(os.getcwd())
 
+        try:
+            gdb.parse_and_eval("*start_kernel").fetch_lazy()
+        except gdb.MemoryError:
+            gdb.write("Error: Kernel is not yet loaded\n")
+            return
+
         # enforce update
         self.module_files = []
         self.module_files_updated = False
 
+        for bp in self.internal_breakpoints:
+            bp.delete()
+        self.internal_breakpoints = []
+
         self.load_all_symbols()
 
         if hasattr(gdb, 'Breakpoint'):
-            if self.breakpoint is not None:
-                self.breakpoint.delete()
-                self.breakpoint = None
-            self.breakpoint = LoadModuleBreakpoint(
-                "kernel/module.c:do_init_module", self)
+            self.internal_breakpoints.append(
+                BreakpointWrapper(self.load_module_symbols,
+                                  spec="kernel/module.c:do_init_module",
+                                  ))
+            self.internal_breakpoints.append(
+                BreakpointWrapper(self.unload_module_symbols,
+                                  spec="kernel/module.c:free_module",
+                                  ))
         else:
             gdb.write("Note: symbol update on module loading not supported "
                       "with this gdb version\n")
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 2/9] KVM: introduce KVM_CAP_SET_GUEST_DEBUG2
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 1/9] scripts/gdb: rework lx-symbols gdb script Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 3/9] KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2 Maxim Levitsky
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

This capability will allow the user to know which KVM_GUESTDBG_* bits
are supported.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 Documentation/virt/kvm/api.rst | 3 +++
 include/uapi/linux/kvm.h       | 1 +
 2 files changed, 4 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 38e327d4b479..9778b2434c03 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -3357,6 +3357,9 @@ indicating the number of supported registers.
 For ppc, the KVM_CAP_PPC_GUEST_DEBUG_SSTEP capability indicates whether
 the single-step debug event (KVM_GUESTDBG_SINGLESTEP) is supported.
 
+Also when supported, KVM_CAP_SET_GUEST_DEBUG2 capability indicates the
+supported KVM_GUESTDBG_* bits in the control field.
+
 When debug events exit the main run loop with the reason
 KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
 structure containing architecture specific debug information.
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index f6afee209620..727010788eff 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1078,6 +1078,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_DIRTY_LOG_RING 192
 #define KVM_CAP_X86_BUS_LOCK_EXIT 193
 #define KVM_CAP_PPC_DAWR1 194
+#define KVM_CAP_SET_GUEST_DEBUG2 195
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 3/9] KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 1/9] scripts/gdb: rework lx-symbols gdb script Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 2/9] KVM: introduce KVM_CAP_SET_GUEST_DEBUG2 Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 4/9] KVM: aarch64: " Maxim Levitsky
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

Store the supported bits into KVM_GUESTDBG_VALID_MASK
macro, similar to how arm does this.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 arch/x86/include/asm/kvm_host.h | 9 +++++++++
 arch/x86/kvm/x86.c              | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a52f973bdff6..cc7c82a449d5 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -221,6 +221,15 @@ enum x86_intercept_stage;
 #define DR7_FIXED_1	0x00000400
 #define DR7_VOLATILE	0xffff2bff
 
+#define KVM_GUESTDBG_VALID_MASK \
+	(KVM_GUESTDBG_ENABLE | \
+	KVM_GUESTDBG_SINGLESTEP | \
+	KVM_GUESTDBG_USE_HW_BP | \
+	KVM_GUESTDBG_USE_SW_BP | \
+	KVM_GUESTDBG_INJECT_BP | \
+	KVM_GUESTDBG_INJECT_DB)
+
+
 #define PFERR_PRESENT_BIT 0
 #define PFERR_WRITE_BIT 1
 #define PFERR_USER_BIT 2
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a9d95f90a048..956e8e0bd6af 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3798,6 +3798,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ENFORCE_PV_FEATURE_CPUID:
 		r = 1;
 		break;
+	case KVM_CAP_SET_GUEST_DEBUG2:
+		return KVM_GUESTDBG_VALID_MASK;
 #ifdef CONFIG_KVM_XEN
 	case KVM_CAP_XEN_HVM:
 		r = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR |
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 4/9] KVM: aarch64: implement KVM_CAP_SET_GUEST_DEBUG2
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
                   ` (2 preceding siblings ...)
  2021-04-01 13:54 ` [PATCH v2 3/9] KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2 Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 5/9] KVM: s390x: " Maxim Levitsky
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

Move KVM_GUESTDBG_VALID_MASK to kvm_host.h
and use it to return the value of this capability.
Compile tested only.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 arch/arm64/include/asm/kvm_host.h | 4 ++++
 arch/arm64/kvm/arm.c              | 2 ++
 arch/arm64/kvm/guest.c            | 5 -----
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3d10e6527f7d..613421454ab6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -401,6 +401,10 @@ struct kvm_vcpu_arch {
 #define KVM_ARM64_PENDING_EXCEPTION	(1 << 8) /* Exception pending */
 #define KVM_ARM64_EXCEPT_MASK		(7 << 9) /* Target EL/MODE */
 
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
+				 KVM_GUESTDBG_USE_SW_BP | \
+				 KVM_GUESTDBG_USE_HW | \
+				 KVM_GUESTDBG_SINGLESTEP)
 /*
  * When KVM_ARM64_PENDING_EXCEPTION is set, KVM_ARM64_EXCEPT_MASK can
  * take the following values:
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 7f06ba76698d..e575eff76e97 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -208,6 +208,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_VCPU_ATTRIBUTES:
 		r = 1;
 		break;
+	case KVM_CAP_SET_GUEST_DEBUG2:
+		return KVM_GUESTDBG_VALID_MASK;
 	case KVM_CAP_ARM_SET_DEVICE_ADDR:
 		r = 1;
 		break;
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 9bbd30e62799..6cb39ee74acd 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -888,11 +888,6 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 	return -EINVAL;
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |    \
-			    KVM_GUESTDBG_USE_SW_BP | \
-			    KVM_GUESTDBG_USE_HW | \
-			    KVM_GUESTDBG_SINGLESTEP)
-
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
  * @kvm:	pointer to the KVM struct
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 5/9] KVM: s390x: implement KVM_CAP_SET_GUEST_DEBUG2
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
                   ` (3 preceding siblings ...)
  2021-04-01 13:54 ` [PATCH v2 4/9] KVM: aarch64: " Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS Maxim Levitsky
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

Define KVM_GUESTDBG_VALID_MASK and use it to implement this capabiity.
Compile tested only.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 arch/s390/include/asm/kvm_host.h | 4 ++++
 arch/s390/kvm/kvm-s390.c         | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 6bcfc5614bbc..a3902b57b825 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -700,6 +700,10 @@ struct kvm_hw_bp_info_arch {
 #define guestdbg_exit_pending(vcpu) (guestdbg_enabled(vcpu) && \
 		(vcpu->guest_debug & KVM_GUESTDBG_EXIT_PENDING))
 
+#define KVM_GUESTDBG_VALID_MASK \
+		(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP |\
+		KVM_GUESTDBG_USE_HW_BP | KVM_GUESTDBG_EXIT_PENDING)
+
 struct kvm_guestdbg_info_arch {
 	unsigned long cr0;
 	unsigned long cr9;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 2f09e9d7dc95..2049fc8c222a 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -544,6 +544,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_S390_DIAG318:
 		r = 1;
 		break;
+	case KVM_CAP_SET_GUEST_DEBUG2:
+		r = KVM_GUESTDBG_VALID_MASK;
+		break;
 	case KVM_CAP_S390_HPAGE_1M:
 		r = 0;
 		if (hpage && !kvm_is_ucontrol(kvm))
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
                   ` (4 preceding siblings ...)
  2021-04-01 13:54 ` [PATCH v2 5/9] KVM: s390x: " Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-02 17:07   ` Paolo Bonzini
  2021-04-01 13:54 ` [PATCH v2 7/9] KVM: SVM: split svm_handle_invalid_exit Maxim Levitsky
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

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@redhat.com>
---
 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
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 7/9] KVM: SVM: split svm_handle_invalid_exit
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
                   ` (5 preceding siblings ...)
  2021-04-01 13:54 ` [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-01 13:54 ` [PATCH v2 8/9] KVM: x86: add force_intercept_exceptions_mask Maxim Levitsky
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

Split the check for having a vmexit handler to
svm_check_exit_valid, and make svm_handle_invalid_exit
only handle a vmexit that is already not valid.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 arch/x86/kvm/svm/svm.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 271196400495..2aa951bc470c 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3220,12 +3220,14 @@ static void dump_vmcb(struct kvm_vcpu *vcpu)
 	       "excp_to:", save->last_excp_to);
 }
 
-static int svm_handle_invalid_exit(struct kvm_vcpu *vcpu, u64 exit_code)
+static bool svm_check_exit_valid(struct kvm_vcpu *vcpu, u64 exit_code)
 {
-	if (exit_code < ARRAY_SIZE(svm_exit_handlers) &&
-	    svm_exit_handlers[exit_code])
-		return 0;
+	return (exit_code < ARRAY_SIZE(svm_exit_handlers) &&
+		svm_exit_handlers[exit_code]);
+}
 
+static int svm_handle_invalid_exit(struct kvm_vcpu *vcpu, u64 exit_code)
+{
 	vcpu_unimpl(vcpu, "svm: unexpected exit reason 0x%llx\n", exit_code);
 	dump_vmcb(vcpu);
 	vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
@@ -3233,14 +3235,13 @@ static int svm_handle_invalid_exit(struct kvm_vcpu *vcpu, u64 exit_code)
 	vcpu->run->internal.ndata = 2;
 	vcpu->run->internal.data[0] = exit_code;
 	vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu;
-
-	return -EINVAL;
+	return 0;
 }
 
 int svm_invoke_exit_handler(struct kvm_vcpu *vcpu, u64 exit_code)
 {
-	if (svm_handle_invalid_exit(vcpu, exit_code))
-		return 0;
+	if (!svm_check_exit_valid(vcpu, exit_code))
+		return svm_handle_invalid_exit(vcpu, exit_code);
 
 #ifdef CONFIG_RETPOLINE
 	if (exit_code == SVM_EXIT_MSR)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 8/9] KVM: x86: add force_intercept_exceptions_mask
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
                   ` (6 preceding siblings ...)
  2021-04-01 13:54 ` [PATCH v2 7/9] KVM: SVM: split svm_handle_invalid_exit Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-27 11:38   ` Borislav Petkov
  2021-04-01 13:54 ` [PATCH v2 9/9] KVM: SVM: implement force_intercept_exceptions_mask Maxim Levitsky
  2021-04-02 17:38 ` [PATCH v2 0/9] KVM: my debug patch queue Paolo Bonzini
  9 siblings, 1 reply; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse, Borislav Petkov

This parameter will be used by VMX and SVM code to force
interception of a set of exceptions, given by a bitmask
for guest debug and/or kvm debug.

This option is not intended for production.

This is based on an idea first shown here:
https://patchwork.kernel.org/project/kvm/patch/20160301192822.GD22677@pd.tnic/

CC: Borislav Petkov <bp@suse.de>
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 arch/x86/kvm/x86.c | 3 +++
 arch/x86/kvm/x86.h | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3627ce8fe5bb..1a51031d64d8 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -176,6 +176,9 @@ module_param(force_emulation_prefix, bool, S_IRUGO);
 int __read_mostly pi_inject_timer = -1;
 module_param(pi_inject_timer, bint, S_IRUGO | S_IWUSR);
 
+uint force_intercept_exceptions_mask;
+module_param(force_intercept_exceptions_mask, uint, S_IRUGO | S_IWUSR);
+EXPORT_SYMBOL_GPL(force_intercept_exceptions_mask);
 /*
  * Restoring the host value for MSRs that are only consumed when running in
  * usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index daccf20fbcd5..644480711ff7 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -311,6 +311,8 @@ extern struct static_key kvm_no_apic_vcpu;
 
 extern bool report_ignored_msrs;
 
+extern uint force_intercept_exceptions_mask;
+
 static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
 {
 	return pvclock_scale_delta(nsec, vcpu->arch.virtual_tsc_mult,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 9/9] KVM: SVM: implement force_intercept_exceptions_mask
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
                   ` (7 preceding siblings ...)
  2021-04-01 13:54 ` [PATCH v2 8/9] KVM: x86: add force_intercept_exceptions_mask Maxim Levitsky
@ 2021-04-01 13:54 ` Maxim Levitsky
  2021-04-02 17:38 ` [PATCH v2 0/9] KVM: my debug patch queue Paolo Bonzini
  9 siblings, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-01 13:54 UTC (permalink / raw)
  To: kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Maxim Levitsky, Wanpeng Li, Janosch Frank, Christian Borntraeger,
	open list:S390, Heiko Carstens, Kieran Bingham,
	open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

Currently #TS interception is only done once.
Also exception interception is not enabled for SEV guests.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 arch/x86/include/asm/kvm_host.h |  2 +
 arch/x86/kvm/svm/svm.c          | 70 +++++++++++++++++++++++++++++++++
 arch/x86/kvm/svm/svm.h          |  6 ++-
 arch/x86/kvm/x86.c              |  5 ++-
 4 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8c529ae9dbbe..d15ae64a2c4e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1574,6 +1574,8 @@ int kvm_emulate_rdpmc(struct kvm_vcpu *vcpu);
 void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload);
+void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr,
+			     u32 error_code, unsigned long payload);
 void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 2aa951bc470c..de7fd7922ec7 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -220,6 +220,8 @@ static const u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
 #define MSRS_RANGE_SIZE 2048
 #define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2)
 
+static int svm_handle_invalid_exit(struct kvm_vcpu *vcpu, u64 exit_code);
+
 u32 svm_msrpm_offset(u32 msr)
 {
 	u32 offset;
@@ -1113,6 +1115,22 @@ static void svm_check_invpcid(struct vcpu_svm *svm)
 	}
 }
 
+static void svm_init_force_exceptions_intercepts(struct vcpu_svm *svm)
+{
+	int exc;
+
+	svm->force_intercept_exceptions_mask = force_intercept_exceptions_mask;
+	for (exc = 0 ; exc < 32 ; exc++) {
+		if (!(svm->force_intercept_exceptions_mask & (1 << exc)))
+			continue;
+
+		/* Those are defined to have undefined behavior in the SVM spec */
+		if (exc != 2 && exc != 9)
+			continue;
+		set_exception_intercept(svm, exc);
+	}
+}
+
 static void init_vmcb(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -1288,6 +1306,9 @@ static void init_vmcb(struct kvm_vcpu *vcpu)
 
 	enable_gif(svm);
 
+	if (!sev_es_guest(vcpu->kvm))
+		svm_init_force_exceptions_intercepts(svm);
+
 }
 
 static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
@@ -1913,6 +1934,17 @@ static int pf_interception(struct kvm_vcpu *vcpu)
 	u64 fault_address = svm->vmcb->control.exit_info_2;
 	u64 error_code = svm->vmcb->control.exit_info_1;
 
+	if ((svm->force_intercept_exceptions_mask & (1 << PF_VECTOR)))
+		if (npt_enabled && !vcpu->arch.apf.host_apf_flags) {
+			/* If the #PF was only intercepted for debug, inject
+			 * it directly to the guest, since the kvm's mmu code
+			 * is not ready to deal with such page faults.
+			 */
+			kvm_queue_exception_e_p(vcpu, PF_VECTOR,
+						error_code, fault_address);
+			return 1;
+		}
+
 	return kvm_handle_page_fault(vcpu, error_code, fault_address,
 			static_cpu_has(X86_FEATURE_DECODEASSISTS) ?
 			svm->vmcb->control.insn_bytes : NULL,
@@ -1988,6 +2020,40 @@ static int ac_interception(struct kvm_vcpu *vcpu)
 	return 1;
 }
 
+static int gen_exc_interception(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * Generic exception intercept handler which forwards a guest exception
+	 * as-is to the guest.
+	 * For exceptions that don't have a special intercept handler.
+	 *
+	 * Used only for 'force_intercept_exceptions_mask' KVM debug feature.
+	 */
+	struct vcpu_svm *svm = to_svm(vcpu);
+	int exc = svm->vmcb->control.exit_code - SVM_EXIT_EXCP_BASE;
+
+	/* SVM doesn't provide us with an error code for the #DF */
+	u32 err_code = exc == DF_VECTOR ? 0 : svm->vmcb->control.exit_info_1;
+
+	if (!(svm->force_intercept_exceptions_mask & (1 << exc)))
+		return svm_handle_invalid_exit(vcpu, svm->vmcb->control.exit_code);
+
+	if (exc == TS_VECTOR) {
+		/*
+		 * SVM doesn't provide us with an error code to be able to
+		 * re-inject the #TS exception, so just disable its
+		 * intercept, and let the guest re-execute the instruction.
+		 */
+		vmcb_clr_intercept(&svm->vmcb01.ptr->control,
+				   INTERCEPT_EXCEPTION_OFFSET + TS_VECTOR);
+		recalc_intercepts(svm);
+	} else if (x86_exception_has_error_code(exc))
+		kvm_queue_exception_e(vcpu, exc, err_code);
+	else
+		kvm_queue_exception(vcpu, exc);
+	return 1;
+}
+
 static bool is_erratum_383(void)
 {
 	int err, i;
@@ -3051,6 +3117,10 @@ static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 	[SVM_EXIT_WRITE_DR5]			= dr_interception,
 	[SVM_EXIT_WRITE_DR6]			= dr_interception,
 	[SVM_EXIT_WRITE_DR7]			= dr_interception,
+
+	[SVM_EXIT_EXCP_BASE ...
+	SVM_EXIT_EXCP_BASE + 31]		= gen_exc_interception,
+
 	[SVM_EXIT_EXCP_BASE + DB_VECTOR]	= db_interception,
 	[SVM_EXIT_EXCP_BASE + BP_VECTOR]	= bp_interception,
 	[SVM_EXIT_EXCP_BASE + UD_VECTOR]	= ud_interception,
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 8e276c4fb33d..79d0aea87753 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -183,6 +183,7 @@ struct vcpu_svm {
 	bool ghcb_sa_free;
 
 	bool guest_state_loaded;
+	u32 force_intercept_exceptions_mask;
 };
 
 struct svm_cpu_data {
@@ -333,8 +334,11 @@ static inline void clr_exception_intercept(struct vcpu_svm *svm, u32 bit)
 	struct vmcb *vmcb = svm->vmcb01.ptr;
 
 	WARN_ON_ONCE(bit >= 32);
-	vmcb_clr_intercept(&vmcb->control, INTERCEPT_EXCEPTION_OFFSET + bit);
 
+	if ((1 << bit) & svm->force_intercept_exceptions_mask)
+		return;
+
+	vmcb_clr_intercept(&vmcb->control, INTERCEPT_EXCEPTION_OFFSET + bit);
 	recalc_intercepts(svm);
 }
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1a51031d64d8..ae57816fe6d9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -630,12 +630,13 @@ void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr,
 }
 EXPORT_SYMBOL_GPL(kvm_queue_exception_p);
 
-static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr,
-				    u32 error_code, unsigned long payload)
+void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr,
+			     u32 error_code, unsigned long payload)
 {
 	kvm_multiple_exception(vcpu, nr, true, error_code,
 			       true, payload, false);
 }
+EXPORT_SYMBOL_GPL(kvm_queue_exception_e_p);
 
 int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err)
 {
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS
  2021-04-01 13:54 ` [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS Maxim Levitsky
@ 2021-04-02 17:07   ` Paolo Bonzini
  0 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2021-04-02 17:07 UTC (permalink / raw)
  To: Maxim Levitsky, kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel, Claudio Imbrenda,
	Jim Mattson, Cornelia Huck, David Hildenbrand, Wanpeng Li,
	Janosch Frank, Christian Borntraeger, open list:S390,
	Heiko Carstens, Kieran Bingham, open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

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@redhat.com>

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
> 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/9] KVM: my debug patch queue
  2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
                   ` (8 preceding siblings ...)
  2021-04-01 13:54 ` [PATCH v2 9/9] KVM: SVM: implement force_intercept_exceptions_mask Maxim Levitsky
@ 2021-04-02 17:38 ` Paolo Bonzini
  2021-04-06 11:59   ` Maxim Levitsky
  2021-04-26 12:43   ` Maxim Levitsky
  9 siblings, 2 replies; 16+ messages in thread
From: Paolo Bonzini @ 2021-04-02 17:38 UTC (permalink / raw)
  To: Maxim Levitsky, kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel, Claudio Imbrenda,
	Jim Mattson, Cornelia Huck, David Hildenbrand, Wanpeng Li,
	Janosch Frank, Christian Borntraeger, open list:S390,
	Heiko Carstens, Kieran Bingham, open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

On 01/04/21 15:54, Maxim Levitsky wrote:
> Hi!
> 
> I would like to publish two debug features which were needed for other stuff
> I work on.
> 
> One is the reworked lx-symbols script which now actually works on at least
> gdb 9.1 (gdb 9.2 was reported to fail to load the debug symbols from the kernel
> for some reason, not related to this patch) and upstream qemu.

Queued patches 2-5 for now.  6 is okay but it needs a selftest. (e.g. 
using KVM_VCPU_SET_EVENTS) and the correct name for the constant.

Paolo

> The other feature is the ability to trap all guest exceptions (on SVM for now)
> and see them in kvmtrace prior to potential merge to double/triple fault.
> 
> This can be very useful and I already had to manually patch KVM a few
> times for this.
> I will, once time permits, implement this feature on Intel as well.
> 
> V2:
> 
>   * Some more refactoring and workarounds for lx-symbols script
> 
>   * added KVM_GUESTDBG_BLOCKEVENTS flag to enable 'block interrupts on
>     single step' together with KVM_CAP_SET_GUEST_DEBUG2 capability
>     to indicate which guest debug flags are supported.
> 
>     This is a replacement for unconditional block of interrupts on single
>     step that was done in previous version of this patch set.
>     Patches to qemu to use that feature will be sent soon.
> 
>   * Reworked the the 'intercept all exceptions for debug' feature according
>     to the review feedback:
> 
>     - renamed the parameter that enables the feature and
>       moved it to common kvm module.
>       (only SVM part is currently implemented though)
> 
>     - disable the feature for SEV guests as was suggested during the review
>     - made the vmexit table const again, as was suggested in the review as well.
> 
> Best regards,
> 	Maxim Levitsky
> 
> Maxim Levitsky (9):
>    scripts/gdb: rework lx-symbols gdb script
>    KVM: introduce KVM_CAP_SET_GUEST_DEBUG2
>    KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2
>    KVM: aarch64: implement KVM_CAP_SET_GUEST_DEBUG2
>    KVM: s390x: implement KVM_CAP_SET_GUEST_DEBUG2
>    KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS
>    KVM: SVM: split svm_handle_invalid_exit
>    KVM: x86: add force_intercept_exceptions_mask
>    KVM: SVM: implement force_intercept_exceptions_mask
> 
>   Documentation/virt/kvm/api.rst    |   4 +
>   arch/arm64/include/asm/kvm_host.h |   4 +
>   arch/arm64/kvm/arm.c              |   2 +
>   arch/arm64/kvm/guest.c            |   5 -
>   arch/s390/include/asm/kvm_host.h  |   4 +
>   arch/s390/kvm/kvm-s390.c          |   3 +
>   arch/x86/include/asm/kvm_host.h   |  12 ++
>   arch/x86/include/uapi/asm/kvm.h   |   1 +
>   arch/x86/kvm/svm/svm.c            |  87 +++++++++++--
>   arch/x86/kvm/svm/svm.h            |   6 +-
>   arch/x86/kvm/x86.c                |  14 ++-
>   arch/x86/kvm/x86.h                |   2 +
>   include/uapi/linux/kvm.h          |   1 +
>   kernel/module.c                   |   8 +-
>   scripts/gdb/linux/symbols.py      | 203 ++++++++++++++++++++----------
>   15 files changed, 272 insertions(+), 84 deletions(-)
> 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/9] KVM: my debug patch queue
  2021-04-02 17:38 ` [PATCH v2 0/9] KVM: my debug patch queue Paolo Bonzini
@ 2021-04-06 11:59   ` Maxim Levitsky
  2021-04-26 12:43   ` Maxim Levitsky
  1 sibling, 0 replies; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-06 11:59 UTC (permalink / raw)
  To: Paolo Bonzini, kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel, Claudio Imbrenda,
	Jim Mattson, Cornelia Huck, David Hildenbrand, Wanpeng Li,
	Janosch Frank, Christian Borntraeger, open list:S390,
	Heiko Carstens, Kieran Bingham, open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

On Fri, 2021-04-02 at 19:38 +0200, Paolo Bonzini wrote:
> On 01/04/21 15:54, Maxim Levitsky wrote:
> > Hi!
> > 
> > I would like to publish two debug features which were needed for other stuff
> > I work on.
> > 
> > One is the reworked lx-symbols script which now actually works on at least
> > gdb 9.1 (gdb 9.2 was reported to fail to load the debug symbols from the kernel
> > for some reason, not related to this patch) and upstream qemu.
> 
> Queued patches 2-5 for now.  6 is okay but it needs a selftest. (e.g. 
> using KVM_VCPU_SET_EVENTS) and the correct name for the constant.

Thanks!
I will do this very soon.

Best regards,
	Maxim Levitsky
> 
> Paolo
> 
> > The other feature is the ability to trap all guest exceptions (on SVM for now)
> > and see them in kvmtrace prior to potential merge to double/triple fault.
> > 
> > This can be very useful and I already had to manually patch KVM a few
> > times for this.
> > I will, once time permits, implement this feature on Intel as well.
> > 
> > V2:
> > 
> >   * Some more refactoring and workarounds for lx-symbols script
> > 
> >   * added KVM_GUESTDBG_BLOCKEVENTS flag to enable 'block interrupts on
> >     single step' together with KVM_CAP_SET_GUEST_DEBUG2 capability
> >     to indicate which guest debug flags are supported.
> > 
> >     This is a replacement for unconditional block of interrupts on single
> >     step that was done in previous version of this patch set.
> >     Patches to qemu to use that feature will be sent soon.
> > 
> >   * Reworked the the 'intercept all exceptions for debug' feature according
> >     to the review feedback:
> > 
> >     - renamed the parameter that enables the feature and
> >       moved it to common kvm module.
> >       (only SVM part is currently implemented though)
> > 
> >     - disable the feature for SEV guests as was suggested during the review
> >     - made the vmexit table const again, as was suggested in the review as well.
> > 
> > Best regards,
> > 	Maxim Levitsky
> > 
> > Maxim Levitsky (9):
> >    scripts/gdb: rework lx-symbols gdb script
> >    KVM: introduce KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: aarch64: implement KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: s390x: implement KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS
> >    KVM: SVM: split svm_handle_invalid_exit
> >    KVM: x86: add force_intercept_exceptions_mask
> >    KVM: SVM: implement force_intercept_exceptions_mask
> > 
> >   Documentation/virt/kvm/api.rst    |   4 +
> >   arch/arm64/include/asm/kvm_host.h |   4 +
> >   arch/arm64/kvm/arm.c              |   2 +
> >   arch/arm64/kvm/guest.c            |   5 -
> >   arch/s390/include/asm/kvm_host.h  |   4 +
> >   arch/s390/kvm/kvm-s390.c          |   3 +
> >   arch/x86/include/asm/kvm_host.h   |  12 ++
> >   arch/x86/include/uapi/asm/kvm.h   |   1 +
> >   arch/x86/kvm/svm/svm.c            |  87 +++++++++++--
> >   arch/x86/kvm/svm/svm.h            |   6 +-
> >   arch/x86/kvm/x86.c                |  14 ++-
> >   arch/x86/kvm/x86.h                |   2 +
> >   include/uapi/linux/kvm.h          |   1 +
> >   kernel/module.c                   |   8 +-
> >   scripts/gdb/linux/symbols.py      | 203 ++++++++++++++++++++----------
> >   15 files changed, 272 insertions(+), 84 deletions(-)
> > 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/9] KVM: my debug patch queue
  2021-04-02 17:38 ` [PATCH v2 0/9] KVM: my debug patch queue Paolo Bonzini
  2021-04-06 11:59   ` Maxim Levitsky
@ 2021-04-26 12:43   ` Maxim Levitsky
  2021-04-26 12:55     ` Paolo Bonzini
  1 sibling, 1 reply; 16+ messages in thread
From: Maxim Levitsky @ 2021-04-26 12:43 UTC (permalink / raw)
  To: Paolo Bonzini, kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel, Claudio Imbrenda,
	Jim Mattson, Cornelia Huck, David Hildenbrand, Wanpeng Li,
	Janosch Frank, Christian Borntraeger, open list:S390,
	Heiko Carstens, Kieran Bingham, open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

On Fri, 2021-04-02 at 10:38 -0700, Paolo Bonzini wrote:
> On 01/04/21 15:54, Maxim Levitsky wrote:
> > Hi!
> > 
> > I would like to publish two debug features which were needed for other stuff
> > I work on.
> > 
> > One is the reworked lx-symbols script which now actually works on at least
> > gdb 9.1 (gdb 9.2 was reported to fail to load the debug symbols from the kernel
> > for some reason, not related to this patch) and upstream qemu.
> 
> Queued patches 2-5 for now.  6 is okay but it needs a selftest. (e.g. 
> using KVM_VCPU_SET_EVENTS) and the correct name for the constant.
Do you mean to add a kvm-unit-test or to add a test to kernel's kvm unit tests
for this?

Best regards,
	Maxim Levitsky

> 
> Paolo
> 
> > The other feature is the ability to trap all guest exceptions (on SVM for now)
> > and see them in kvmtrace prior to potential merge to double/triple fault.
> > 
> > This can be very useful and I already had to manually patch KVM a few
> > times for this.
> > I will, once time permits, implement this feature on Intel as well.
> > 
> > V2:
> > 
> >   * Some more refactoring and workarounds for lx-symbols script
> > 
> >   * added KVM_GUESTDBG_BLOCKEVENTS flag to enable 'block interrupts on
> >     single step' together with KVM_CAP_SET_GUEST_DEBUG2 capability
> >     to indicate which guest debug flags are supported.
> > 
> >     This is a replacement for unconditional block of interrupts on single
> >     step that was done in previous version of this patch set.
> >     Patches to qemu to use that feature will be sent soon.
> > 
> >   * Reworked the the 'intercept all exceptions for debug' feature according
> >     to the review feedback:
> > 
> >     - renamed the parameter that enables the feature and
> >       moved it to common kvm module.
> >       (only SVM part is currently implemented though)
> > 
> >     - disable the feature for SEV guests as was suggested during the review
> >     - made the vmexit table const again, as was suggested in the review as well.
> > 
> > Best regards,
> > 	Maxim Levitsky
> > 
> > Maxim Levitsky (9):
> >    scripts/gdb: rework lx-symbols gdb script
> >    KVM: introduce KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: aarch64: implement KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: s390x: implement KVM_CAP_SET_GUEST_DEBUG2
> >    KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS
> >    KVM: SVM: split svm_handle_invalid_exit
> >    KVM: x86: add force_intercept_exceptions_mask
> >    KVM: SVM: implement force_intercept_exceptions_mask
> > 
> >   Documentation/virt/kvm/api.rst    |   4 +
> >   arch/arm64/include/asm/kvm_host.h |   4 +
> >   arch/arm64/kvm/arm.c              |   2 +
> >   arch/arm64/kvm/guest.c            |   5 -
> >   arch/s390/include/asm/kvm_host.h  |   4 +
> >   arch/s390/kvm/kvm-s390.c          |   3 +
> >   arch/x86/include/asm/kvm_host.h   |  12 ++
> >   arch/x86/include/uapi/asm/kvm.h   |   1 +
> >   arch/x86/kvm/svm/svm.c            |  87 +++++++++++--
> >   arch/x86/kvm/svm/svm.h            |   6 +-
> >   arch/x86/kvm/x86.c                |  14 ++-
> >   arch/x86/kvm/x86.h                |   2 +
> >   include/uapi/linux/kvm.h          |   1 +
> >   kernel/module.c                   |   8 +-
> >   scripts/gdb/linux/symbols.py      | 203 ++++++++++++++++++++----------
> >   15 files changed, 272 insertions(+), 84 deletions(-)
> > 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/9] KVM: my debug patch queue
  2021-04-26 12:43   ` Maxim Levitsky
@ 2021-04-26 12:55     ` Paolo Bonzini
  0 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2021-04-26 12:55 UTC (permalink / raw)
  To: Maxim Levitsky, kvm
  Cc: maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Borislav Petkov, Suzuki K Poulose,
	Jonathan Corbet, Jessica Yu, H. Peter Anvin, Jan Kiszka,
	Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel, Claudio Imbrenda,
	Jim Mattson, Cornelia Huck, David Hildenbrand, Wanpeng Li,
	Janosch Frank, Christian Borntraeger, open list:S390,
	Heiko Carstens, Kieran Bingham, open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

On 26/04/21 14:43, Maxim Levitsky wrote:
> On Fri, 2021-04-02 at 10:38 -0700, Paolo Bonzini wrote:
>> On 01/04/21 15:54, Maxim Levitsky wrote:
>>> Hi!
>>>
>>> I would like to publish two debug features which were needed for other stuff
>>> I work on.
>>>
>>> One is the reworked lx-symbols script which now actually works on at least
>>> gdb 9.1 (gdb 9.2 was reported to fail to load the debug symbols from the kernel
>>> for some reason, not related to this patch) and upstream qemu.
>>
>> Queued patches 2-5 for now.  6 is okay but it needs a selftest. (e.g.
>> using KVM_VCPU_SET_EVENTS) and the correct name for the constant.
> Do you mean to add a kvm-unit-test or to add a test to kernel's kvm unit tests
> for this?

selftests is used for those in the kernel.  "Unit test" can mean both, 
but usually it means kvm-unit-tests because they're easier to write.

Paolo


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 8/9] KVM: x86: add force_intercept_exceptions_mask
  2021-04-01 13:54 ` [PATCH v2 8/9] KVM: x86: add force_intercept_exceptions_mask Maxim Levitsky
@ 2021-04-27 11:38   ` Borislav Petkov
  0 siblings, 0 replies; 16+ messages in thread
From: Borislav Petkov @ 2021-04-27 11:38 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: kvm, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	Ingo Molnar, Andrew Morton, Thomas Gleixner, Sean Christopherson,
	Marc Zyngier, Catalin Marinas, open list, Julien Thierry,
	Stefano Garzarella, Suzuki K Poulose, Jonathan Corbet,
	Jessica Yu, H. Peter Anvin, Jan Kiszka, Will Deacon,
	open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	Paolo Bonzini, Vitaly Kuznetsov, Vasily Gorbik, Joerg Roedel,
	Claudio Imbrenda, Jim Mattson, Cornelia Huck, David Hildenbrand,
	Wanpeng Li, Janosch Frank, Christian Borntraeger, open list:S390,
	Heiko Carstens, Kieran Bingham, open list:DOCUMENTATION,
	moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64),
	James Morse

On Thu, Apr 01, 2021 at 04:54:50PM +0300, Maxim Levitsky wrote:
> This parameter will be used by VMX and SVM code to force
> interception of a set of exceptions, given by a bitmask
> for guest debug and/or kvm debug.
> 
> This option is not intended for production.
> 
> This is based on an idea first shown here:
> https://patchwork.kernel.org/project/kvm/patch/20160301192822.GD22677@pd.tnic/
> 
> CC: Borislav Petkov <bp@suse.de>
> Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
> ---
>  arch/x86/kvm/x86.c | 3 +++
>  arch/x86/kvm/x86.h | 2 ++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 3627ce8fe5bb..1a51031d64d8 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -176,6 +176,9 @@ module_param(force_emulation_prefix, bool, S_IRUGO);
>  int __read_mostly pi_inject_timer = -1;
>  module_param(pi_inject_timer, bint, S_IRUGO | S_IWUSR);
>  
> +uint force_intercept_exceptions_mask;
> +module_param(force_intercept_exceptions_mask, uint, S_IRUGO | S_IWUSR);
> +EXPORT_SYMBOL_GPL(force_intercept_exceptions_mask);

That's nice.

I could use some text explaning the usage though, i.e. that thing takes
a bitfield of exception vectors, so that I don't have to look at the
code each time. :-)

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-04-27 11:38 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-01 13:54 [PATCH v2 0/9] KVM: my debug patch queue Maxim Levitsky
2021-04-01 13:54 ` [PATCH v2 1/9] scripts/gdb: rework lx-symbols gdb script Maxim Levitsky
2021-04-01 13:54 ` [PATCH v2 2/9] KVM: introduce KVM_CAP_SET_GUEST_DEBUG2 Maxim Levitsky
2021-04-01 13:54 ` [PATCH v2 3/9] KVM: x86: implement KVM_CAP_SET_GUEST_DEBUG2 Maxim Levitsky
2021-04-01 13:54 ` [PATCH v2 4/9] KVM: aarch64: " Maxim Levitsky
2021-04-01 13:54 ` [PATCH v2 5/9] KVM: s390x: " Maxim Levitsky
2021-04-01 13:54 ` [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS Maxim Levitsky
2021-04-02 17:07   ` Paolo Bonzini
2021-04-01 13:54 ` [PATCH v2 7/9] KVM: SVM: split svm_handle_invalid_exit Maxim Levitsky
2021-04-01 13:54 ` [PATCH v2 8/9] KVM: x86: add force_intercept_exceptions_mask Maxim Levitsky
2021-04-27 11:38   ` Borislav Petkov
2021-04-01 13:54 ` [PATCH v2 9/9] KVM: SVM: implement force_intercept_exceptions_mask Maxim Levitsky
2021-04-02 17:38 ` [PATCH v2 0/9] KVM: my debug patch queue Paolo Bonzini
2021-04-06 11:59   ` Maxim Levitsky
2021-04-26 12:43   ` Maxim Levitsky
2021-04-26 12:55     ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).