11

I have an Alienware Aurora R7, running Arch Linux. On shutdown, the kernel panics, with something like this in the panic message (omitting timestamps):

BUG: Unable to handle kernel NULL pointer dereference at     (null)
IP: i2c_dw_isr+0x3ef/0x6d0
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI

From various sources (1, 2), this seems to be related to the i2c-designware-core module, and the workaround is blacklisting it. However, with recent kernels (seems to be 4.10 and above), this doesn't seem to be built as a module:

# uname -srv                      
Linux 4.15.2-2-ARCH #1 SMP PREEMPT Thu Feb 8 18:54:52 UTC 2018
# zgrep DESIGNWARE /proc/config.gz
CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_DESIGNWARE_SLAVE=y
CONFIG_I2C_DESIGNWARE_PCI=m
CONFIG_I2C_DESIGNWARE_BAYTRAIL=y
CONFIG_SPI_DESIGNWARE=m
CONFIG_SND_DESIGNWARE_I2S=m
CONFIG_SND_DESIGNWARE_PCM=y

So I have resorted to making the kernel reboot on panic:

# cat /proc/cmdline
root=UUID=e5018f7e-5838-4a47-b146-fc1614673356 rw initrd=/intel-ucode.img initrd=/initramfs-linux.img panic=10 sysrq_always_enabled=1 printk.devkmsg=on

(The odd paths in the /proc/cmdline are because I boot directly from UEFI, with entries created using efibootmgr. The paths are rooted at /boot, where my ESP is mounted.)

This seems to be something for touchpads, but I don't have a touchpad and won't get one. What can I do to disable this thing? Do I have to build a custom kernel?

Since linux-lts is also newer than 4.10, (4.14, currently), there doesn't seem to be an easy way to install an older kernel either, where blacklisting might presumably work.


Using nolapic as a kernel parameter solves the shutdown panic problem, but it causes the system to freeze a few minutes after boot, so I can't use it.

muru
  • 72,889

3 Answers3

14

After reading kernel sources, I found a function we need to blacklist!

Thanks to Stephen Kitt for the hint about initcall_blacklist.

Add initcall_blacklist=dw_i2c_init_driver to the kernel command line. This works for me on kernel 4.15.0.

For anyone else who'll find this answer. You can do it by editing /etc/default/grub:

  1. Run in the terminal: sudo -H gedit /etc/default/grub.
  2. Append blacklist string to the GRUB_CMDLINE_LINUX_DEFAULT: GRUB_CMDLINE_LINUX_DEFAULT="… initcall_blacklist=dw_i2c_init_driver".
  3. Save the file, close the editor.
  4. Run in the terminal: sudo update-grub.
  5. Reboot and test!
muru
  • 72,889
Yurij
  • 256
7

Adding initcall_blacklist=i2c_dw_init_master to the kernel command-line should stop the Designware driver from initialising during boot, and avoid the issue altogether.

See the kernel parameters for a very brief description of initcall_blacklist, and the thread around the patch for more useful background information.

Stephen Kitt
  • 434,908
  • No luck, I still get a kernel panic on i2c_dw_isr+0x3ef/0x6d0. Does that mean that function is being pulled by something else, or is the fault in another module? – muru Feb 13 '18 at 11:23
  • It probably means I picked the wrong function to blacklist ;-). Does blacklisting i2c_dw_probe work any better? Do you see the blacklist in effect? (It logs a message to the kernel logs saying it’s skipping a function.) – Stephen Kitt Feb 13 '18 at 11:27
  • No luck with initcall_blacklist=i2c_dw_init_master,i2c_dw_probe either. dmesg | grep i2c does show entries like [ 0.000000] blacklisting initcall i2c_dw_init_master. – muru Feb 13 '18 at 11:35
  • Do the logs ever mention anything like initcall i2c_dw_probe blacklisted? The blacklisting message indicates the boot parameter was used to populate the list, but the blacklisted message indicates the call was actually skipped. I could well be barking up the wrong tree here, sorry about that... – Stephen Kitt Feb 13 '18 at 11:42
  • no, only the "blacklisting" message. That is weird - yet another entry point for i2c? – muru Feb 13 '18 at 11:56
  • Presumably a chained entry point from something else where the “one call” init function lives (that’s what initcall_blacklist filters)... – Stephen Kitt Feb 13 '18 at 12:53
  • Sigh. In the meantime, I have discovered that booting with systemd.unit=poweroff.target shuts down fine, so I have added a UEFI boot entry for Linux with that parmeter, and a script that reboots to that boot entry. – muru Feb 13 '18 at 12:58
  • That sounds like a useful answer for other people faced with this issue... I’ll delete mine in a little while. – Stephen Kitt Feb 13 '18 at 13:01
  • 1
    Nah, I think keeping it around might be useful - the principle seems to be sound, all we're missing is the correct the init function. Hopefully someone may spot your answer and provide that. – muru Feb 13 '18 at 13:05
0

Experimenting with various ways of shutting down, it seems booting Linux to the poweroff target using systemd.unit=poweroff.target as a kernel parameter shuts down OK.

So, while I wait around for a better solution, I added a boot entry that simply shuts down. This is easy with GRUB (and presumably with other boot loaders), but I couldn't figure out a way to have UEFI itself simply shutdown. And it seems the Alienware's UEFI implementation does not support multiple entries for the same file, so I ended up copying vmlinuz-linux and adding an entry for the copy:

cp /boot/vmlinuz-linux /boot/vmlinuz-shutdown
cp /boot/initramfs-linux.img /boot/initramfs-shutdown.img
kernel_opts="root=UUID=e5018f7e-5838-4a47-b146-fc1614673356 ro initrd=/initramfs-shutdown.img systemd.unit=poweroff.target"
efibootmgr --disk /dev/nvme0n1 --part 1 --create --gpt --label "Shutdown" --loader /vmlinuz-shutdown --unicode "$kernel_opts"

Here the disk and partition options are specific to my system. The boot entry created here was numbered 0001, so an off script to give a clean shutdown:

#! /bin/sh
sudo efibootmgr -n 0001
reboot

There probably is a simpler way to have a UEFI shutdown target.

muru
  • 72,889