Re: [PATCH v2 5/5] tty/serial/8250: use mctrl_gpio helpers

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

 



Hello,

On 04/06/2016 12:38 PM, Uwe Kleine-König wrote: 
> On Wed, Apr 06, 2016 at 12:27:29PM -0700, Peter Hurley wrote:
>> On 04/06/2016 12:14 PM, Uwe Kleine-König wrote:
>>> On Wed, Apr 06, 2016 at 11:35:23AM -0700, Peter Hurley wrote:
>>>> On 04/06/2016 10:48 AM, Uwe Kleine-König wrote:
>>>>> On Wed, Apr 06, 2016 at 08:23:02AM -0700, Peter Hurley wrote:
>>>>>> On 04/05/2016 11:20 PM, Uwe Kleine-König wrote:
>>>>>>> On Tue, Apr 05, 2016 at 09:58:09AM -0700, Peter Hurley wrote:
>>>>>>>> On 04/05/2016 06:25 AM, Yegor Yefremov wrote:
>>>>>>>>> On Tue, Apr 5, 2016 at 2:21 PM, Uwe Kleine-König
>>>>>>>>> <u.kleine-koenig@xxxxxxxxxxxxxx> wrote:
>>>>>>>>>> On Tue, Apr 05, 2016 at 12:32:53PM +0200, Yegor Yefremov wrote:
>>>>>>>>>>> I've got a kernel crash from kernel robot. If we use UART before
>>>>>>>>>>> general initialization (earlyprintk), then any call to mctrl API would
>>>>>>>>>>> result in NULL pointer dereference. One solution would be to check, if
>>>>>>>>>>> gpios IS_ERR_OR_NULL(). See below:
>>>>>>>>>>>
>>>>>>>>>>> --- a/drivers/tty/serial/serial_mctrl_gpio.c
>>>>>>>>>>> +++ b/drivers/tty/serial/serial_mctrl_gpio.c
>>>>>>>>>>> @@ -54,6 +54,9 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios,
>>>>>>>>>>> unsigned int mctrl)
>>>>>>>>>>>         int value_array[UART_GPIO_MAX];
>>>>>>>>>>>         unsigned int count = 0;
>>>>>>>>>>>
>>>>>>>>>>> +       if (IS_ERR_OR_NULL(gpios))
>>>>>>>>>>> +               return;
>>>>>>>>>>> +
>>>>>>>>>>>         for (i = 0; i < UART_GPIO_MAX; i++)
>>>>>>>>>>>                 if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) {
>>>>>>>>>>>                         desc_array[count] = gpios->gpio[i];
>>>>>>>>>>
>>>>>>>>>> IS_ERR_OR_NULL(gpios) should never be true. gpios should be the value
>>>>>>>>>> that was returned by mctrl_gpio_init, this never returns NULL and if it
>>>>>>>>>> returns an error you're supposed to not register the port. And for early
>>>>>>>>>> printk there is AFAIK no mctrl involved.
>>>>>>>>>
>>>>>>>>> You're right. it was console_init stuff. It happens before
>>>>>>>>> serial8250_register_8250_port().  Perhaps I should introduce one more
>>>>>>>>> gpio_init invocation in univ8250_console_setup().
>>>>>>>
>>>>>>> If the port isn't registered yet, nobody should call the port's
>>>>>>> .set_mctrl. So your plan sounds wrong for this reason, too.
>>>>>>
>>>>>> The 8250 driver initializes MCR from mctrl in its set_termios method:
>>>>>>   uart_set_options
>>>>>>     mctrl |= TIOCM_DTR
>>>>>>     ->set_termios  =>  serial8250_set_termios
>>>>>>       serial8250_set_mctrl
>>>>>
>>>>> Then maybe the bug is that uart_set_options calls serial8250_set_mctrl
>>>>> which is supposed to be only called after the device is probed?
>>>>
>>>> Nope; DTR should be asserted when the console is initialized.
>>>
>>> Oh, that's news to me. I thought console communication is supposed to
>>> never use handshaking. Who can give an authorative answer here? Greg?
>>> Russell?
>>
>> Since v2.6.23:
>>
>> commit 79492689e40d4f4d3d8a7262781d56fb295b4b86
>> Author: Yinghai Lu <Yinghai.Lu@xxxxxxx>
>> Date:   Sun Jul 15 23:37:25 2007 -0700
>>
>>     serial: assert DTR for serial console devices
>>     
>>     Some RS-232 devices require DTR to be asserted before they can be used.  DTR
>>     is normally asserted in uart_startup() when the port is opened.  But we don't
>>     actually open serial console ports, so assert DTR when the port is added.
>>     
>>     BTW:
>>     earlyprintk and early_uart are hard coded to set DTR/RTS.
>>     
>>     rmk says
>>     
>>       The only issue I can think of is the possibility for an attached modem to
>>       auto-answer or maybe even auto-dial before the system is ready for it to do
>>       so.  Might have an undesirable cost implication for some running with such a
>>       setup.
>>     
>>       Apart from that, I can't think of any other side effect of this specific
>>       patch.
>>     
>>     Signed-off-by: Yinghai Lu <yinghai.lu@xxxxxxx>
>>     Acked-by: Russell King <rmk@xxxxxxxxxxxxxxxx>
>>
>>
>>>> I understand that is not possible with the mctrl helpers right now,
>>>> but that's no reason to break other setups that do the right thing.
>>>>
>>>>>>>> Just skip mctrl_gpio_set() and mctrl_gpio_get*() if !up->gpios
>>>>>>>
>>>>>>> This would work, but sounds wrong for the above reason, too. I'd like to
>>>>>>> reserve gpios=NULL for the case where no gpio has to be controlled, so
>>>>>>> please don't use it as indication if mctrl_gpio_init was called.
>>>>>>
>>>>>> I'm confused; what operations will be different if gpios==NULL?
>>>>>> And wouldn't that argue for checking gpios==NULL in mctrl_gpio_set(),
>>>>>> performing no action in that case?
>>>>>
>>>>> OK, the right thing would happen. Still I'd prefer if a serial driver
>>>>> did not try to interpret what a certain value means or not. I'd say the
>>>>> only allowed operations on a gpios value are calling mctrl_gpio
>>>>> functions and use IS_ERR and PTR_ERR during probe.
>>>>
>>>> Ok, so then we're back to checking gpios == NULL in mctrl_gpio_set()
>>>> instead, right?
>>>>
>>>> Because that's "the case where no gpio has to be controlled" because
>>>> there is no gpio yet.
>>>
>>> I don't agree. It's a layer violation if you pass a "self made" value
>>> (in this case NULL) to an mctrl_gpio function. Currently mctrl_gpio_init
>>> cannot return NULL, so it's a bug to call mctrl_gpio_set with NULL.
>>
>> Which is exactly the opposite argument you just waged 2 emails before.
>>
>> Ok, so if "mctrl_gpio_init() cannot return NULL", and gpios is a
>> self-made value, then I see no problem simply not calling
>> mctrl_gpio_set() if up->gpios is NULL.
> 
> No, the rule is: Only call mctrl_gpio_* with a value returned by
> mctrl_gpio_init. Currently this implies you're doing something wrong
> when you pass NULL. When one day NULL might be returned by
> mctrl_gpio_init (likely meaning "there are no gpios to be controlled")
> you can of course pass NULL. But only if you called mctrl_gpio_init
> before and it gave you NULL. But this is all internal knowledge that
> shouldn't be used in a serial driver. And you shouldn't make it possible
> to let mctrl_gpio_init return NULL just to bless your current usage. The
> hard rule is: Only call mctrl_gpio_* after mctrl_gpio_init and pass the
> value returned by it.

I'm not adding a bunch of driver state for an inadequately designed
interface, sorry.

The initial state before mctrl_gpio_init() is ever called is already NULL,
so there will be no way to distinguish between whether mctrl_gpio_init()
has ever been called or not.

The mctrl helpers will not be able to assert their own invariances, which
imho, is broken.

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