From patchwork Wed Aug 11 12:29:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 495424 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4724C432BE for ; Wed, 11 Aug 2021 12:30:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9DE8361008 for ; Wed, 11 Aug 2021 12:30:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230107AbhHKMak (ORCPT ); Wed, 11 Aug 2021 08:30:40 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:43525 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231778AbhHKMaR (ORCPT ); Wed, 11 Aug 2021 08:30:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1628684993; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L2zltoeBUaiiUWd903sk/fd+wquvy5ZlpMpjy5zL9F8=; b=IbsCfNpI9PRRV3w7Yg2xV0sPhYTGa8mRkqZA3ZkCr/8PIgkrAmvKfLfjdQoqSDJbceIAZ2 C+NFv3GAbm4TyceY2XWmWCk19oZmzJXckuf1P5t5ox4tYTm1U7p7pCZBmAvffCfEj2A9cC 8Qukp5HDcvjAPDO0ruM0H/f6ykwoNcQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-414-Dv_T0RRpNGOnprh8ybR84w-1; Wed, 11 Aug 2021 08:29:52 -0400 X-MC-Unique: Dv_T0RRpNGOnprh8ybR84w-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 210F0192D787; Wed, 11 Aug 2021 12:29:50 +0000 (UTC) Received: from localhost.localdomain (unknown [10.35.206.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 716085D9C6; Wed, 11 Aug 2021 12:29:42 +0000 (UTC) From: Maxim Levitsky To: kvm@vger.kernel.org Cc: Kieran Bingham , Jan Kiszka , Andrew Jones , Jonathan Corbet , Maxim Levitsky , Vitaly Kuznetsov , Sean Christopherson , Ingo Molnar , Thomas Gleixner , x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)), Johannes Berg , Wanpeng Li , "H. Peter Anvin" , Jessica Yu , Jim Mattson , Paolo Bonzini , Joerg Roedel , Yang Weijiang , linux-kernel@vger.kernel.org, Borislav Petkov , linux-kselftest@vger.kernel.org (open list:KERNEL SELFTEST FRAMEWORK), linux-doc@vger.kernel.org (open list:DOCUMENTATION), Shuah Khan , Andrew Morton , Borislav Petkov Subject: [PATCH v3 2/6] KVM: x86: add force_intercept_exceptions_mask Date: Wed, 11 Aug 2021 15:29:23 +0300 Message-Id: <20210811122927.900604-3-mlevitsk@redhat.com> In-Reply-To: <20210811122927.900604-1-mlevitsk@redhat.com> References: <20210811122927.900604-1-mlevitsk@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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 is based on an idea first shown here: https://patchwork.kernel.org/project/kvm/patch/20160301192822.GD22677@pd.tnic/ CC: Borislav Petkov Signed-off-by: Maxim Levitsky --- 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 fdc0c18339fb..092e2fad3c0d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -184,6 +184,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 7d66d63dc55a..2b59825213c7 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -347,6 +347,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, From patchwork Wed Aug 11 12:29:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 495423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 391A8C4320E for ; Wed, 11 Aug 2021 12:30:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1BE4D61102 for ; Wed, 11 Aug 2021 12:30:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229791AbhHKMbM (ORCPT ); Wed, 11 Aug 2021 08:31:12 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:39267 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237702AbhHKMav (ORCPT ); Wed, 11 Aug 2021 08:30:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1628685020; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FhI+Jpw21wRyiXw1xpRGiUEgUtxFY2GpZUIIqD4wt6g=; b=XAEKCwSS6W4YkoWy1UfHmle0GTxAhxWKRqnBiXC/46B1lO+YgBV//wgoq5i+qs/0mMvQUa nvGmM686yGEnfzhYcac4+YxAcEgxq4P+MhcaghaFPN21DcdUFvecaXvy3XBqJ4PDLm6xnD rZIEysO071dXftIt0Wph1c54Pn/SREM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-431-UxsCJig1M7Gd3ch-y8Eh3A-1; Wed, 11 Aug 2021 08:30:17 -0400 X-MC-Unique: UxsCJig1M7Gd3ch-y8Eh3A-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8E168100808D; Wed, 11 Aug 2021 12:30:14 +0000 (UTC) Received: from localhost.localdomain (unknown [10.35.206.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 943965D9C6; Wed, 11 Aug 2021 12:29:59 +0000 (UTC) From: Maxim Levitsky To: kvm@vger.kernel.org Cc: Kieran Bingham , Jan Kiszka , Andrew Jones , Jonathan Corbet , Maxim Levitsky , Vitaly Kuznetsov , Sean Christopherson , Ingo Molnar , Thomas Gleixner , x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)), Johannes Berg , Wanpeng Li , "H. Peter Anvin" , Jessica Yu , Jim Mattson , Paolo Bonzini , Joerg Roedel , Yang Weijiang , linux-kernel@vger.kernel.org, Borislav Petkov , linux-kselftest@vger.kernel.org (open list:KERNEL SELFTEST FRAMEWORK), linux-doc@vger.kernel.org (open list:DOCUMENTATION), Shuah Khan , Andrew Morton Subject: [PATCH v3 4/6] scripts/gdb: rework lx-symbols gdb script Date: Wed, 11 Aug 2021 15:29:25 +0300 Message-Id: <20210811122927.900604-5-mlevitsk@redhat.com> In-Reply-To: <20210811122927.900604-1-mlevitsk@redhat.com> References: <20210811122927.900604-1-mlevitsk@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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 the script is running as this seems to crash gdb * Add a basic check that kernel is already loaded into the guest memory to avoid confusing errors. Signed-off-by: Maxim Levitsky --- 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 ed13917ea5f3..242bd4bb0b55 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -906,8 +906,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 08d264ac328b..78e278fb4bad 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,56 +145,112 @@ 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.abspath(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") From patchwork Wed Aug 11 12:29:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 495422 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B78CC4338F for ; Wed, 11 Aug 2021 12:31:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6DC8661058 for ; Wed, 11 Aug 2021 12:31:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230082AbhHKMba (ORCPT ); Wed, 11 Aug 2021 08:31:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:43739 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230242AbhHKMbM (ORCPT ); Wed, 11 Aug 2021 08:31:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1628685048; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4e6sjxP1xMCtgKIkc/C7Ht738Uh5NYfem9ykOOCFrHo=; b=Ary+uH/D/YBSoN8vjgBwvPbAiHeqQ2UhFGeRqpeiCg9GqNLk++Cnv5MLYwnpOyBe+gsTGq C+t+LvmnRZ6sYqiIv2MUdnyRfoNNr02o1UIPoq3SVQKCZ6Vnj0M+XSeXInzIv6u6nIpmoc Z3Wt1+RHPfPlvwrytc7gKhuUU+zkslU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-559-vy3N7G0qPJ-MzSfqhPkfZQ-1; Wed, 11 Aug 2021 08:30:45 -0400 X-MC-Unique: vy3N7G0qPJ-MzSfqhPkfZQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DAD40801A92; Wed, 11 Aug 2021 12:30:41 +0000 (UTC) Received: from localhost.localdomain (unknown [10.35.206.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id EAFB95D9C6; Wed, 11 Aug 2021 12:30:30 +0000 (UTC) From: Maxim Levitsky To: kvm@vger.kernel.org Cc: Kieran Bingham , Jan Kiszka , Andrew Jones , Jonathan Corbet , Maxim Levitsky , Vitaly Kuznetsov , Sean Christopherson , Ingo Molnar , Thomas Gleixner , x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)), Johannes Berg , Wanpeng Li , "H. Peter Anvin" , Jessica Yu , Jim Mattson , Paolo Bonzini , Joerg Roedel , Yang Weijiang , linux-kernel@vger.kernel.org, Borislav Petkov , linux-kselftest@vger.kernel.org (open list:KERNEL SELFTEST FRAMEWORK), linux-doc@vger.kernel.org (open list:DOCUMENTATION), Shuah Khan , Andrew Morton Subject: [PATCH v3 6/6] KVM: selftests: test KVM_GUESTDBG_BLOCKIRQ Date: Wed, 11 Aug 2021 15:29:27 +0300 Message-Id: <20210811122927.900604-7-mlevitsk@redhat.com> In-Reply-To: <20210811122927.900604-1-mlevitsk@redhat.com> References: <20210811122927.900604-1-mlevitsk@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Modify debug_regs test to create a pending interrupt and see that it is blocked when single stepping is done with KVM_GUESTDBG_BLOCKIRQ Signed-off-by: Maxim Levitsky --- .../testing/selftests/kvm/x86_64/debug_regs.c | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/x86_64/debug_regs.c b/tools/testing/selftests/kvm/x86_64/debug_regs.c index 6097a8283377..5f078db1bcba 100644 --- a/tools/testing/selftests/kvm/x86_64/debug_regs.c +++ b/tools/testing/selftests/kvm/x86_64/debug_regs.c @@ -8,12 +8,15 @@ #include #include "kvm_util.h" #include "processor.h" +#include "apic.h" #define VCPU_ID 0 #define DR6_BD (1 << 13) #define DR7_GD (1 << 13) +#define IRQ_VECTOR 0xAA + /* For testing data access debug BP */ uint32_t guest_value; @@ -21,6 +24,11 @@ extern unsigned char sw_bp, hw_bp, write_data, ss_start, bd_start; static void guest_code(void) { + /* Create a pending interrupt on current vCPU */ + x2apic_enable(); + x2apic_write_reg(APIC_ICR, APIC_DEST_SELF | APIC_INT_ASSERT | + APIC_DM_FIXED | IRQ_VECTOR); + /* * Software BP tests. * @@ -38,12 +46,19 @@ static void guest_code(void) "mov %%rax,%0;\n\t write_data:" : "=m" (guest_value) : : "rax"); - /* Single step test, covers 2 basic instructions and 2 emulated */ + /* + * Single step test, covers 2 basic instructions and 2 emulated + * + * Enable interrupts during the single stepping to see that + * pending interrupt we raised is not handled due to KVM_GUESTDBG_BLOCKIRQ + */ asm volatile("ss_start: " + "sti\n\t" "xor %%eax,%%eax\n\t" "cpuid\n\t" "movl $0x1a0,%%ecx\n\t" "rdmsr\n\t" + "cli\n\t" : : : "eax", "ebx", "ecx", "edx"); /* DR6.BD test */ @@ -72,11 +87,13 @@ int main(void) uint64_t cmd; int i; /* Instruction lengths starting at ss_start */ - int ss_size[4] = { + int ss_size[6] = { + 1, /* sti*/ 2, /* xor */ 2, /* cpuid */ 5, /* mov */ 2, /* rdmsr */ + 1, /* cli */ }; if (!kvm_check_cap(KVM_CAP_SET_GUEST_DEBUG)) { @@ -154,7 +171,8 @@ int main(void) for (i = 0; i < (sizeof(ss_size) / sizeof(ss_size[0])); i++) { target_rip += ss_size[i]; CLEAR_DEBUG(); - debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; + debug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP | + KVM_GUESTDBG_BLOCKIRQ; debug.arch.debugreg[7] = 0x00000400; APPLY_DEBUG(); vcpu_run(vm, VCPU_ID);