Commit 7d6a31c3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 debug updates from Ingo Molnar:
 "The biggest update is the addition of USB3 debug port based
  early-console.

  Greg was fine with the USB changes and with the routing of these
  patches:

    https://www.spinics.net/lists/linux-usb/msg155093.html"

* 'x86-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  usb/doc: Add document for USB3 debug port usage
  usb/serial: Add DBC debug device support to usb_debug
  x86/earlyprintk: Add support for earlyprintk via USB3 debug port
  usb/early: Add driver for xhci debug capability
  x86/timers: Add simple udelay calibration
parents 2cc12e2e 1b326277
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -988,6 +988,7 @@
			earlyprintk=ttySn[,baudrate]
			earlyprintk=dbgp[debugController#]
			earlyprintk=pciserial,bus:device.function[,baudrate]
			earlyprintk=xdbc[xhciController#]

			earlyprintk is useful when the kernel crashes before
			the normal console is initialized. It is not enabled by
+100 −0
Original line number Diff line number Diff line
===============
USB3 debug port
===============

:Author: Lu Baolu <baolu.lu@linux.intel.com>
:Date: March 2017

GENERAL
=======

This is a HOWTO for using the USB3 debug port on x86 systems.

Before using any kernel debugging functionality based on USB3
debug port, you need to::

	1) check whether any USB3 debug port is available in
	   your system;
	2) check which port is used for debugging purposes;
	3) have a USB 3.0 super-speed A-to-A debugging cable.

INTRODUCTION
============

The xHCI debug capability (DbC) is an optional but standalone
functionality provided by the xHCI host controller. The xHCI
specification describes DbC in the section 7.6.

When DbC is initialized and enabled, it will present a debug
device through the debug port (normally the first USB3
super-speed port). The debug device is fully compliant with
the USB framework and provides the equivalent of a very high
performance full-duplex serial link between the debug target
(the system under debugging) and a debug host.

EARLY PRINTK
============

DbC has been designed to log early printk messages. One use for
this feature is kernel debugging. For example, when your machine
crashes very early before the regular console code is initialized.
Other uses include simpler, lockless logging instead of a full-
blown printk console driver and klogd.

On the debug target system, you need to customize a debugging
kernel with CONFIG_EARLY_PRINTK_USB_XDBC enabled. And, add below
kernel boot parameter::

	"earlyprintk=xdbc"

If there are multiple xHCI controllers in your system, you can
append a host contoller index to this kernel parameter. This
index starts from 0.

Current design doesn't support DbC runtime suspend/resume. As
the result, you'd better disable runtime power management for
USB subsystem by adding below kernel boot parameter::

	"usbcore.autosuspend=-1"

Before starting the debug target, you should connect the debug
port to a USB port (root port or port of any external hub) on
the debug host. The cable used to connect these two ports
should be a USB 3.0 super-speed A-to-A debugging cable.

During early boot of the debug target, DbC will be detected and
initialized. After initialization, the debug host should be able
to enumerate the debug device in debug target. The debug host
will then bind the debug device with the usb_debug driver module
and create the /dev/ttyUSB device.

If the debug device enumeration goes smoothly, you should be able
to see below kernel messages on the debug host::

	# tail -f /var/log/kern.log
	[ 1815.983374] usb 4-3: new SuperSpeed USB device number 4 using xhci_hcd
	[ 1815.999595] usb 4-3: LPM exit latency is zeroed, disabling LPM.
	[ 1815.999899] usb 4-3: New USB device found, idVendor=1d6b, idProduct=0004
	[ 1815.999902] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
	[ 1815.999903] usb 4-3: Product: Remote GDB
	[ 1815.999904] usb 4-3: Manufacturer: Linux
	[ 1815.999905] usb 4-3: SerialNumber: 0001
	[ 1816.000240] usb_debug 4-3:1.0: xhci_dbc converter detected
	[ 1816.000360] usb 4-3: xhci_dbc converter now attached to ttyUSB0

You can use any communication program, for example minicom, to
read and view the messages. Below simple bash scripts can help
you to check the sanity of the setup.

.. code-block:: sh

	===== start of bash scripts =============
	#!/bin/bash

	while true ; do
		while [ ! -d /sys/class/tty/ttyUSB0 ] ; do
			:
		done
	cat /dev/ttyUSB0
	done
	===== end of bash scripts ===============
+25 −2
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@ config TRACE_IRQFLAGS_SUPPORT

source "lib/Kconfig.debug"

config EARLY_PRINTK_USB
	bool

config X86_VERBOSE_BOOTUP
	bool "Enable verbose x86 bootup info messages"
	default y
@@ -23,19 +26,20 @@ config EARLY_PRINTK
	  This is useful for kernel debugging when your machine crashes very
	  early before the console code is initialized. For normal operation
	  it is not recommended because it looks ugly and doesn't cooperate
	  with klogd/syslogd or the X server. You should normally N here,
	  with klogd/syslogd or the X server. You should normally say N here,
	  unless you want to debug such a crash.

config EARLY_PRINTK_DBGP
	bool "Early printk via EHCI debug port"
	depends on EARLY_PRINTK && PCI
	select EARLY_PRINTK_USB
	---help---
	  Write kernel log output directly into the EHCI debug port.

	  This is useful for kernel debugging when your machine crashes very
	  early before the console code is initialized. For normal operation
	  it is not recommended because it looks ugly and doesn't cooperate
	  with klogd/syslogd or the X server. You should normally N here,
	  with klogd/syslogd or the X server. You should normally say N here,
	  unless you want to debug such a crash. You need usb debug device.

config EARLY_PRINTK_EFI
@@ -48,6 +52,25 @@ config EARLY_PRINTK_EFI
	  This is useful for kernel debugging when your machine crashes very
	  early before the console code is initialized.

config EARLY_PRINTK_USB_XDBC
	bool "Early printk via the xHCI debug port"
	depends on EARLY_PRINTK && PCI
	select EARLY_PRINTK_USB
	---help---
	  Write kernel log output directly into the xHCI debug port.

	  One use for this feature is kernel debugging, for example when your
	  machine crashes very early before the regular console code is
	  initialized. Other uses include simpler, lockless logging instead of
	  a full-blown printk console driver + klogd.

	  For normal production environments this is normally not recommended,
	  because it doesn't feed events into klogd/syslogd and doesn't try to
	  print anything on the screen.

	  You should normally say N here, unless you want to debug early
	  crashes or need a very simple printk logging facility.

config X86_PTDUMP_CORE
	def_bool n

+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <asm/intel-mid.h>
#include <asm/pgtable.h>
#include <linux/usb/ehci_def.h>
#include <linux/usb/xhci-dbgp.h>
#include <linux/efi.h>
#include <asm/efi.h>
#include <asm/pci_x86.h>
@@ -381,6 +382,10 @@ static int __init setup_early_printk(char *buf)
		if (!strncmp(buf, "efi", 3))
			early_console_register(&early_efi_console, keep);
#endif
#ifdef CONFIG_EARLY_PRINTK_USB_XDBC
		if (!strncmp(buf, "xdbc", 4))
			early_xdbc_parse_parameter(buf + 4);
#endif

		buf++;
	}
+26 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@
#include <linux/tboot.h>
#include <linux/jiffies.h>

#include <linux/usb/xhci-dbgp.h>
#include <video/edid.h>

#include <asm/mtrr.h>
@@ -811,6 +812,26 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
	return 0;
}

static void __init simple_udelay_calibration(void)
{
	unsigned int tsc_khz, cpu_khz;
	unsigned long lpj;

	if (!boot_cpu_has(X86_FEATURE_TSC))
		return;

	cpu_khz = x86_platform.calibrate_cpu();
	tsc_khz = x86_platform.calibrate_tsc();

	tsc_khz = tsc_khz ? : cpu_khz;
	if (!tsc_khz)
		return;

	lpj = tsc_khz * 1000;
	do_div(lpj, HZ);
	loops_per_jiffy = lpj;
}

/*
 * Determine if we were loaded by an EFI loader.  If so, then we have also been
 * passed the efi memmap, systab, etc., so we should use these data structures
@@ -959,6 +980,8 @@ void __init setup_arch(char **cmdline_p)
	 */
	x86_configure_nx();

	simple_udelay_calibration();

	parse_early_param();

#ifdef CONFIG_MEMORY_HOTPLUG
@@ -1095,6 +1118,9 @@ void __init setup_arch(char **cmdline_p)
	memblock_set_current_limit(ISA_END_ADDRESS);
	e820__memblock_setup();

	if (!early_xdbc_setup_hardware())
		early_xdbc_register_console();

	reserve_bios_regions();

	if (efi_enabled(EFI_MEMMAP)) {
Loading