[i2c] 2.6.19-rc3 Segmentation fault on i2c_register_driver.

Tom Rathbone tom.rathbone at gmail.com
Fri Oct 27 11:20:08 CEST 2006


Hi All,

Recently upgraded from 2.6.17-rc4 to 2.6.19-rc2 and found an audio
driver we are developing was causing segfaults whenever it was
inserted, previously it worked just fine.

Quickly traced the problem to i2c_register_driver and created a
minimal test case (listed below).  The crash is strange as the trace
varies with each crash but always relates to device registration or
kobject code called from beneath i2c_register_driver or
i2c_detach_client.

I'm using Andrew Victor's AT91 bus driver
(http://lists.lm-sensors.org/pipermail/i2c/2006-October/000396.html)
on Linus' git head with only minor modifications to support my board.
I can't see a direct connection between this driver and the crash.

Has anyone seen anything similar?  Is the test case just doing
something wrong?  Any ideas at all would be greatly appreciated.

Thanks,

Tom.

~ # insmod mintest.ko
mintest: module license 'unspecified' taintskernel.
Unable to handle kernel paging request at virtual address 00100100
pgd = c0cdc000
[00100100] *pgd=20cf6031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
Modules linked in: mintest(P) g_ether
CPU: 0
PC is at device_add+0x280/0x45c
LR is at kobject_put+0x20/0x28
pc : [<c0101d2c>]    lr : [<c00de7b0>]    Tainted: P
sp : c02d1e04  ip : c0061ab4  fp : c02d1e34
r10: 00000000  r9 : c0418c04  r8 : 00000000
r7 : 00000000  r6 : c0c52754  r5 : c0c526ec  r4 : c0c526ec
r3 : 00100100  r2 : 20000013  r1 : 00000000  r0 : 00000000
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  Segment user
Control: C000717F
Table: 20CDC000  DAC: 00000015
Process insmod (pid: 37, stack limit = 0xc02d0250)
Stack: (0xc02d1e04 to 0xc02d2000)
1e00:          c0c527a8 00000000 c0c526ec c0c526d8 c0c526ec c0418bc8 c0c5281c
1e20: c0418ca8 c0418c04 c02d1e48 c02d1e38 c0101f24 c0101abc c0c52790 c02d1e8c
1e40: c02d1e4c c0123890 c0101f18 c0c52790 000000d0 c0c52824 00000000 c0418bf0
1e60: 00000000 c0c526d8 00000000 c0418bc8 0000000e c1855498 c1855000 c02b2330
1e80: c02d1ea8 c02d1e90 bf007058 c01237ac c0418dd0 bf0074fc c01f0bf4 c02d1ec4
1ea0: c02d1eac c0123560 bf007010 c02b2314 bf0075c0 00000000 c02d1ed4 c02d1ec8
1ec0: bf0070dc c01234ec c02d1fa4 c02d1ed8 c0049efc bf0070d4 00000000 00000208
1ee0: c01ab6bc c01ab6bc 00000124 00000020 0000000e 00000000 00000000 c012379c
1f00: bf0073c0 00000000 0000002a 00000034 00000030 0000001c c02d0000 00000000
1f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1f40: 00000004 00000000 00000007 00000000 00000000 00000000 0000000d 0000000c
1f60: c1855a10 c029c980 c1855424 c001fdf0 c0064e70 00000000 00000000 00000003
1f80: 00000000 00000100 00000080 c001cd44 c02d0000 00000002 00000000 c02d1fa8
1fa0: c001cba0 c0048a2c 00000000 00000100 00900080 40017000 00000b40 00067050
1fc0: 00000003 00000000 00000100 bec1fe94 bec1ff5c 00000000 00000002 00000000
1fe0: bec1fdd4 bec1fdc8 0001e578 401261c0 60000010 00900080 40181250 40181258
Backtrace:
[<c0101aac>] (device_add+0x0/0x45c) from [<c0101f24>]
(device_register+0x1c/0x20)
[<c0101f08>] (device_register+0x0/0x20) from [<c0123890>]
(i2c_attach_client+0xf4/0x214)
 r4 = C0C52790
[<c012379c>] (i2c_attach_client+0x0/0x214) from [<bf007058>]
(mintest_attach_client+0x58/0x80 [mintest])
[<bf007000>] (mintest_attach_client+0x0/0x80 [mintest]) from
[<c0123560>] (i2c_register_driver+0x84/0xb0)
 r6 = C01F0BF4  r5 = BF0074FC  r4 = C0418DD0
[<c01234dc>] (i2c_register_driver+0x0/0xb0) from [<bf0070dc>]
(mintest_i2c_init+0x18/0x44 [mintest])
 r6 = 00000000  r5 = BF0075C0  r4 = C02B2314
[<bf0070c4>] (mintest_i2c_init+0x0/0x44 [mintest]) from [<c0049efc>]
(sys_init_module+0x14e0/0x15b8)
[<c0048a1c>] (sys_init_module+0x0/0x15b8) from [<c001cba0>]
(ret_fast_syscall+0x0/0x2c)
Code: e5953128 e1a08007 e3530000 0a000015 (e5933000)
 Segmentation fault
~ #

mintest.c
------------
/* GPL */
#include <linux/init.h>
#include <linux/i2c.h>

#define I2C_CLIENT_ADDR		0x4d
#define MAX_REGISTER 	0xa

static int registered = 0;
static struct	i2c_driver mintest_driver;

static int mintest_attach_client(struct i2c_adapter *adapter)
{
	int rc = 0;
	struct i2c_client *new_client;
	const char *client_name = "Mintest Client";

	new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);

	if (!new_client) {
		rc = -ENOMEM;
		goto bail;
	}
	
	new_client->addr = I2C_CLIENT_ADDR;
	new_client->adapter = adapter;
	new_client->driver = &mintest_driver;
	new_client->flags = 0;
	strcpy(new_client->name, client_name);
	
/* crash here */
	if (i2c_attach_client(new_client)) {
		rc = -ENODEV;
		goto bail;
	}

	return 0;	
bail:
	kfree(new_client);
	return rc;
}

static int mintest_detach_client(struct i2c_client *client)
{
/* or crash here */
	return i2c_detach_client(client);
}

static struct i2c_driver mintest_driver = {
	.driver= {
		.name =	"Minimal I2C Test",
	},
	.attach_adapter = &mintest_attach_client,
	.detach_client	= &mintest_detach_client,
};


static void mintest_i2c_cleanup(void)
{
	if(registered)
		i2c_del_driver(&mintest_driver);
}

static int mintest_i2c_init(void)
{
	if (i2c_add_driver(&mintest_driver)) {
		mintest_i2c_cleanup();
		return -ENODEV;
	}
	registered = 1;
	
	return 0;
}

module_init(mintest_i2c_init)
module_exit(mintest_i2c_cleanup)



More information about the i2c mailing list