6

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.

7

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!
  • Yep, blacklisting that worked! – muru May 30 '18 at 13:33
6

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.

  • 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
  • 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.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.