insmod在submit_bio()调用中以“Killed”结束

时间:2018-01-15 14:23:40

标签: linux-device-driver

要了解如何从内核模块在块设备上执行I / O,我使用了/drivers/block/floppy.c中的一段代码:

struct rb0_cbdata {
    int drive;
    struct completion complete;
};

static void floppy_rb0_cb(struct bio *bio)
{
    struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private;

    complete(&cbdata->complete);
}

static int __floppy_read_block_0(struct block_device *bdev)
{
struct bio bio;
struct bio_vec bio_vec;
struct page *page;
struct rb0_cbdata cbdata;
size_t size;

    page = alloc_page(GFP_NOIO);
    if (!page) {

        return -ENOMEM;
    }

    size = bdev->bd_block_size;
    if (!size)
        size = 1024;

    bio_init(&bio, &bio_vec, 1);
    bio.bi_bdev = bdev;
    bio_add_page(&bio, page, size, 0);

    bio.bi_iter.bi_sector = 0;
    bio.bi_flags |= (1 << BIO_QUIET);
    bio.bi_private = &cbdata;
    bio.bi_end_io = floppy_rb0_cb;
    bio_set_op_attrs(&bio, REQ_OP_READ, 0);

    submit_bio(&bio);


    init_completion(&cbdata.complete);
    wait_for_completion(&cbdata.complete);

    __free_page(page);

    return 0;
}

...

static int __init dua_init(void)
{

    /*
     */
    if ( IS_ERR(backend_bdev = lookup_bdev(dudrv_bckends, FMODE_READ | FMODE_WRITE)) )
        {
        status = PTR_ERR(backend_bdev);
        printk(KERN_ERR __MODULE__ ": lookup_bdev(%s) -> %d\n", dudrv_bckends, status);
        return  status;
        }

     __floppy_read_block_0(backend_bdev);

... }

dmesg的一段输出如下:

[ 1945.885812] BUG: unable to handle kernel NULL pointer dereference at 00000000000003d0
[ 1945.885838] IP: generic_make_request_checks+0x49/0x5b0
[ 1945.885850] PGD 0 
[ 1945.885851] P4D 0 

[ 1945.885866] Oops: 0000 [#1] SMP PTI
[ 1945.885875] Modules linked in: dudriver(OE+) vboxsf(OE) joydev input_leds vboxvideo(OE) ttm drm_kms_helper drm fb_sys_fops syscopyarea crct10dif_pclmul sysfillrect mac_hid sysimgblt crc32_pclmul ghash_clmulni_intel serio_raw pcbc vboxguest(OE) aesni_intel aes_x86_64 crypto_simd glue_helper i2c_piix4 cryptd intel_rapl_perf parport_pc ppdev lp parport autofs4 hid_generic usbhid hid psmouse ahci libahci e1000 video
[ 1945.885966] CPU: 2 PID: 6567 Comm: insmod Tainted: G           OE   4.13.0-26-generic #29~16.04.2-Ubuntu
[ 1945.885987] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 1945.886005] task: ffff99add4ee5d00 task.stack: ffffbe04c4b00000
[ 1945.886019] RIP: 0010:generic_make_request_checks+0x49/0x5b0
[ 1945.886032] RSP: 0018:ffffbe04c4b03a60 EFLAGS: 00010293
[ 1945.886044] RAX: 0000000000000000 RBX: ffffbe04c4b03bb8 RCX: 0000000000000000
[ 1945.886070] RDX: 0000000000000008 RSI: 00000000fffffffd RDI: ffff99ae0e8dd6c0
[ 1945.886086] RBP: ffffbe04c4b03ac0 R08: ffffbe04c4b03b80 R09: 0000000000000010
[ 1945.886101] R10: ffffbe04c4b03b38 R11: 0000000000000002 R12: 0000000000000008
[ 1945.886117] R13: 00000000ffffffff R14: ffff99addb486de0 R15: 0000000000000001
[ 1945.886133] FS:  00007f2e3f7a7700(0000) GS:ffff99ae1fd00000(0000) knlGS:0000000000000000
[ 1945.886151] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1945.886164] CR2: 00000000000003d0 CR3: 00000000b4a8a000 CR4: 00000000000406e0
[ 1945.886181] Call Trace:
[ 1945.886191]  generic_make_request+0x3e/0x300
[ 1945.886204]  ? __alloc_pages_nodemask+0xfb/0x280
[ 1945.886215]  submit_bio+0x73/0x150
[ 1945.886224]  ? submit_bio+0x73/0x150
[ 1945.886234]  ? alloc_pages_current+0x6a/0xe0
[ 1945.886246]  __floppy_read_block_0+0xc8/0x126 [dudriver]
[ 1945.886259]  ? kmem_cache_alloc+0x15a/0x1b0
[ 1945.886269]  ? 0xffffffffc04c2000
[ 1945.886279]  dua_init+0x2bb/0x1000 [dudriver]
[ 1945.886289]  ? 0xffffffffc0265000
[ 1945.886298]  do_one_initcall+0x53/0x1b0
[ 1945.886685]  ? kmem_cache_alloc_trace+0x152/0x1b0
[ 1945.887081]  do_init_module+0x5f/0x209
[ 1945.887451]  load_module+0x1961/0x1d60
[ 1945.887834]  ? ima_post_read_file+0x7d/0xa0
[ 1945.888228]  SYSC_finit_module+0xe5/0x120
[ 1945.888609]  ? SYSC_finit_module+0xe5/0x120
[ 1945.888974]  SyS_finit_module+0xe/0x10
[ 1945.889345]  entry_SYSCALL_64_fastpath+0x1e/0x81
[ 1945.889696] RIP: 0033:0x7f2e3f2d6499
[ 1945.890021] RSP: 002b:00007fffdd293cb8 EFLAGS: 00000206 ORIG_RAX: 0000000000000139
[ 1945.890362] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f2e3f2d6499
[ 1945.890713] RDX: 0000000000000000 RSI: 000055e8ff18226b RDI: 0000000000000003
[ 1945.891033] RBP: 00007fffdd292c70 R08: 0000000000000000 R09: 00007f2e3f59bea0
[ 1945.891370] R10: 0000000000000003 R11: 0000000000000206 R12: 000000000000006a
[ 1945.891729] R13: 000055e90114e1d0 R14: 000055e90114e130 R15: 00007fffdd292b3c
[ 1945.892040] Code: 48 8b 04 25 28 00 00 00 48 89 45 d0 31 c0 e8 7f 68 4e 00 41 c1 ec 09 48 8b 7b 08 45 85 e4 0f 85 d7 00 00 00 48 8b 87 80 00 00 00 <4c> 8b b8 d0 03 00 00 4d 85 ff 0f 84 70 03 00 00 8b 43 14 a9 00 
[ 1945.893127] RIP: generic_make_request_checks+0x49/0x5b0 RSP: ffffbe04c4b03a60
[ 1945.893515] CR2: 00000000000003d0
[ 1945.893867] fbcon_switch: detected unhandled fb_set_par error, error code -16
[ 1945.894968] fbcon_switch: detected unhandled fb_set_par error, error code -16
[ 1945.896013] ---[ end trace fc5fe7c84aae7b6d ]---

那么,有什么我需要检查的吗? uname - 4.13.0-26-generic

Ubutnu 16.4 LTS gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.5)

1 个答案:

答案 0 :(得分:0)

此处可找到解决方案: Reading block_device from kernel (3.7) module: segfault in submit_bio, bd_disk is missing

问题的根源: lookup_bdev()不构成功能强大的Block I / O上下文,所以 在我的情况下,它需要使用 blkdev_get_by_path()