Skip to content

serial: 8250: Toggle IER bits on only after irq has been set up

Prarit Bhargava requested to merge prarit/centos-stream-9:RHEL-30355 into main

JIRA: https://issues.redhat.com/browse/RHEL-30355

commit 039d4926379b1d1c17b51cf21c500a5eed86899e
Author: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
Date: Thu Sep 22 10:00:05 2022 +0300

serial: 8250: Toggle IER bits on only after irq has been set up  

Invoking TIOCVHANGUP on 8250_mid port on Ice Lake-D and then reopening  
the port triggers these faults during serial8250_do_startup():  

  DMAR: DRHD: handling fault status reg 3  
  DMAR: [DMA Write NO_PASID] Request device [00:1a.0] fault addr 0x0 [fault reason 0x05] PTE Write access is not set  

If the IRQ hasn't been set up yet, the UART will have zeroes in its MSI  
address/data registers. Disabling the IRQ at the interrupt controller  
won't stop the UART from performing a DMA write to the address programmed  
in its MSI address register (zero) when it wants to signal an interrupt.  

The UARTs (in Ice Lake-D) implement PCI 2.1 style MSI without masking  
capability, so there is no way to mask the interrupt at the source PCI  
function level, except disabling the MSI capability entirely, but that  
would cause it to fall back to INTx# assertion, and the PCI specification  
prohibits disabling the MSI capability as a way to mask a function's  
interrupt service request.  

The MSI address register is zeroed by the hangup as the irq is freed.  
The interrupt is signalled during serial8250_do_startup() performing a  
THRE test that temporarily toggles THRI in IER. The THRE test currently  
occurs before UART's irq (and MSI address) is properly set up.  

Refactor serial8250_do_startup() such that irq is set up before the  
THRE test. The current irq setup code is intermixed with the timer  
setup code. As THRE test must be performed prior to the timer setup,  
extract it into own function and call it only after the THRE test.  

The ->setup_timer() needs to be part of the struct uart_8250_ops in  
order to not create circular dependency between 8250 and 8250_base  
modules.  

Fixes: 40b36daad0ac ("[PATCH] 8250 UART backup timer")  
Reported-by: Lennert Buytenhek <buytenh@arista.com>  
Tested-by: Lennert Buytenhek <buytenh@arista.com>  
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>  
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>  
Link: https://lore.kernel.org/r/20220922070005.2965-1-ilpo.jarvinen@linux.intel.com  
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>  

Signed-off-by: Prarit Bhargava prarit@redhat.com

Merge request reports