All of lore.kernel.org
 help / color / mirror / Atom feed
* RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
@ 2016-09-07  9:25 Yadi Hu
  2016-09-07  9:25 ` [PATCH] i2c-eg20t: " Yadi Hu
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Yadi Hu @ 2016-09-07  9:25 UTC (permalink / raw)
  To: yadi.hu, wsa, jdelvare; +Cc: linux-i2c


the eg20t driver call request_irq() function before the pch_base_address,
base address of i2c controller's register, isassigned an effective value.

it is one possible scenario that an interrupt which isn't inside eg20t
arrives immediately after request_irq() is executed when i2c controller
shares an interrupt number with others.  since the interrupt handler
pch_i2c_handler() has already active as shared action, it will be called
and read its own register to determine if this interrupt is from itself.

At that moment, since base address of i2c registers is not remapped
in kernel space yet,so the INT handler will access an illegal address
and then a error occurs.

Bad IO access at port 0x18 (return inl(port))
 Call Trace:
  [<c102c733>] warn_slowpath_common+0x73/0xa0
  [<c13109f5>] ? bad_io_access+0x45/0x50
  [<c13109f5>] ? bad_io_access+0x45/0x50
  [<c102c804>] warn_slowpath_fmt+0x34/0x40
  [<c13109f5>] bad_io_access+0x45/0x50
  [<c1310b62>] ioread32+0x22/0x40
  [<c14c60db>] pch_i2c_handler+0x3b/0x120
  [<c1092f34>] handle_irq_event_percpu+0x64/0x330
  [<c109323b>] handle_irq_event+0x3b/0x60
  [<c1095b50>] ? unmask_irq+0x30/0x30
  [<c1095ba0>] handle_fasteoi_irq+0x50/0xe0
  <IRQ>  [<c16e7e78>] ? do_IRQ+0x48/0xc0
  [<c16e7f6f>] ? smp_apic_timer_interrupt+0x7f/0x17a
  [<c16e7da9>] ? common_interrupt+0x29/0x30
  [<c1008ebb>] ? mwait_idle+0x8b/0x2c0
  [<c1009e8e>] ? cpu_idle+0x9e/0xc0
  [<c16be408>] ? rest_init+0x6c/0x74
  [<c19f770a>] ? start_kernel+0x311/0x318
  [<c19f7231>] ? repair_env_string+0x51/0x51
  [<c19f7078>] ? i386_start_kernel+0x78/0x7d
 ---[ end trace eb3a1028f468a140 ]---
 i2c_eg20t 0000:05:0c.2: pch_i2c_handler :I2C-3 mode(0) is not supported

after testing last patch, replacing request_irq() location is not a
good idea,it might produce a little time windows ,in which the interrupts
occurring inside  will be omitted.

the new patch adds a check point on interrupt handler in case field
'pch_base_address' has not been initialed.


Yadi Hu (1)
    i2c-eg20t: fix race between i2c init and interrupt enable

drivers/i2c/busses/i2c-eg20t.c |    5 +++++
 1 file changed, 5 insertions(+)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-07  9:25 RESEND:i2c-eg20t: fix race between i2c init and interrupt enable Yadi Hu
@ 2016-09-07  9:25 ` Yadi Hu
  2016-09-12  0:41 ` RESEND:i2c-eg20t: " Yadi
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Yadi Hu @ 2016-09-07  9:25 UTC (permalink / raw)
  To: yadi.hu, wsa, jdelvare; +Cc: linux-i2c

From: "Yadi.hu" <yadi.hu@windriver.com>

the eg20t driver call request_irq() function before the pch_base_address, 
base address of i2c controller's register, isassigned an effective value.

it is one possible scenario that an interrupt which isn't inside eg20t 
arrives immediately after request_irq() is executed when i2c controller 
shares an interrupt number with others.  since the interrupt handler 
pch_i2c_handler() has already active as shared action, it will be called 
and read its own register to determine if this interrupt is from itself.

At that moment, since base address of i2c registers is not remapped 
in kernel space yet,so the INT handler will access an illegal address
and then a error occurs.

the new patch adds a check point on interrupt handler in case field
'pch_base_address' has not been initialed.

Signed-off-by: Yadi.hu <yadi.hu@windriver.com>
---
 drivers/i2c/busses/i2c-eg20t.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
index 137125b..4ac8a49 100644
--- a/drivers/i2c/busses/i2c-eg20t.c
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -152,6 +152,7 @@ struct i2c_algo_pch_data {
 	int pch_buff_mode_en;
 	u32 pch_event_flag;
 	bool pch_i2c_xfer_in_progress;
+	bool initflag;
 };
 
 /**
@@ -635,6 +636,8 @@ static irqreturn_t pch_i2c_handler(int irq, void *pData)
 	u32 mode;
 
 	for (i = 0, flag = 0; i < adap_info->ch_num; i++) {
+		if (!adap_info->pch_data[i].initflag)
+			continue;
 		p = adap_info->pch_data[i].pch_base_address;
 		mode = ioread32(p + PCH_I2CMOD);
 		mode &= BUFFER_MODE | EEPROM_SR_MODE;
@@ -783,6 +786,7 @@ static int pch_i2c_probe(struct pci_dev *pdev,
 	for (i = 0; i < adap_info->ch_num; i++) {
 		pch_adap = &adap_info->pch_data[i].pch_adapter;
 		adap_info->pch_i2c_suspended = false;
+		adap_info->pch_data[i].initflag = false;
 
 		adap_info->pch_data[i].p_adapter_info = adap_info;
 
@@ -806,6 +810,7 @@ static int pch_i2c_probe(struct pci_dev *pdev,
 			pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i);
 			goto err_add_adapter;
 		}
+		adap_info->pch_data[i].initflag = true;
 	}
 
 	pci_set_drvdata(pdev, adap_info);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-07  9:25 RESEND:i2c-eg20t: fix race between i2c init and interrupt enable Yadi Hu
  2016-09-07  9:25 ` [PATCH] i2c-eg20t: " Yadi Hu
@ 2016-09-12  0:41 ` Yadi
  2016-09-14  6:39 ` Yadi
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Yadi @ 2016-09-12  0:41 UTC (permalink / raw)
  To: wsa, jdelvare; +Cc: linux-i2c

ping....  any objection?

Yadi


On 2016年09月07日 17:25, Yadi Hu wrote:
> the eg20t driver call request_irq() function before the pch_base_address,
> base address of i2c controller's register, isassigned an effective value.
>
> it is one possible scenario that an interrupt which isn't inside eg20t
> arrives immediately after request_irq() is executed when i2c controller
> shares an interrupt number with others.  since the interrupt handler
> pch_i2c_handler() has already active as shared action, it will be called
> and read its own register to determine if this interrupt is from itself.
>
> At that moment, since base address of i2c registers is not remapped
> in kernel space yet,so the INT handler will access an illegal address
> and then a error occurs.
>
> Bad IO access at port 0x18 (return inl(port))
>   Call Trace:
>    [<c102c733>] warn_slowpath_common+0x73/0xa0
>    [<c13109f5>] ? bad_io_access+0x45/0x50
>    [<c13109f5>] ? bad_io_access+0x45/0x50
>    [<c102c804>] warn_slowpath_fmt+0x34/0x40
>    [<c13109f5>] bad_io_access+0x45/0x50
>    [<c1310b62>] ioread32+0x22/0x40
>    [<c14c60db>] pch_i2c_handler+0x3b/0x120
>    [<c1092f34>] handle_irq_event_percpu+0x64/0x330
>    [<c109323b>] handle_irq_event+0x3b/0x60
>    [<c1095b50>] ? unmask_irq+0x30/0x30
>    [<c1095ba0>] handle_fasteoi_irq+0x50/0xe0
>    <IRQ>  [<c16e7e78>] ? do_IRQ+0x48/0xc0
>    [<c16e7f6f>] ? smp_apic_timer_interrupt+0x7f/0x17a
>    [<c16e7da9>] ? common_interrupt+0x29/0x30
>    [<c1008ebb>] ? mwait_idle+0x8b/0x2c0
>    [<c1009e8e>] ? cpu_idle+0x9e/0xc0
>    [<c16be408>] ? rest_init+0x6c/0x74
>    [<c19f770a>] ? start_kernel+0x311/0x318
>    [<c19f7231>] ? repair_env_string+0x51/0x51
>    [<c19f7078>] ? i386_start_kernel+0x78/0x7d
>   ---[ end trace eb3a1028f468a140 ]---
>   i2c_eg20t 0000:05:0c.2: pch_i2c_handler :I2C-3 mode(0) is not supported
>
> after testing last patch, replacing request_irq() location is not a
> good idea,it might produce a little time windows ,in which the interrupts
> occurring inside  will be omitted.
>
> the new patch adds a check point on interrupt handler in case field
> 'pch_base_address' has not been initialed.
>
>
> Yadi Hu (1)
>      i2c-eg20t: fix race between i2c init and interrupt enable
>
> drivers/i2c/busses/i2c-eg20t.c |    5 +++++
>   1 file changed, 5 insertions(+)
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-07  9:25 RESEND:i2c-eg20t: fix race between i2c init and interrupt enable Yadi Hu
  2016-09-07  9:25 ` [PATCH] i2c-eg20t: " Yadi Hu
  2016-09-12  0:41 ` RESEND:i2c-eg20t: " Yadi
@ 2016-09-14  6:39 ` Yadi
  2016-09-14  7:28 ` Wolfram Sang
  2016-09-16 20:04 ` Wolfram Sang
  4 siblings, 0 replies; 10+ messages in thread
From: Yadi @ 2016-09-14  6:39 UTC (permalink / raw)
  To: wsa, jdelvare; +Cc: linux-i2c

ping once again, any objection?

Yadi

On 2016年09月07日 17:25, Yadi Hu wrote:
> the eg20t driver call request_irq() function before the pch_base_address,
> base address of i2c controller's register, isassigned an effective value.
>
> it is one possible scenario that an interrupt which isn't inside eg20t
> arrives immediately after request_irq() is executed when i2c controller
> shares an interrupt number with others.  since the interrupt handler
> pch_i2c_handler() has already active as shared action, it will be called
> and read its own register to determine if this interrupt is from itself.
>
> At that moment, since base address of i2c registers is not remapped
> in kernel space yet,so the INT handler will access an illegal address
> and then a error occurs.
>
> Bad IO access at port 0x18 (return inl(port))
>   Call Trace:
>    [<c102c733>] warn_slowpath_common+0x73/0xa0
>    [<c13109f5>] ? bad_io_access+0x45/0x50
>    [<c13109f5>] ? bad_io_access+0x45/0x50
>    [<c102c804>] warn_slowpath_fmt+0x34/0x40
>    [<c13109f5>] bad_io_access+0x45/0x50
>    [<c1310b62>] ioread32+0x22/0x40
>    [<c14c60db>] pch_i2c_handler+0x3b/0x120
>    [<c1092f34>] handle_irq_event_percpu+0x64/0x330
>    [<c109323b>] handle_irq_event+0x3b/0x60
>    [<c1095b50>] ? unmask_irq+0x30/0x30
>    [<c1095ba0>] handle_fasteoi_irq+0x50/0xe0
>    <IRQ>  [<c16e7e78>] ? do_IRQ+0x48/0xc0
>    [<c16e7f6f>] ? smp_apic_timer_interrupt+0x7f/0x17a
>    [<c16e7da9>] ? common_interrupt+0x29/0x30
>    [<c1008ebb>] ? mwait_idle+0x8b/0x2c0
>    [<c1009e8e>] ? cpu_idle+0x9e/0xc0
>    [<c16be408>] ? rest_init+0x6c/0x74
>    [<c19f770a>] ? start_kernel+0x311/0x318
>    [<c19f7231>] ? repair_env_string+0x51/0x51
>    [<c19f7078>] ? i386_start_kernel+0x78/0x7d
>   ---[ end trace eb3a1028f468a140 ]---
>   i2c_eg20t 0000:05:0c.2: pch_i2c_handler :I2C-3 mode(0) is not supported
>
> after testing last patch, replacing request_irq() location is not a
> good idea,it might produce a little time windows ,in which the interrupts
> occurring inside  will be omitted.
>
> the new patch adds a check point on interrupt handler in case field
> 'pch_base_address' has not been initialed.
>
>
> Yadi Hu (1)
>      i2c-eg20t: fix race between i2c init and interrupt enable
>
> drivers/i2c/busses/i2c-eg20t.c |    5 +++++
>   1 file changed, 5 insertions(+)
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-07  9:25 RESEND:i2c-eg20t: fix race between i2c init and interrupt enable Yadi Hu
                   ` (2 preceding siblings ...)
  2016-09-14  6:39 ` Yadi
@ 2016-09-14  7:28 ` Wolfram Sang
  2016-09-14  7:49   ` Yadi
  2016-09-16 20:04 ` Wolfram Sang
  4 siblings, 1 reply; 10+ messages in thread
From: Wolfram Sang @ 2016-09-14  7:28 UTC (permalink / raw)
  To: Yadi Hu; +Cc: jdelvare, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 321 bytes --]


> after testing last patch, replacing request_irq() location is not a
> good idea,it might produce a little time windows ,in which the interrupts
> occurring inside  will be omitted.

To give you a little feedback: I think I liked the previous patch
better, but need the weekend to think about it.

Thanks,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-14  7:28 ` Wolfram Sang
@ 2016-09-14  7:49   ` Yadi
  0 siblings, 0 replies; 10+ messages in thread
From: Yadi @ 2016-09-14  7:49 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: jdelvare, linux-i2c

On 2016年09月14日 15:28, Wolfram Sang wrote:
>> after testing last patch, replacing request_irq() location is not a
>> good idea,it might produce a little time windows ,in which the interrupts
>> occurring inside  will be omitted.
> To give you a little feedback: I think I liked the previous patch
> better, but need the weekend to think about it.
>
> Thanks,
>
>     Wolfram
>
thanks your feedback.


Yadi

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-07  9:25 RESEND:i2c-eg20t: fix race between i2c init and interrupt enable Yadi Hu
                   ` (3 preceding siblings ...)
  2016-09-14  7:28 ` Wolfram Sang
@ 2016-09-16 20:04 ` Wolfram Sang
  2016-09-18  2:55   ` Yadi
  4 siblings, 1 reply; 10+ messages in thread
From: Wolfram Sang @ 2016-09-16 20:04 UTC (permalink / raw)
  To: Yadi Hu; +Cc: jdelvare, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 545 bytes --]


> after testing last patch, replacing request_irq() location is not a
> good idea,it might produce a little time windows ,in which the interrupts
> occurring inside  will be omitted.
> 
> the new patch adds a check point on interrupt handler in case field
> 'pch_base_address' has not been initialed.

What about using two for-loops in probe like this pseudo code?

for (all_channels)
	do_initialization

request_irq()

for (all_channels)
	register_adapter


This seems to me the correct order and most readable solution.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-16 20:04 ` Wolfram Sang
@ 2016-09-18  2:55   ` Yadi
  2016-09-18  7:53     ` Wolfram Sang
  0 siblings, 1 reply; 10+ messages in thread
From: Yadi @ 2016-09-18  2:55 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: jdelvare, linux-i2c



在 2016/9/17 4:04, Wolfram Sang 写道:
>> after testing last patch, replacing request_irq() location is not a
>> good idea,it might produce a little time windows ,in which the interrupts
>> occurring inside  will be omitted.
>>
>> the new patch adds a check point on interrupt handler in case field
>> 'pch_base_address' has not been initialed.
> What about using two for-loops in probe like this pseudo code?
>
> for (all_channels)
> 	do_initialization
>
> request_irq()
>
> for (all_channels)
> 	register_adapter
>
>
> This seems to me the correct order and most readable solution.
if we use two for-loops, we would have to put  pch_i2c_init on the 
second loop in order to avoid littel interval, in which the interrupts 
occuring inside will be omitted.
it seems to me so uncomfortable. how do you like it?

for (all_channels)
	do_initialization

request_irq()

for (all_channels) {
	 pch_i2c_init  /* Enable interrupts at end of function*/
	 register_adapter
}

Yadi

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-18  2:55   ` Yadi
@ 2016-09-18  7:53     ` Wolfram Sang
  2016-09-18  8:51       ` Yadi
  0 siblings, 1 reply; 10+ messages in thread
From: Wolfram Sang @ 2016-09-18  7:53 UTC (permalink / raw)
  To: Yadi; +Cc: jdelvare, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 318 bytes --]


> it seems to me so uncomfortable. how do you like it?
> 
> for (all_channels)
> 	do_initialization
> 
> request_irq()
> 
> for (all_channels) {
> 	 pch_i2c_init  /* Enable interrupts at end of function*/
> 	 register_adapter
> }

Thanks for the correction. This would be still my preferred solution.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: RESEND:i2c-eg20t: fix race between i2c init and interrupt enable
  2016-09-18  7:53     ` Wolfram Sang
@ 2016-09-18  8:51       ` Yadi
  0 siblings, 0 replies; 10+ messages in thread
From: Yadi @ 2016-09-18  8:51 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: jdelvare, linux-i2c

On 2016年09月18日 15:53, Wolfram Sang wrote:
>> it seems to me so uncomfortable. how do you like it?
>>
>> for (all_channels)
>> 	do_initialization
>>
>> request_irq()
>>
>> for (all_channels) {
>> 	 pch_i2c_init  /* Enable interrupts at end of function*/
>> 	 register_adapter
>> }
> Thanks for the correction. This would be still my preferred solution.
>
ok, I have no objection and will resend patch V3 per your solution.

Yadi

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-09-18  8:51 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-07  9:25 RESEND:i2c-eg20t: fix race between i2c init and interrupt enable Yadi Hu
2016-09-07  9:25 ` [PATCH] i2c-eg20t: " Yadi Hu
2016-09-12  0:41 ` RESEND:i2c-eg20t: " Yadi
2016-09-14  6:39 ` Yadi
2016-09-14  7:28 ` Wolfram Sang
2016-09-14  7:49   ` Yadi
2016-09-16 20:04 ` Wolfram Sang
2016-09-18  2:55   ` Yadi
2016-09-18  7:53     ` Wolfram Sang
2016-09-18  8:51       ` Yadi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.