Revision f4e61f0c9add3b00bd5f2df3c814d688849b8707 authored by Wanpeng Li on 15 March 2021, 06:55:28 UTC, committed by Paolo Bonzini on 18 March 2021, 17:58:14 UTC
After commit 997acaf6b4b59c (lockdep: report broken irq restoration), the guest
splatting below during boot:

 raw_local_irq_restore() called with IRQs enabled
 WARNING: CPU: 1 PID: 169 at kernel/locking/irqflag-debug.c:10 warn_bogus_irq_restore+0x26/0x30
 Modules linked in: hid_generic usbhid hid
 CPU: 1 PID: 169 Comm: systemd-udevd Not tainted 5.11.0+ #25
 RIP: 0010:warn_bogus_irq_restore+0x26/0x30
 Call Trace:
  kvm_wait+0x76/0x90
  __pv_queued_spin_lock_slowpath+0x285/0x2e0
  do_raw_spin_lock+0xc9/0xd0
  _raw_spin_lock+0x59/0x70
  lockref_get_not_dead+0xf/0x50
  __legitimize_path+0x31/0x60
  legitimize_root+0x37/0x50
  try_to_unlazy_next+0x7f/0x1d0
  lookup_fast+0xb0/0x170
  path_openat+0x165/0x9b0
  do_filp_open+0x99/0x110
  do_sys_openat2+0x1f1/0x2e0
  do_sys_open+0x5c/0x80
  __x64_sys_open+0x21/0x30
  do_syscall_64+0x32/0x50
  entry_SYSCALL_64_after_hwframe+0x44/0xae

The new consistency checking,  expects local_irq_save() and
local_irq_restore() to be paired and sanely nested, and therefore expects
local_irq_restore() to be called with irqs disabled.
The irqflags handling in kvm_wait() which ends up doing:

	local_irq_save(flags);
	safe_halt();
	local_irq_restore(flags);

instead triggers it.  This patch fixes it by using
local_irq_disable()/enable() directly.

Cc: Thomas Gleixner <tglx@linutronix.de>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
Message-Id: <1615791328-2735-1-git-send-email-wanpengli@tencent.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent c2162e1
Raw File
ver_linux
#!/usr/bin/awk -f
# SPDX-License-Identifier: GPL-2.0
# Before running this script please ensure that your PATH is
# typical as you use for compilation/installation. I use
# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
# differ on your system.

BEGIN {
	usage = "If some fields are empty or look unusual you may have an old version.\n"
	usage = usage "Compare to the current minimal requirements in Documentation/Changes.\n"
	print usage

	system("uname -a")
	printf("\n")

	vernum = "[0-9]+([.]?[0-9]+)+"
	libc = "libc[.]so[.][0-9]+$"
	libcpp = "(libg|stdc)[+]+[.]so([.][0-9]+)+$"

	printversion("GNU C", version("gcc -dumpversion"))
	printversion("GNU Make", version("make --version"))
	printversion("Binutils", version("ld -v"))
	printversion("Util-linux", version("mount --version"))
	printversion("Mount", version("mount --version"))
	printversion("Module-init-tools", version("depmod -V"))
	printversion("E2fsprogs", version("tune2fs"))
	printversion("Jfsutils", version("fsck.jfs -V"))
	printversion("Reiserfsprogs", version("reiserfsck -V"))
	printversion("Reiser4fsprogs", version("fsck.reiser4 -V"))
	printversion("Xfsprogs", version("xfs_db -V"))
	printversion("Pcmciautils", version("pccardctl -V"))
	printversion("Pcmcia-cs", version("cardmgr -V"))
	printversion("Quota-tools", version("quota -V"))
	printversion("PPP", version("pppd --version"))
	printversion("Isdn4k-utils", version("isdnctrl"))
	printversion("Nfs-utils", version("showmount --version"))
	printversion("Bison", version("bison --version"))
	printversion("Flex", version("flex --version"))

	while ("ldconfig -p 2>/dev/null" | getline > 0)
		if ($NF ~ libc || $NF ~ libcpp)
			if (!seen[ver = version("readlink " $NF)]++)
				printversion("Linux C" ($NF ~ libcpp? "++" : "") " Library", ver)

	printversion("Dynamic linker (ldd)", version("ldd --version"))
	printversion("Procps", version("ps --version"))
	printversion("Net-tools", version("ifconfig --version"))
	printversion("Kbd", version("loadkeys -V"))
	printversion("Console-tools", version("loadkeys -V"))
	printversion("Oprofile", version("oprofiled --version"))
	printversion("Sh-utils", version("expr --v"))
	printversion("Udev", version("udevadm --version"))
	printversion("Wireless-tools", version("iwconfig --version"))

	while ("sort /proc/modules" | getline > 0) {
		mods = mods sep $1
		sep = " "
	}
	printversion("Modules Loaded", mods)
}

function version(cmd,    ver) {
	cmd = cmd " 2>&1"
	while (cmd | getline > 0) {
		if (match($0, vernum)) {
			ver = substr($0, RSTART, RLENGTH)
			break
		}
	}
	close(cmd)
	return ver
}

function printversion(name, value,  ofmt) {
	if (value != "") {
		ofmt = "%-20s\t%s\n"
		printf(ofmt, name, value)
	}
}
back to top