• Linus Walleij's avatar
    mmc: block: Convert RPMB to a character device · 97548575
    Linus Walleij authored
    The RPMB partition on the eMMC devices is a special area used
    for storing cryptographically safe information signed by a
    special secret key. To write and read records from this special
    area, authentication is needed.
    
    The RPMB area is *only* and *exclusively* accessed using
    ioctl():s from userspace. It is not really a block device,
    as blocks cannot be read or written from the device, also
    the signed chunks that can be stored on the RPMB are actually
    256 bytes, not 512 making a block device a real bad fit.
    
    Currently the RPMB partition spawns a separate block device
    named /dev/mmcblkNrpmb for each device with an RPMB partition,
    including the creation of a block queue with its own kernel
    thread and all overhead associated with this. On the Ux500
    HREFv60 platform, for example, the two eMMCs means that two
    block queues with separate threads are created for no use
    whatsoever.
    
    I have concluded that this block device design for RPMB is
    actually pretty wrong. The RPMB area should have been designed
    to be accessed from /dev/mmcblkN directly, using ioctl()s on
    the main block device. It is however way too late to change
    that, since userspace expects to open an RPMB device in
    /dev/mmcblkNrpmb and we cannot break userspace.
    
    This patch tries to amend the situation using the following
    strategy:
    
    - Stop creating a block device for the RPMB partition/area
    
    - Instead create a custom, dynamic character device with
      the same name.
    
    - Make this new character device support exactly the same
      set of ioctl()s as the old block device.
    
    - Wrap the requests back to the same ioctl() handlers, but
      issue them on the block queue of the main partition/area,
      i.e. /dev/mmcblkN
    
    We need to create a special "rpmb" bus type in order to get
    udev and/or busybox hot/coldplug to instantiate the device
    node properly.
    
    Before the patch, this appears in 'ps aux':
    
    101 root       0:00 [mmcqd/2rpmb]
    123 root       0:00 [mmcqd/3rpmb]
    
    After applying the patch these surplus block queue threads
    are gone, but RPMB is as usable as ever using the userspace
    MMC tools, such as 'mmc rpmb read-counter'.
    
    We get instead those dynamice devices in /dev:
    
    brw-rw----    1 root     root      179,   0 Jan  1  2000 mmcblk0
    brw-rw----    1 root     root      179,   1 Jan  1  2000 mmcblk0p1
    brw-rw----    1 root     root      179,   2 Jan  1  2000 mmcblk0p2
    brw-rw----    1 root     root      179,   5 Jan  1  2000 mmcblk0p5
    brw-rw----    1 root     root      179,   8 Jan  1  2000 mmcblk2
    brw-rw----    1 root     root      179,  16 Jan  1  2000 mmcblk2boot0
    brw-rw----    1 root     root      179,  24 Jan  1  2000 mmcblk2boot1
    crw-rw----    1 root     root      248,   0 Jan  1  2000 mmcblk2rpmb
    brw-rw----    1 root     root      179,  32 Jan  1  2000 mmcblk3
    brw-rw----    1 root     root      179,  40 Jan  1  2000 mmcblk3boot0
    brw-rw----    1 root     root      179,  48 Jan  1  2000 mmcblk3boot1
    brw-rw----    1 root     root      179,  33 Jan  1  2000 mmcblk3p1
    crw-rw----    1 root     root      248,   1 Jan  1  2000 mmcblk3rpmb
    
    Notice the (248,0) and (248,1) character devices for RPMB.
    
    Cc: Tomas Winkler <tomas.winkler@intel.com>
    Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
    Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
    97548575
block.c 70.7 KB