diff --git a/MAINTAINERS b/MAINTAINERS index 4e593e0c6de7..7caae05320d7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14512,3 +14512,11 @@ F: arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi AMLOGIC G12B w400 buildroot dts M: liangzhuo xie F: arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts + +AMLOGIC P PARTITION DTSI +M: Xindong Xu +F: arch/arm64/boot/dts/amlogic/firmware_avb.dtsi +F: arch/arm64/boot/dts/amlogic/firmware_normal.dtsi +F: arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_32.dtsi +F: arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_64.dtsi +F: arch/arm64/boot/dts/amlogic/partition_mbox_p241_P.dtsi diff --git a/arch/arm64/boot/dts/amlogic/firmware_avb.dtsi b/arch/arm64/boot/dts/amlogic/firmware_avb.dtsi new file mode 100644 index 000000000000..c5c9bc9f4698 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/firmware_avb.dtsi @@ -0,0 +1,52 @@ +/* + * Amlogic partition set for normal + * + * Copyright (c) 2017-2017 Amlogic Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ +/ { + firmware { + android { + compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor"; + by_name_prefix="/dev/block"; + }; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,avb"; + }; + + vendor { + compatible = "android,vendor"; + dev = "/dev/block/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,avb"; + }; + odm { + compatible = "android,odm"; + dev = "/dev/block/odm"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + product { + compatible = "android,product"; + dev = "/dev/block/product"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; + }; + }; +};/* end of / */ diff --git a/arch/arm64/boot/dts/amlogic/firmware_normal.dtsi b/arch/arm64/boot/dts/amlogic/firmware_normal.dtsi new file mode 100644 index 000000000000..9d113d9b2a96 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/firmware_normal.dtsi @@ -0,0 +1,52 @@ +/* + * Amlogic partition set for normal + * + * Copyright (c) 2017-2017 Amlogic Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ +/ { + firmware { + android { + compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor"; + by_name_prefix="/dev/block"; + }; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + + vendor { + compatible = "android,vendor"; + dev = "/dev/block/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + odm { + compatible = "android,odm"; + dev = "/dev/block/odm"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + product { + compatible = "android,product"; + dev = "/dev/block/product"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; + }; + }; +};/* end of / */ diff --git a/arch/arm64/boot/dts/amlogic/partition_mbox_ab.dtsi b/arch/arm64/boot/dts/amlogic/partition_mbox_ab.dtsi index 62916ddda4ba..a78cd67fdc23 100644 --- a/arch/arm64/boot/dts/amlogic/partition_mbox_ab.dtsi +++ b/arch/arm64/boot/dts/amlogic/partition_mbox_ab.dtsi @@ -8,7 +8,7 @@ */ / { partitions: partitions{ - parts = <16>; + parts = <18>; part-0 = <&logo>; part-1 = <&boot_a>; part-2 = <&misc>; @@ -16,15 +16,17 @@ part-4 = <&cri_data>; part-5 = <¶m>; part-6 = <&boot_b>; - part-7 = <&rsv>; - part-8 = <&tee>; - part-9 = <&vendor_a>; - part-10 = <&vendor_b>; - part-11 = <&odm_a>; - part-12 = <&odm_b>; - part-13 = <&system_a>; - part-14 = <&system_b>; - part-15 = <&data>; + part-7 = <&vbmeta_a>; + part-8 = <&vbmeta_b>; + part-9 = <&rsv>; + part-10 = <&tee>; + part-11 = <&vendor_a>; + part-12 = <&vendor_b>; + part-13 = <&odm_a>; + part-14 = <&odm_b>; + part-15 = <&system_a>; + part-16 = <&system_b>; + part-17 = <&data>; logo:logo{ pname = "logo"; @@ -52,9 +54,19 @@ size = <0x0 0x800000>; mask = <2>; }; + vbmeta_a:vbmeta_a{ + pname = "vbmeta_a"; + size = <0x0 0x100000>; + mask = <1>; + }; + vbmeta_b:vbmeta_b{ + pname = "vbmeta_b"; + size = <0x0 0x100000>; + mask = <1>; + }; rsv:rsv{ pname = "rsv"; - size = <0x0 0x1000000>; + size = <0x0 0xE00000>; mask = <1>; }; param:param{ diff --git a/arch/arm64/boot/dts/amlogic/partition_mbox_ab_avb.dtsi b/arch/arm64/boot/dts/amlogic/partition_mbox_ab_avb.dtsi new file mode 100644 index 000000000000..c64a54e27c17 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/partition_mbox_ab_avb.dtsi @@ -0,0 +1,169 @@ +/* + * Amlogic partition set for normal + * + * Copyright (c) 2017-2017 Amlogic Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ +/ { + partitions: partitions{ + parts = <18>; + part-0 = <&logo>; + part-1 = <&boot_a>; + part-2 = <&misc>; + part-3 = <&dto>; + part-4 = <&cri_data>; + part-5 = <¶m>; + part-6 = <&boot_b>; + part-7 = <&vbmeta_a>; + part-8 = <&vbmeta_b>; + part-9 = <&rsv>; + part-10 = <&tee>; + part-11 = <&vendor_a>; + part-12 = <&vendor_b>; + part-13 = <&odm_a>; + part-14 = <&odm_b>; + part-15 = <&system_a>; + part-16 = <&system_b>; + part-17 = <&data>; + + logo:logo{ + pname = "logo"; + size = <0x0 0x800000>; + mask = <1>; + }; + boot_a:boot_a{ + pname = "boot_a"; + size = <0x0 0x1000000>; + mask = <1>; + }; + misc:misc{ + pname = "misc"; + size = <0x0 0x800000>; + mask = <1>; + }; + dto:dto{ + pname = "dto"; + size = <0x0 0x800000>; + mask = <1>; + }; + cri_data:cri_data + { + pname = "cri_data"; + size = <0x0 0x800000>; + mask = <2>; + }; + vbmeta_a:vbmeta_a{ + pname = "vbmeta_a"; + size = <0x0 0x100000>; + mask = <1>; + }; + vbmeta_b:vbmeta_b{ + pname = "vbmeta_b"; + size = <0x0 0x100000>; + mask = <1>; + }; + rsv:rsv{ + pname = "rsv"; + size = <0x0 0xE00000>; + mask = <1>; + }; + param:param{ + pname = "param"; + size = <0x0 0x1000000>; + mask = <2>; + }; + boot_b:boot_b + { + pname = "boot_b"; + size = <0x0 0x1000000>; + mask = <1>; + }; + tee:tee{ + pname = "tee"; + size = <0x0 0x2000000>; + mask = <1>; + }; + vendor_a:vendor_a + { + pname = "vendor_a"; + size = <0x0 0x10000000>; + mask = <1>; + }; + vendor_b:vendor_b + { + pname = "vendor_b"; + size = <0x0 0x10000000>; + mask = <1>; + }; + odm_a:odm_a + { + pname = "odm_a"; + size = <0x0 0x10000000>; + mask = <1>; + }; + odm_b:odm_b + { + pname = "odm_b"; + size = <0x0 0x10000000>; + mask = <1>; + }; + system_a:system_a + { + pname = "system_a"; + size = <0x0 0x74000000>; + mask = <1>; + }; + system_b:system_b + { + pname = "system_b"; + size = <0x0 0x74000000>; + mask = <1>; + }; + data:data + { + pname = "data"; + size = <0xffffffff 0xffffffff>; + mask = <4>; + }; + }; + + firmware { + android { + compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor"; + by_name_prefix="/dev/block"; + }; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,slotselect,avb"; + }; + + vendor { + compatible = "android,vendor"; + dev = "/dev/block/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,slotselect,avb"; + }; + + odm { + compatible = "android,odm"; + dev = "/dev/block/odm"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,slotselect"; + }; + }; + }; + }; + +};/* end of / */ diff --git a/arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_32.dtsi b/arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_32.dtsi new file mode 100644 index 000000000000..1f519c8b6710 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_32.dtsi @@ -0,0 +1,126 @@ +/* + * Amlogic partition set for normal + * + * Copyright (c) 2017-2017 Amlogic Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ + +#include "firmware_normal.dtsi" + +/ { + partitions: partitions{ + parts = <17>; + part-0 = <&logo>; + part-1 = <&recovery>; + part-2 = <&misc>; + part-3 = <&dto>; + part-4 = <&cri_data>; + part-5 = <¶m>; + part-6 = <&boot>; + part-7 = <&rsv>; + part-8 = <&metadata>; + part-9 = <&vbmeta>; + part-10 = <&tee>; + part-11 = <&vendor>; + part-12 = <&odm>; + part-13 = <&system>; + part-14 = <&product>; + part-15 = <&cache>; + part-16 = <&data>; + + logo:logo{ + pname = "logo"; + size = <0x0 0x800000>; + mask = <1>; + }; + recovery:recovery{ + pname = "recovery"; + size = <0x0 0x1800000>; + mask = <1>; + }; + misc:misc{ + pname = "misc"; + size = <0x0 0x800000>; + mask = <1>; + }; + dto:dto{ + pname = "dto"; + size = <0x0 0x800000>; + mask = <1>; + }; + cri_data:cri_data + { + pname = "cri_data"; + size = <0x0 0x800000>; + mask = <2>; + }; + rsv:rsv{ + pname = "rsv"; + size = <0x0 0x1000000>; + mask = <1>; + }; + metadata:metadata{ + pname = "metadata"; + size = <0x0 0x1000000>; + mask = <1>; + }; + vbmeta:vbmeta{ + pname = "vbmeta"; + size = <0x0 0x200000>; + mask = <1>; + }; + param:param{ + pname = "param"; + size = <0x0 0x1000000>; + mask = <2>; + }; + boot:boot + { + pname = "boot"; + size = <0x0 0x1000000>; + mask = <1>; + }; + tee:tee{ + pname = "tee"; + size = <0x0 0x2000000>; + mask = <1>; + }; + vendor:vendor + { + pname = "vendor"; + size = <0x0 0x10000000>; + mask = <1>; + }; + odm:odm + { + pname = "odm"; + size = <0x0 0x8000000>; + mask = <1>; + }; + system:system + { + pname = "system"; + size = <0x0 0x50000000>; + mask = <1>; + }; + product:product{ + pname = "product"; + size = <0x0 0x8000000>; + mask = <1>; + }; + cache:cache + { + pname = "cache"; + size = <0x0 0x46000000>; + mask = <2>; + }; + data:data + { + pname = "data"; + size = <0xffffffff 0xffffffff>; + mask = <4>; + }; + }; +};/* end of / */ diff --git a/arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_64.dtsi b/arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_64.dtsi new file mode 100644 index 000000000000..f8f8bc593d08 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/partition_mbox_normal_P_64.dtsi @@ -0,0 +1,126 @@ +/* + * Amlogic partition set for normal + * + * Copyright (c) 2017-2017 Amlogic Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ + +#include "firmware_normal.dtsi" + +/ { + partitions: partitions{ + parts = <17>; + part-0 = <&logo>; + part-1 = <&recovery>; + part-2 = <&misc>; + part-3 = <&dto>; + part-4 = <&cri_data>; + part-5 = <¶m>; + part-6 = <&boot>; + part-7 = <&rsv>; + part-8 = <&metadata>; + part-9 = <&vbmeta>; + part-10 = <&tee>; + part-11 = <&vendor>; + part-12 = <&odm>; + part-13 = <&system>; + part-14 = <&product>; + part-15 = <&cache>; + part-16 = <&data>; + + logo:logo{ + pname = "logo"; + size = <0x0 0x800000>; + mask = <1>; + }; + recovery:recovery{ + pname = "recovery"; + size = <0x0 0x1800000>; + mask = <1>; + }; + misc:misc{ + pname = "misc"; + size = <0x0 0x800000>; + mask = <1>; + }; + dto:dto{ + pname = "dto"; + size = <0x0 0x800000>; + mask = <1>; + }; + cri_data:cri_data + { + pname = "cri_data"; + size = <0x0 0x800000>; + mask = <2>; + }; + rsv:rsv{ + pname = "rsv"; + size = <0x0 0x1000000>; + mask = <1>; + }; + metadata:metadata{ + pname = "metadata"; + size = <0x0 0x1000000>; + mask = <1>; + }; + vbmeta:vbmeta{ + pname = "vbmeta"; + size = <0x0 0x200000>; + mask = <1>; + }; + param:param{ + pname = "param"; + size = <0x0 0x1000000>; + mask = <2>; + }; + boot:boot + { + pname = "boot"; + size = <0x0 0x1000000>; + mask = <1>; + }; + tee:tee{ + pname = "tee"; + size = <0x0 0x2000000>; + mask = <1>; + }; + vendor:vendor + { + pname = "vendor"; + size = <0x0 0x10000000>; + mask = <1>; + }; + odm:odm + { + pname = "odm"; + size = <0x0 0x8000000>; + mask = <1>; + }; + system:system + { + pname = "system"; + size = <0x0 0x62C00000>; + mask = <1>; + }; + product:product{ + pname = "product"; + size = <0x0 0x8000000>; + mask = <1>; + }; + cache:cache + { + pname = "cache"; + size = <0x0 0x46000000>; + mask = <2>; + }; + data:data + { + pname = "data"; + size = <0xffffffff 0xffffffff>; + mask = <4>; + }; + }; +};/* end of / */ diff --git a/arch/arm64/boot/dts/amlogic/partition_mbox_p241_P.dtsi b/arch/arm64/boot/dts/amlogic/partition_mbox_p241_P.dtsi new file mode 100644 index 000000000000..5ae903093881 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/partition_mbox_p241_P.dtsi @@ -0,0 +1,126 @@ +/* + * Amlogic partition set for normal + * + * Copyright (c) 2017-2017 Amlogic Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ + +#include "firmware_normal.dtsi" + +/ { + partitions: partitions{ + parts = <17>; + part-0 = <&logo>; + part-1 = <&recovery>; + part-2 = <&misc>; + part-3 = <&dto>; + part-4 = <&cri_data>; + part-5 = <¶m>; + part-6 = <&boot>; + part-7 = <&rsv>; + part-8 = <&metadata>; + part-9 = <&vbmeta>; + part-10 = <&tee>; + part-11 = <&vendor>; + part-12 = <&odm>; + part-13 = <&system>; + part-14 = <&product>; + part-15 = <&cache>; + part-16 = <&data>; + + logo:logo{ + pname = "logo"; + size = <0x0 0x800000>; + mask = <1>; + }; + recovery:recovery{ + pname = "recovery"; + size = <0x0 0x1800000>; + mask = <1>; + }; + misc:misc{ + pname = "misc"; + size = <0x0 0x800000>; + mask = <1>; + }; + dto:dto{ + pname = "dto"; + size = <0x0 0x800000>; + mask = <1>; + }; + cri_data:cri_data + { + pname = "cri_data"; + size = <0x0 0x800000>; + mask = <2>; + }; + rsv:rsv{ + pname = "rsv"; + size = <0x0 0x1000000>; + mask = <1>; + }; + metadata:metadata{ + pname = "metadata"; + size = <0x0 0x1000000>; + mask = <1>; + }; + vbmeta:vbmeta{ + pname = "vbmeta"; + size = <0x0 0x200000>; + mask = <1>; + }; + param:param{ + pname = "param"; + size = <0x0 0x1000000>; + mask = <2>; + }; + boot:boot + { + pname = "boot"; + size = <0x0 0x1000000>; + mask = <1>; + }; + tee:tee{ + pname = "tee"; + size = <0x0 0x2000000>; + mask = <1>; + }; + vendor:vendor + { + pname = "vendor"; + size = <0x0 0x10000000>; + mask = <1>; + }; + odm:odm + { + pname = "odm"; + size = <0x0 0x8000000>; + mask = <1>; + }; + system:system + { + pname = "system"; + size = <0x0 0x50000000>; + mask = <1>; + }; + product:product{ + pname = "product"; + size = <0x0 0x8000000>; + mask = <1>; + }; + cache:cache + { + pname = "cache"; + size = <0x0 0x25000000>; + mask = <2>; + }; + data:data + { + pname = "data"; + size = <0xffffffff 0xffffffff>; + mask = <4>; + }; + }; +};/* end of / */ diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index 017b983a19a9..d24bd92a3eb9 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -389,6 +389,7 @@ CONFIG_DM_VERITY=y CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE=1 CONFIG_DM_VERITY_FEC=y CONFIG_DM_ANDROID_VERITY=y +CONFIG_DM_VERITY_AVB=y CONFIG_NETDEVICES=y CONFIG_TUN=y CONFIG_8139CP=y diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index c97b731111d5..9525e3a0d902 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -516,6 +516,17 @@ config DM_LOG_WRITES If unsure, say N. +config DM_VERITY_AVB + tristate "Support AVB specific verity error behavior" + depends on DM_VERITY + ---help--- + Enables Android Verified Boot platform-specific error + behavior. In particular, it will modify the vbmeta partition + specified on the kernel command-line when non-transient error + occurs (followed by a panic). + + If unsure, say N. + config DM_ANDROID_VERITY bool "Android verity target support" depends on DM_VERITY=y diff --git a/drivers/md/Makefile b/drivers/md/Makefile index f26ce41af389..63c317063efa 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -68,3 +68,7 @@ endif ifeq ($(CONFIG_DM_VERITY_FEC),y) dm-verity-objs += dm-verity-fec.o endif + +ifeq ($(CONFIG_DM_VERITY_AVB),y) +dm-verity-objs += dm-verity-avb.o +endif diff --git a/drivers/md/dm-verity-avb.c b/drivers/md/dm-verity-avb.c new file mode 100644 index 000000000000..3220bc46fbb9 --- /dev/null +++ b/drivers/md/dm-verity-avb.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2017 Google. + * + * This file is released under the GPLv2. + * + * Based on drivers/md/dm-verity-chromeos.c + */ + +#include +#include +#include + +#define DM_MSG_PREFIX "verity-avb" + +/* Set via module parameters. */ +static char avb_vbmeta_device[64]; +static char avb_invalidate_on_error[4]; + +static void invalidate_vbmeta_endio(struct bio *bio) +{ + if (bio->bi_error) + DMERR("invalidate_vbmeta_endio: error %d", bio->bi_error); + complete(bio->bi_private); +} + +static int invalidate_vbmeta_submit(struct bio *bio, + struct block_device *bdev, + int rw, int access_last_sector, + struct page *page) +{ + DECLARE_COMPLETION_ONSTACK(wait); + + bio->bi_private = &wait; + bio->bi_end_io = invalidate_vbmeta_endio; + bio->bi_bdev = bdev; + bio->bi_iter.bi_sector = 0; + if (access_last_sector) { + sector_t last_sector; + + last_sector = (i_size_read(bdev->bd_inode)>>SECTOR_SHIFT) - 1; + bio->bi_iter.bi_sector = last_sector; + } + if (!bio_add_page(bio, page, PAGE_SIZE, 0)) { + DMERR("invalidate_vbmeta_submit: bio_add_page error"); + return -EIO; + } + + submit_bio(bio); + /* Wait up to 2 seconds for completion or fail. */ + if (!wait_for_completion_timeout(&wait, msecs_to_jiffies(2000))) + return -EIO; + return 0; +} + +static int invalidate_vbmeta(dev_t vbmeta_devt) +{ + int ret = 0; + struct block_device *bdev; + struct bio *bio; + struct page *page; + fmode_t dev_mode; + /* Ensure we do synchronous unblocked I/O. We may also need + * sync_bdev() on completion, but it really shouldn't. + */ + int rw = REQ_SYNC | REQ_SOFTBARRIER | REQ_NOIDLE; + int access_last_sector = 0; + + DMINFO("invalidate_vbmeta: acting on device %d:%d", + MAJOR(vbmeta_devt), MINOR(vbmeta_devt)); + + /* First we open the device for reading. */ + dev_mode = FMODE_READ | FMODE_EXCL; + bdev = blkdev_get_by_dev(vbmeta_devt, dev_mode, + invalidate_vbmeta); + if (IS_ERR(bdev)) { + DMERR("invalidate_kernel: could not open device for reading"); + dev_mode = 0; + ret = -ENOENT; + goto failed_to_read; + } + + bio = bio_alloc(GFP_NOIO, 1); + if (!bio) { + ret = -ENOMEM; + goto failed_bio_alloc; + } + + bio_set_op_attrs(bio, REQ_OP_READ, rw); + page = alloc_page(GFP_NOIO); + if (!page) { + ret = -ENOMEM; + goto failed_to_alloc_page; + } + + access_last_sector = 0; + ret = invalidate_vbmeta_submit(bio, bdev, rw, access_last_sector, page); + if (ret) { + DMERR("invalidate_vbmeta: error reading"); + goto failed_to_submit_read; + } + + /* We have a page. Let's make sure it looks right. */ + if (memcmp("AVB0", page_address(page), 4) == 0) { + /* Stamp it. */ + memcpy(page_address(page), "AVE0", 4); + DMINFO("invalidate_vbmeta: found vbmeta partition"); + } else { + /* Could be this is on a AVB footer, check. Also, since the + * AVB footer is in the last 64 bytes, adjust for the fact that + * we're dealing with 512-byte sectors. + */ + size_t offset = (1<bi_remaining. + */ + bio_reset(bio); + + bio_set_op_attrs(bio, REQ_OP_WRITE, rw); + ret = invalidate_vbmeta_submit(bio, bdev, rw, access_last_sector, page); + if (ret) { + DMERR("invalidate_vbmeta: error writing"); + goto failed_to_submit_write; + } + + DMERR("invalidate_vbmeta: completed."); + ret = 0; +failed_to_submit_write: +failed_to_write: +invalid_header: + __free_page(page); +failed_to_submit_read: + /* Technically, we'll leak a page with the pending bio, but + * we're about to reboot anyway. + */ +failed_to_alloc_page: + bio_put(bio); +failed_bio_alloc: + if (dev_mode) + blkdev_put(bdev, dev_mode); +failed_to_read: + return ret; +} + +void dm_verity_avb_error_handler(void) +{ + dev_t dev; + + DMINFO("AVB error handler called for %s", avb_vbmeta_device); + + if (strcmp(avb_invalidate_on_error, "yes") != 0) { + DMINFO("Not configured to invalidate"); + return; + } + + if (avb_vbmeta_device[0] == '\0') { + DMERR("avb_vbmeta_device parameter not set"); + goto fail_no_dev; + } + + dev = name_to_dev_t(avb_vbmeta_device); + if (!dev) { + DMERR("No matching partition for device: %s", + avb_vbmeta_device); + goto fail_no_dev; + } + + invalidate_vbmeta(dev); + +fail_no_dev: + ; +} + +static int __init dm_verity_avb_init(void) +{ + DMINFO("AVB error handler initialized with vbmeta device: %s", + avb_vbmeta_device); + return 0; +} + +static void __exit dm_verity_avb_exit(void) +{ +} + +module_init(dm_verity_avb_init); +module_exit(dm_verity_avb_exit); + +MODULE_AUTHOR("David Zeuthen "); +MODULE_DESCRIPTION("AVB-specific error handler for dm-verity"); +MODULE_LICENSE("GPL"); + +/* Declare parameter with no module prefix */ +#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "androidboot.vbmeta." +module_param_string(device, avb_vbmeta_device, sizeof(avb_vbmeta_device), 0000); +module_param_string(invalidate_on_error, avb_invalidate_on_error, + sizeof(avb_invalidate_on_error), 0000); diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index d96aa84cacd2..615a6fdb2dff 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -235,8 +235,12 @@ out: if (v->mode == DM_VERITY_MODE_LOGGING) return 0; - if (v->mode == DM_VERITY_MODE_RESTART) + if (v->mode == DM_VERITY_MODE_RESTART) { +#ifdef CONFIG_DM_VERITY_AVB + dm_verity_avb_error_handler(); +#endif kernel_restart("dm-verity device corrupted"); + } return 1; } diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h index 6d6d8df5b58c..d216fc76d350 100644 --- a/drivers/md/dm-verity.h +++ b/drivers/md/dm-verity.h @@ -137,4 +137,5 @@ extern void verity_io_hints(struct dm_target *ti, struct queue_limits *limits); extern void verity_dtr(struct dm_target *ti); extern int verity_ctr(struct dm_target *ti, unsigned argc, char **argv); extern int verity_map(struct dm_target *ti, struct bio *bio); +extern void dm_verity_avb_error_handler(void); #endif /* DM_VERITY_H */