Merge "libavb: update LICENSE info"
diff --git a/LICENSE b/LICENSE
index d21621a..7d1e37b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,7 @@
-Copyright 2016, The Android Open Source Project
+Code in this repo uses one or more of the following licenses.
+Refer to each file to determine which licenses apply.
+
+-------------------------------------------------------------------------
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
@@ -18,3 +21,43 @@
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------------
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the project nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD
diff --git a/README.md b/README.md
index 54d215c..1f599c6 100644
--- a/README.md
+++ b/README.md
@@ -257,10 +257,6 @@
       boot loaders using the experimental `libavb_ab` A/B stack.
       **NOTE**: This code is *DEPRECATED* and will be removed Jun 1
       2018.
-* `contrib/`
-    + Contains patches needed in other projects for interoperability with AVB.
-      For example, `contrib/linux/4.4` has the patches for Linux kernel 4.4,
-      which are generated by `git format-patch`.
 * `Android.bp`
     + Build instructions for building `libavb` (a static library for use
       on the device), host-side libraries (for unit tests), and unit
diff --git a/contrib/linux/4.4/0001-ANDROID-Update-init-do_mounts_dm.c-to-the-latest-Chr.patch b/contrib/linux/4.4/0001-ANDROID-Update-init-do_mounts_dm.c-to-the-latest-Chr.patch
deleted file mode 100644
index ff41996..0000000
--- a/contrib/linux/4.4/0001-ANDROID-Update-init-do_mounts_dm.c-to-the-latest-Chr.patch
+++ /dev/null
@@ -1,760 +0,0 @@
-From 6a6a7657c231e947233c43ae0522bbd4edf0139e Mon Sep 17 00:00:00 2001
-From: David Zeuthen <zeuthen@google.com>
-Date: Tue, 24 Jan 2017 13:02:35 -0500
-Subject: [PATCH 1/2] ANDROID: Update init/do_mounts_dm.c to the latest
- ChromiumOS version.
-
-This is needed for AVB integration work.
-
-Bug: 31796270
-Test: Manually tested (other arch).
-Change-Id: I32fd37c1578c6414e3e6ff277d16ad94df7886b8
-Signed-off-by: David Zeuthen <zeuthen@google.com>
----
- include/linux/device-mapper.h |   7 +
- init/do_mounts_dm.c           | 556 +++++++++++++++++++++++-------------------
- 2 files changed, 307 insertions(+), 256 deletions(-)
-
-diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
-index b874d5b61ffc..f3f87db34429 100644
---- a/include/linux/device-mapper.h
-+++ b/include/linux/device-mapper.h
-@@ -415,6 +415,13 @@ union map_info *dm_get_rq_mapinfo(struct request *rq);
- 
- struct queue_limits *dm_get_queue_limits(struct mapped_device *md);
- 
-+void dm_lock_md_type(struct mapped_device *md);
-+void dm_unlock_md_type(struct mapped_device *md);
-+void dm_set_md_type(struct mapped_device *md, unsigned type);
-+unsigned dm_get_md_type(struct mapped_device *md);
-+int dm_setup_md_queue(struct mapped_device *md);
-+unsigned dm_table_get_type(struct dm_table *t);
-+
- /*
-  * Geometry functions.
-  */
-diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c
-index ecda58df9a19..bce1c2fbb915 100644
---- a/init/do_mounts_dm.c
-+++ b/init/do_mounts_dm.c
-@@ -5,13 +5,17 @@
-  *
-  * This file is released under the GPL.
-  */
-+#include <linux/async.h>
-+#include <linux/ctype.h>
- #include <linux/device-mapper.h>
- #include <linux/fs.h>
- #include <linux/string.h>
-+#include <linux/delay.h>
- 
- #include "do_mounts.h"
--#include "../drivers/md/dm.h"
- 
-+#define DM_MAX_DEVICES 256
-+#define DM_MAX_TARGETS 256
- #define DM_MAX_NAME 32
- #define DM_MAX_UUID 129
- #define DM_NO_UUID "none"
-@@ -19,14 +23,47 @@
- #define DM_MSG_PREFIX "init"
- 
- /* Separators used for parsing the dm= argument. */
--#define DM_FIELD_SEP ' '
--#define DM_LINE_SEP ','
-+#define DM_FIELD_SEP " "
-+#define DM_LINE_SEP ","
-+#define DM_ANY_SEP DM_FIELD_SEP DM_LINE_SEP
- 
- /*
-  * When the device-mapper and any targets are compiled into the kernel
-- * (not a module), one target may be created and used as the root device at
-- * boot time with the parameters given with the boot line dm=...
-- * The code for that is here.
-+ * (not a module), one or more device-mappers may be created and used
-+ * as the root device at boot time with the parameters given with the
-+ * boot line dm=...
-+ *
-+ * Multiple device-mappers can be stacked specifing the number of
-+ * devices. A device can have multiple targets if the the number of
-+ * targets is specified.
-+ *
-+ * TODO(taysom:defect 32847)
-+ * In the future, the <num> field will be mandatory.
-+ *
-+ * <device>        ::= [<num>] <device-mapper>+
-+ * <device-mapper> ::= <head> "," <target>+
-+ * <head>          ::= <name> <uuid> <mode> [<num>]
-+ * <target>        ::= <start> <length> <type> <options> ","
-+ * <mode>          ::= "ro" | "rw"
-+ * <uuid>          ::= xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | "none"
-+ * <type>          ::= "verity" | "bootcache" | ...
-+ *
-+ * Example:
-+ * 2 vboot none ro 1,
-+ *     0 1768000 bootcache
-+ *       device=aa55b119-2a47-8c45-946a-5ac57765011f+1
-+ *       signature=76e9be054b15884a9fa85973e9cb274c93afadb6
-+ *       cache_start=1768000 max_blocks=100000 size_limit=23 max_trace=20000,
-+ *   vroot none ro 1,
-+ *     0 1740800 verity payload=254:0 hashtree=254:0 hashstart=1740800 alg=sha1
-+ *       root_hexdigest=76e9be054b15884a9fa85973e9cb274c93afadb6
-+ *       salt=5b3549d54d6c7a3837b9b81ed72e49463a64c03680c47835bef94d768e5646fe
-+ *
-+ * Notes:
-+ *  1. uuid is a label for the device and we set it to "none".
-+ *  2. The <num> field will be optional initially and assumed to be 1.
-+ *     Once all the scripts that set these fields have been set, it will
-+ *     be made mandatory.
-  */
- 
- struct dm_setup_target {
-@@ -38,381 +75,388 @@ struct dm_setup_target {
- 	struct dm_setup_target *next;
- };
- 
--static struct {
-+struct dm_device {
- 	int minor;
- 	int ro;
- 	char name[DM_MAX_NAME];
- 	char uuid[DM_MAX_UUID];
--	char *targets;
-+	unsigned long num_targets;
- 	struct dm_setup_target *target;
- 	int target_count;
-+	struct dm_device *next;
-+};
-+
-+struct dm_option {
-+	char *start;
-+	char *next;
-+	size_t len;
-+	char delim;
-+};
-+
-+static struct {
-+	unsigned long num_devices;
-+	char *str;
- } dm_setup_args __initdata;
- 
- static __initdata int dm_early_setup;
- 
--static size_t __init get_dm_option(char *str, char **next, char sep)
-+static int __init get_dm_option(struct dm_option *opt, const char *accept)
- {
--	size_t len = 0;
--	char *endp = NULL;
-+	char *str = opt->next;
-+	char *endp;
- 
- 	if (!str)
- 		return 0;
- 
--	endp = strchr(str, sep);
-+	str = skip_spaces(str);
-+	opt->start = str;
-+	endp = strpbrk(str, accept);
- 	if (!endp) {  /* act like strchrnul */
--		len = strlen(str);
--		endp = str + len;
-+		opt->len = strlen(str);
-+		endp = str + opt->len;
- 	} else {
--		len = endp - str;
-+		opt->len = endp - str;
- 	}
--
--	if (endp == str)
--		return 0;
--
--	if (!next)
--		return len;
--
-+	opt->delim = *endp;
- 	if (*endp == 0) {
- 		/* Don't advance past the nul. */
--		*next = endp;
-+		opt->next = endp;
- 	} else {
--		*next = endp + 1;
-+		opt->next = endp + 1;
- 	}
--	return len;
--}
--
--static int __init dm_setup_args_init(void)
--{
--	dm_setup_args.minor = 0;
--	dm_setup_args.ro = 0;
--	dm_setup_args.target = NULL;
--	dm_setup_args.target_count = 0;
--	return 0;
-+	return opt->len != 0;
- }
- 
--static int __init dm_setup_cleanup(void)
-+static int __init dm_setup_cleanup(struct dm_device *devices)
- {
--	struct dm_setup_target *target = dm_setup_args.target;
--	struct dm_setup_target *old_target = NULL;
--	while (target) {
--		kfree(target->type);
--		kfree(target->params);
--		old_target = target;
--		target = target->next;
--		kfree(old_target);
--		dm_setup_args.target_count--;
-+	struct dm_device *dev = devices;
-+
-+	while (dev) {
-+		struct dm_device *old_dev = dev;
-+		struct dm_setup_target *target = dev->target;
-+		while (target) {
-+			struct dm_setup_target *old_target = target;
-+			kfree(target->type);
-+			kfree(target->params);
-+			target = target->next;
-+			kfree(old_target);
-+			dev->target_count--;
-+		}
-+		BUG_ON(dev->target_count);
-+		dev = dev->next;
-+		kfree(old_dev);
- 	}
--	BUG_ON(dm_setup_args.target_count);
- 	return 0;
- }
- 
--static char * __init dm_setup_parse_device_args(char *str)
-+static char * __init dm_parse_device(struct dm_device *dev, char *str)
- {
--	char *next = NULL;
--	size_t len = 0;
-+	struct dm_option opt;
-+	size_t len;
- 
- 	/* Grab the logical name of the device to be exported to udev */
--	len = get_dm_option(str, &next, DM_FIELD_SEP);
--	if (!len) {
-+	opt.next = str;
-+	if (!get_dm_option(&opt, DM_FIELD_SEP)) {
- 		DMERR("failed to parse device name");
- 		goto parse_fail;
- 	}
--	len = min(len + 1, sizeof(dm_setup_args.name));
--	strlcpy(dm_setup_args.name, str, len);  /* includes nul */
--	str = skip_spaces(next);
-+	len = min(opt.len + 1, sizeof(dev->name));
-+	strlcpy(dev->name, opt.start, len);  /* includes nul */
- 
- 	/* Grab the UUID value or "none" */
--	len = get_dm_option(str, &next, DM_FIELD_SEP);
--	if (!len) {
-+	if (!get_dm_option(&opt, DM_FIELD_SEP)) {
- 		DMERR("failed to parse device uuid");
- 		goto parse_fail;
- 	}
--	len = min(len + 1, sizeof(dm_setup_args.uuid));
--	strlcpy(dm_setup_args.uuid, str, len);
--	str = skip_spaces(next);
-+	len = min(opt.len + 1, sizeof(dev->uuid));
-+	strlcpy(dev->uuid, opt.start, len);
- 
- 	/* Determine if the table/device will be read only or read-write */
--	if (!strncmp("ro,", str, 3)) {
--		dm_setup_args.ro = 1;
--	} else if (!strncmp("rw,", str, 3)) {
--		dm_setup_args.ro = 0;
-+	get_dm_option(&opt, DM_ANY_SEP);
-+	if (!strncmp("ro", opt.start, opt.len)) {
-+		dev->ro = 1;
-+	} else if (!strncmp("rw", opt.start, opt.len)) {
-+		dev->ro = 0;
- 	} else {
- 		DMERR("failed to parse table mode");
- 		goto parse_fail;
- 	}
--	str = skip_spaces(str + 3);
- 
--	return str;
-+	/* Optional number field */
-+	/* XXX: The <num> field will be mandatory in the next round */
-+	if (opt.delim == DM_FIELD_SEP[0]) {
-+		if (!get_dm_option(&opt, DM_LINE_SEP))
-+			return NULL;
-+		dev->num_targets = simple_strtoul(opt.start, NULL, 10);
-+	} else {
-+		dev->num_targets = 1;
-+	}
-+	if (dev->num_targets > DM_MAX_TARGETS) {
-+		DMERR("too many targets %lu > %d",
-+			dev->num_targets, DM_MAX_TARGETS);
-+	}
-+	return opt.next;
- 
- parse_fail:
- 	return NULL;
- }
- 
--static void __init dm_substitute_devices(char *str, size_t str_len)
-+static char * __init dm_parse_targets(struct dm_device *dev, char *str)
- {
--	char *candidate = str;
--	char *candidate_end = str;
--	char old_char;
--	size_t len = 0;
--	dev_t dev;
--
--	if (str_len < 3)
--		return;
--
--	while (str && *str) {
--		candidate = strchr(str, '/');
--		if (!candidate)
--			break;
--
--		/* Avoid embedded slashes */
--		if (candidate != str && *(candidate - 1) != DM_FIELD_SEP) {
--			str = strchr(candidate, DM_FIELD_SEP);
--			continue;
--		}
--
--		len = get_dm_option(candidate, &candidate_end, DM_FIELD_SEP);
--		str = skip_spaces(candidate_end);
--		if (len < 3 || len > 37)  /* name_to_dev_t max; maj:mix min */
--			continue;
--
--		/* Temporarily terminate with a nul */
--		if (*candidate_end)
--			candidate_end--;
--		old_char = *candidate_end;
--		*candidate_end = '\0';
--
--		DMDEBUG("converting candidate device '%s' to dev_t", candidate);
--		/* Use the boot-time specific device naming */
--		dev = name_to_dev_t(candidate);
--		*candidate_end = old_char;
--
--		DMDEBUG(" -> %u", dev);
--		/* No suitable replacement found */
--		if (!dev)
--			continue;
--
--		/* Rewrite the /dev/path as a major:minor */
--		len = snprintf(candidate, len, "%u:%u", MAJOR(dev), MINOR(dev));
--		if (!len) {
--			DMERR("error substituting device major/minor.");
--			break;
--		}
--		candidate += len;
--		/* Pad out with spaces (fixing our nul) */
--		while (candidate < candidate_end)
--			*(candidate++) = DM_FIELD_SEP;
--	}
--}
--
--static int __init dm_setup_parse_targets(char *str)
--{
--	char *next = NULL;
--	size_t len = 0;
--	struct dm_setup_target **target = NULL;
-+	struct dm_option opt;
-+	struct dm_setup_target **target = &dev->target;
-+	unsigned long num_targets = dev->num_targets;
-+	unsigned long i;
- 
- 	/* Targets are defined as per the table format but with a
- 	 * comma as a newline separator. */
--	target = &dm_setup_args.target;
--	while (str && *str) {
-+	opt.next = str;
-+	for (i = 0; i < num_targets; i++) {
- 		*target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL);
- 		if (!*target) {
--			DMERR("failed to allocate memory for target %d",
--			      dm_setup_args.target_count);
-+			DMERR("failed to allocate memory for target %s<%ld>",
-+				dev->name, i);
- 			goto parse_fail;
- 		}
--		dm_setup_args.target_count++;
-+		dev->target_count++;
- 
--		(*target)->begin = simple_strtoull(str, &next, 10);
--		if (!next || *next != DM_FIELD_SEP) {
--			DMERR("failed to parse starting sector for target %d",
--			      dm_setup_args.target_count - 1);
-+		if (!get_dm_option(&opt, DM_FIELD_SEP)) {
-+			DMERR("failed to parse starting sector"
-+				" for target %s<%ld>", dev->name, i);
- 			goto parse_fail;
- 		}
--		str = skip_spaces(next + 1);
-+		(*target)->begin = simple_strtoull(opt.start, NULL, 10);
- 
--		(*target)->length = simple_strtoull(str, &next, 10);
--		if (!next || *next != DM_FIELD_SEP) {
--			DMERR("failed to parse length for target %d",
--			      dm_setup_args.target_count - 1);
-+		if (!get_dm_option(&opt, DM_FIELD_SEP)) {
-+			DMERR("failed to parse length for target %s<%ld>",
-+				dev->name, i);
- 			goto parse_fail;
- 		}
--		str = skip_spaces(next + 1);
--
--		len = get_dm_option(str, &next, DM_FIELD_SEP);
--		if (!len ||
--		    !((*target)->type = kstrndup(str, len, GFP_KERNEL))) {
--			DMERR("failed to parse type for target %d",
--			      dm_setup_args.target_count - 1);
-+		(*target)->length = simple_strtoull(opt.start, NULL, 10);
-+
-+		if (get_dm_option(&opt, DM_FIELD_SEP))
-+			(*target)->type = kstrndup(opt.start, opt.len,
-+							GFP_KERNEL);
-+		if (!((*target)->type)) {
-+			DMERR("failed to parse type for target %s<%ld>",
-+				dev->name, i);
- 			goto parse_fail;
- 		}
--		str = skip_spaces(next);
--
--		len = get_dm_option(str, &next, DM_LINE_SEP);
--		if (!len ||
--		    !((*target)->params = kstrndup(str, len, GFP_KERNEL))) {
--			DMERR("failed to parse params for target %d",
--			      dm_setup_args.target_count - 1);
-+		if (get_dm_option(&opt, DM_LINE_SEP))
-+			(*target)->params = kstrndup(opt.start, opt.len,
-+							GFP_KERNEL);
-+		if (!((*target)->params)) {
-+			DMERR("failed to parse params for target %s<%ld>",
-+				dev->name, i);
- 			goto parse_fail;
- 		}
--		str = skip_spaces(next);
--
--		/* Before moving on, walk through the copied target and
--		 * attempt to replace all /dev/xxx with the major:minor number.
--		 * It may not be possible to resolve them traditionally at
--		 * boot-time. */
--		dm_substitute_devices((*target)->params, len);
--
- 		target = &((*target)->next);
- 	}
--	DMDEBUG("parsed %d targets", dm_setup_args.target_count);
-+	DMDEBUG("parsed %d targets", dev->target_count);
- 
--	return 0;
-+	return opt.next;
- 
- parse_fail:
--	return 1;
-+	return NULL;
-+}
-+
-+static struct dm_device * __init dm_parse_args(void)
-+{
-+	struct dm_device *devices = NULL;
-+	struct dm_device **tail = &devices;
-+	struct dm_device *dev;
-+	char *str = dm_setup_args.str;
-+	unsigned long num_devices = dm_setup_args.num_devices;
-+	unsigned long i;
-+
-+	if (!str)
-+		return NULL;
-+	for (i = 0; i < num_devices; i++) {
-+		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-+		if (!dev) {
-+			DMERR("failed to allocated memory for dev");
-+			goto error;
-+		}
-+		*tail = dev;
-+		tail = &dev->next;
-+		/*
-+		 * devices are given minor numbers 0 - n-1
-+		 * in the order they are found in the arg
-+		 * string.
-+		 */
-+		dev->minor = i;
-+		str = dm_parse_device(dev, str);
-+		if (!str)	/* NULL indicates error in parsing, bail */
-+			goto error;
-+
-+		str = dm_parse_targets(dev, str);
-+		if (!str)
-+			goto error;
-+	}
-+	return devices;
-+error:
-+	dm_setup_cleanup(devices);
-+	return NULL;
- }
- 
- /*
-  * Parse the command-line parameters given our kernel, but do not
-  * actually try to invoke the DM device now; that is handled by
-- * dm_setup_drive after the low-level disk drivers have initialised.
-- * dm format is as follows:
-- *  dm="name uuid fmode,[table line 1],[table line 2],..."
-- * May be used with root=/dev/dm-0 as it always uses the first dm minor.
-+ * dm_setup_drives after the low-level disk drivers have initialised.
-+ * dm format is described at the top of the file.
-+ *
-+ * Because dm minor numbers are assigned in assending order starting with 0,
-+ * You can assume the first device is /dev/dm-0, the next device is /dev/dm-1,
-+ * and so forth.
-  */
--
- static int __init dm_setup(char *str)
- {
--	dm_setup_args_init();
-+	struct dm_option opt;
-+	unsigned long num_devices;
- 
--	str = dm_setup_parse_device_args(str);
- 	if (!str) {
- 		DMDEBUG("str is NULL");
- 		goto parse_fail;
- 	}
--
--	/* Target parsing is delayed until we have dynamic memory */
--	dm_setup_args.targets = str;
--
--	printk(KERN_INFO "dm: will configure '%s' on dm-%d\n",
--	       dm_setup_args.name, dm_setup_args.minor);
--
-+	opt.next = str;
-+	if (!get_dm_option(&opt, DM_FIELD_SEP))
-+		goto parse_fail;
-+	if (isdigit(opt.start[0])) {	/* XXX: Optional number field */
-+		num_devices = simple_strtoul(opt.start, NULL, 10);
-+		str = opt.next;
-+	} else {
-+		num_devices = 1;
-+		/* Don't advance str */
-+	}
-+	if (num_devices > DM_MAX_DEVICES) {
-+		DMDEBUG("too many devices %lu > %d",
-+			num_devices, DM_MAX_DEVICES);
-+	}
-+	dm_setup_args.str = str;
-+	dm_setup_args.num_devices = num_devices;
-+	DMINFO("will configure %lu devices", num_devices);
- 	dm_early_setup = 1;
- 	return 1;
- 
- parse_fail:
--	printk(KERN_WARNING "dm: Invalid arguments supplied to dm=.\n");
-+	DMWARN("Invalid arguments supplied to dm=.");
- 	return 0;
- }
- 
--
--static void __init dm_setup_drive(void)
-+static void __init dm_setup_drives(void)
- {
- 	struct mapped_device *md = NULL;
- 	struct dm_table *table = NULL;
- 	struct dm_setup_target *target;
--	char *uuid = dm_setup_args.uuid;
-+	struct dm_device *dev;
-+	char *uuid;
- 	fmode_t fmode = FMODE_READ;
-+	struct dm_device *devices;
- 
--	/* Finish parsing the targets. */
--	if (dm_setup_parse_targets(dm_setup_args.targets))
--		goto parse_fail;
--
--	if (dm_create(dm_setup_args.minor, &md)) {
--		DMDEBUG("failed to create the device");
--		goto dm_create_fail;
--	}
--	DMDEBUG("created device '%s'", dm_device_name(md));
--
--	/* In addition to flagging the table below, the disk must be
--	 * set explicitly ro/rw. */
--	set_disk_ro(dm_disk(md), dm_setup_args.ro);
-+	devices = dm_parse_args();
- 
--	if (!dm_setup_args.ro)
--		fmode |= FMODE_WRITE;
--	if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) {
--		DMDEBUG("failed to create the table");
--		goto dm_table_create_fail;
--	}
-+	for (dev = devices; dev; dev = dev->next) {
-+		if (dm_create(dev->minor, &md)) {
-+			DMDEBUG("failed to create the device");
-+			goto dm_create_fail;
-+		}
-+		DMDEBUG("created device '%s'", dm_device_name(md));
-+
-+		/*
-+		 * In addition to flagging the table below, the disk must be
-+		 * set explicitly ro/rw.
-+		 */
-+		set_disk_ro(dm_disk(md), dev->ro);
-+
-+		if (!dev->ro)
-+			fmode |= FMODE_WRITE;
-+		if (dm_table_create(&table, fmode, dev->target_count, md)) {
-+			DMDEBUG("failed to create the table");
-+			goto dm_table_create_fail;
-+		}
- 
--	dm_lock_md_type(md);
--	target = dm_setup_args.target;
--	while (target) {
--		DMINFO("adding target '%llu %llu %s %s'",
--		       (unsigned long long) target->begin,
--		       (unsigned long long) target->length, target->type,
--		       target->params);
--		if (dm_table_add_target(table, target->type, target->begin,
--					target->length, target->params)) {
--			DMDEBUG("failed to add the target to the table");
--			goto add_target_fail;
-+		dm_lock_md_type(md);
-+
-+		for (target = dev->target; target; target = target->next) {
-+			DMINFO("adding target '%llu %llu %s %s'",
-+			       (unsigned long long) target->begin,
-+			       (unsigned long long) target->length,
-+			       target->type, target->params);
-+			if (dm_table_add_target(table, target->type,
-+						target->begin,
-+						target->length,
-+						target->params)) {
-+				DMDEBUG("failed to add the target"
-+					" to the table");
-+				goto add_target_fail;
-+			}
-+		}
-+		if (dm_table_complete(table)) {
-+			DMDEBUG("failed to complete the table");
-+			goto table_complete_fail;
- 		}
--		target = target->next;
--	}
- 
--	if (dm_table_complete(table)) {
--		DMDEBUG("failed to complete the table");
--		goto table_complete_fail;
--	}
-+		/* Suspend the device so that we can bind it to the table. */
-+		if (dm_suspend(md, 0)) {
-+			DMDEBUG("failed to suspend the device pre-bind");
-+			goto suspend_fail;
-+		}
- 
--	if (dm_get_md_type(md) == DM_TYPE_NONE) {
-+		/* Initial table load: acquire type of table. */
- 		dm_set_md_type(md, dm_table_get_type(table));
-+
-+		/* Setup md->queue to reflect md's type. */
- 		if (dm_setup_md_queue(md)) {
- 			DMWARN("unable to set up device queue for new table.");
- 			goto setup_md_queue_fail;
- 		}
--	} else if (dm_get_md_type(md) != dm_table_get_type(table)) {
--		DMWARN("can't change device type after initial table load.");
--		goto setup_md_queue_fail;
--        }
--
--	/* Suspend the device so that we can bind it to the table. */
--	if (dm_suspend(md, 0)) {
--		DMDEBUG("failed to suspend the device pre-bind");
--		goto suspend_fail;
--	}
- 
--	/* Bind the table to the device. This is the only way to associate
--	 * md->map with the table and set the disk capacity directly. */
--	if (dm_swap_table(md, table)) {  /* should return NULL. */
--		DMDEBUG("failed to bind the device to the table");
--		goto table_bind_fail;
--	}
-+		/*
-+		 * Bind the table to the device. This is the only way
-+		 * to associate md->map with the table and set the disk
-+		 * capacity directly.
-+		 */
-+		if (dm_swap_table(md, table)) {  /* should return NULL. */
-+			DMDEBUG("failed to bind the device to the table");
-+			goto table_bind_fail;
-+		}
- 
--	/* Finally, resume and the device should be ready. */
--	if (dm_resume(md)) {
--		DMDEBUG("failed to resume the device");
--		goto resume_fail;
--	}
-+		/* Finally, resume and the device should be ready. */
-+		if (dm_resume(md)) {
-+			DMDEBUG("failed to resume the device");
-+			goto resume_fail;
-+		}
- 
--	/* Export the dm device via the ioctl interface */
--	if (!strcmp(DM_NO_UUID, dm_setup_args.uuid))
--		uuid = NULL;
--	if (dm_ioctl_export(md, dm_setup_args.name, uuid)) {
--		DMDEBUG("failed to export device with given name and uuid");
--		goto export_fail;
--	}
--	printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor);
-+		/* Export the dm device via the ioctl interface */
-+		if (!strcmp(DM_NO_UUID, dev->uuid))
-+			uuid = NULL;
-+		if (dm_ioctl_export(md, dev->name, uuid)) {
-+			DMDEBUG("failed to export device with given"
-+				" name and uuid");
-+			goto export_fail;
-+		}
- 
--	dm_unlock_md_type(md);
--	dm_setup_cleanup();
-+		dm_unlock_md_type(md);
-+
-+		DMINFO("dm-%d is ready", dev->minor);
-+	}
-+	dm_setup_cleanup(devices);
- 	return;
- 
- export_fail:
- resume_fail:
- table_bind_fail:
--suspend_fail:
- setup_md_queue_fail:
-+suspend_fail:
- table_complete_fail:
- add_target_fail:
- 	dm_unlock_md_type(md);
- dm_table_create_fail:
- 	dm_put(md);
- dm_create_fail:
--	dm_setup_cleanup();
--parse_fail:
--	printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n",
--	       dm_setup_args.minor, dm_setup_args.name);
-+	DMWARN("starting dm-%d (%s) failed",
-+	       dev->minor, dev->name);
-+	dm_setup_cleanup(devices);
- }
- 
- __setup("dm=", dm_setup);
-@@ -421,6 +465,6 @@ void __init dm_run_setup(void)
- {
- 	if (!dm_early_setup)
- 		return;
--	printk(KERN_INFO "dm: attempting early device configuration.\n");
--	dm_setup_drive();
-+	DMINFO("attempting early device configuration.");
-+	dm_setup_drives();
- }
--- 
-2.14.1.581.gf28d330327-goog
-
diff --git a/contrib/linux/4.4/0002-ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch b/contrib/linux/4.4/0002-ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch
deleted file mode 100644
index 0dad3a6..0000000
--- a/contrib/linux/4.4/0002-ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch
+++ /dev/null
@@ -1,343 +0,0 @@
-From fabdd30b4cf9ee341dabbbd51b2a1e3335d7d4cd Mon Sep 17 00:00:00 2001
-From: David Zeuthen <zeuthen@google.com>
-Date: Tue, 24 Jan 2017 13:17:01 -0500
-Subject: [PATCH 2/2] ANDROID: AVB error handler to invalidate vbmeta
- partition.
-
-If androidboot.vbmeta.device is set and points to a device with vbmeta
-magic, this header will be overwritten upon an irrecoverable dm-verity
-error. The side-effect of this is that the slot will fail to verify on
-next reboot, effectively triggering the boot loader to fallback to
-another slot. This work both if the vbmeta struct is at the start of a
-partition or if there's an AVB footer at the end.
-
-This code is based on drivers/md/dm-verity-chromeos.c from ChromiumOS.
-
-Example:
-
- [    0.000000] Kernel command line: rootfstype=ext4 init=/init console=ttyS0,115200 androidboot.console=ttyS0 androidboot.hardware=uefi_x86_64 enforcing=0 androidboot.selinux=permissive androidboot.debuggable=1 buildvariant=eng dm="1 vroot none ro 1,0 2080496 verity 1 PARTUUID=6779df46-78f6-4c69-bf53-59bb1fbf126b PARTUUID=6779df46-78f6-4c69-bf53-59bb1fbf126b 4096 4096 260062 260062 sha1 4f76354c86e430e27426d584a726f2fbffecae32 7e4085342d634065269631ac9a199e1a43f4632c 1 ignore_zero_blocks" root=0xfd00 androidboot.vbmeta.device=PARTUUID=b865935d-38fb-4c4e-b8b4-70dc67321552 androidboot.slot_suffix=_a androidboot.vbmeta.device_state=unlocked androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3200 androidboot.vbmeta.digest=14fe41c2b3696c31b7ad5eae7877d7d188995e1ab122c604aaaf4785850b91f7 skip_initramfs
- [...]
- [    0.612802] device-mapper: verity-avb: AVB error handler initialized with vbmeta device: PARTUUID=b865935d-38fb-4c4e-b8b4-70dc67321552
- [...]
- [    1.213804] device-mapper: init: attempting early device configuration.
- [    1.214752] device-mapper: init: adding target '0 2080496 verity 1 PARTUUID=6779df46-78f6-4c69-bf53-59bb1fbf126b PARTUUID=6779df46-78f6-4c69-bf53-59bb1fbf126b 4096 4096 260062 260062 sha1 4f76354c86e430e27426d584a726f2fbffecae32 7e4085342d634065269631ac9a199e1a43f4632c 1 ignore_zero_blocks'
- [    1.217643] device-mapper: init: dm-0 is ready
- [    1.226694] device-mapper: verity: 8:6: data block 0 is corrupted
- [    1.227666] device-mapper: verity-avb: AVB error handler called for PARTUUID=b865935d-38fb-4c4e-b8b4-70dc67321552
- [    1.234308] device-mapper: verity-avb: invalidate_vbmeta: found vbmeta partition
- [    1.235848] device-mapper: verity-avb: invalidate_vbmeta: completed.
- [...]
-
-Bug: 31622239
-Test: Manually tested (other arch).
-Change-Id: Idf6be32d6a3d28e15de9302aa26ad6a516d663aa
-Signed-off-by: David Zeuthen <zeuthen@google.com>
----
- drivers/md/Kconfig            |  11 ++
- drivers/md/Makefile           |   4 +
- drivers/md/dm-verity-avb.c    | 229 ++++++++++++++++++++++++++++++++++++++++++
- drivers/md/dm-verity-target.c |   6 +-
- drivers/md/dm-verity.h        |   1 +
- 5 files changed, 250 insertions(+), 1 deletion(-)
- create mode 100644 drivers/md/dm-verity-avb.c
-
-diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
-index 9eb08a43cd27..6f2fde5d98e7 100644
---- a/drivers/md/Kconfig
-+++ b/drivers/md/Kconfig
-@@ -515,6 +515,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 32b5d0a90d60..c22cc74c9fa8 100644
---- a/drivers/md/Makefile
-+++ b/drivers/md/Makefile
-@@ -69,3 +69,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..727aacbb1480
---- /dev/null
-+++ b/drivers/md/dm-verity-avb.c
-@@ -0,0 +1,229 @@
-+/*
-+ * Copyright (C) 2017 Google.
-+ *
-+ * This file is released under the GPLv2.
-+ *
-+ * Based on drivers/md/dm-verity-chromeos.c
-+ */
-+
-+#include <linux/device-mapper.h>
-+#include <linux/module.h>
-+#include <linux/mount.h>
-+
-+#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_rw = rw;
-+
-+	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(rw, 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;
-+	}
-+
-+	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<<SECTOR_SHIFT) - 64;
-+
-+		access_last_sector = 1;
-+		ret = invalidate_vbmeta_submit(bio, bdev, rw,
-+					       access_last_sector, page);
-+		if (ret) {
-+			DMERR("invalidate_vbmeta: error reading");
-+			goto failed_to_submit_read;
-+		}
-+		if (memcmp("AVBf", page_address(page) + offset, 4) != 0) {
-+			DMERR("invalidate_vbmeta on non-vbmeta partition");
-+			ret = -EINVAL;
-+			goto invalid_header;
-+		}
-+		/* Stamp it. */
-+		memcpy(page_address(page) + offset, "AVE0", 4);
-+		DMINFO("invalidate_vbmeta: found vbmeta footer partition");
-+	}
-+
-+	/* Now rewrite the changed page - the block dev was being
-+	 * changed on read. Let's reopen here.
-+	 */
-+	blkdev_put(bdev, dev_mode);
-+	dev_mode = FMODE_WRITE | FMODE_EXCL;
-+	bdev = blkdev_get_by_dev(vbmeta_devt, dev_mode,
-+				 invalidate_vbmeta);
-+	if (IS_ERR(bdev)) {
-+		DMERR("invalidate_vbmeta: could not open device for writing");
-+		dev_mode = 0;
-+		ret = -ENOENT;
-+		goto failed_to_write;
-+	}
-+
-+	/* We re-use the same bio to do the write after the read. Need to reset
-+	 * it to initialize bio->bi_remaining.
-+	 */
-+	bio_reset(bio);
-+
-+	rw |= REQ_WRITE;
-+	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 <zeuthen@google.com>");
-+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), 0);
-+module_param_string(invalidate_on_error, avb_invalidate_on_error,
-+		    sizeof(avb_invalidate_on_error), 0);
-diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
-index c7e97cf6e7fb..e34cf53bd068 100644
---- a/drivers/md/dm-verity-target.c
-+++ b/drivers/md/dm-verity-target.c
-@@ -233,8 +233,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 75effca400a3..a90d1d416107 100644
---- a/drivers/md/dm-verity.h
-+++ b/drivers/md/dm-verity.h
-@@ -136,4 +136,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 */
--- 
-2.14.1.581.gf28d330327-goog
-