Re: Misc questions about 8250_core.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 03/06/2015 03:04 PM, Mason wrote:
> Peter Hurley wrote:
> 
>> Mason wrote:
>>
>>> Is the UART_CONFIG_TYPE flag set for an UPIO_AU iotype?
>>>
>>> The only place that sets UART_CONFIG_TYPE is
>>> drivers/tty/serial/serial_core.c:2177
>>>
>>>     if (port->flags & UPF_BOOT_AUTOCONF) {
>>>         if (!(port->flags & UPF_FIXED_TYPE)) {
>>>             port->type = PORT_UNKNOWN;
>>>             flags |= UART_CONFIG_TYPE;
>>>         }
>>>         port->ops->config_port(port, flags);
>>>     }
>>>
>>> Don't know where to look at that point.
>>
>> For exactly this scenario, the 8250 core rechecks the fields
>> derived from port->type (fifosize, capabilites, etc) when the port
>> is first opened in serial8250_do_startup().
> 
> Thanks, I will take a closer look.

These fields need to be defined by an entry for PORT_RT2880 in
the uart_config[] table.

>>> Whatever it is used for, here's the problem:
>>>
>>>   serial_port_in(port, UART_SCR); calls au_serial_in(port, UART_SCR);
>>>
>>> Out-of-bound access.
>>
>> That's my breakage.
> 
> Oh! I wasn't aware that the code was recent. I just grabbed the
> 4.0-rc2 tarball, and started reading the code.
> 
>>> serial_out(up, UART_SCR, canary); is even worse, as it will scribble
>>> over some innocent bystander.
>>
>> It won't be a different device because the mmio resource request is
>> for base + 8 registers.
> 
> Do you mean that some kind of IOMMU would prevent the "misaddressed"
> write? I don't think there is any protection on Tango4.

I didn't realize the AU register lookup was 'sparse'. That doesn't
seem like a good idea. It should at least be defined for the standard
register region.

>>> So an appropriate fix might be:
>>>
>>> --- 8250_core.c    2015-03-03 18:04:59.000000000 +0100
>>> +++ 8250_core.fix.c    2015-03-06 18:23:27.374740156 +0100
>>> @@ -378,12 +378,14 @@
>>>  
>>>  static unsigned int au_serial_in(struct uart_port *p, int offset)
>>>  {
>>> +    if (offset > UART_MSR) return 0;
>>>      offset = au_io_in_map[offset] << p->regshift;
>>>      return __raw_readl(p->membase + offset);
>>>  }
>>>  
>>>  static void au_serial_out(struct uart_port *p, int offset, int value)
>>>  {
>>> +    if (offset > UART_MCR) return;
>>>      offset = au_io_out_map[offset] << p->regshift;
>>>      __raw_writel(value, p->membase + offset);
>>>  }
>>
>> If that fixes my breakage, then ok. I could also skip this UPIO_* type
>> for the canary/console restore problem.
>>
>> Will you submit that as a patch or would you like me to?
> 
> My patch is not even compile-tested ;-)
> It was only intended to kick-start the discussion.

Ok, I'll come up with something. Will you be able to test a patch?

Also, looking at the RT3050 datasheet shows it has has a scratch
register; I'll see if I can dig up some info on the RT2880/Au1xxx.

> I was also trying to verify that serial_in/out is never called
> with UART_EFR when UART_CAP_EFR is not set. Do you know?

UART_EFR == 2 == UART_FCR, so yes.
But not while in CONF_MODE_B, which I think is what you were asking.

Regards,
Peter Hurley
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux