minigbm: cros_gralloc: fix initialization race condition

On Android M, since we don't hold a lock during cros_gralloc_driver::init(),
another thread would sometimes access data before the driver was initialized.
This would lead to dEQP crashes. We don't experience this issue on Android
N since the framework has it's own layer of locks in the Gralloc1On0Adapter.

This patch makes the module initialization during (*registerBuffer) and
gralloc_open re-entrant.

BUG=b:63511976
TEST=run cts --package com.drawelements.deqp.gles2 on veyron_tiger has no
     crashes

Change-Id: I2b72f2f8ed5e4a5afbacb291ed8cd928beb2a3b3
Reviewed-on: https://chromium-review.googlesource.com/597015
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc
index ec897be..e62c670 100644
--- a/cros_gralloc/gralloc0/gralloc0.cc
+++ b/cros_gralloc/gralloc0/gralloc0.cc
@@ -13,6 +13,8 @@
 	gralloc_module_t base;
 	std::unique_ptr<alloc_device_t> alloc;
 	std::unique_ptr<cros_gralloc_driver> driver;
+	bool initialized;
+	std::mutex initialization_mutex;
 };
 
 /* This enumeration must match the one in <gralloc_drm.h>.
@@ -128,11 +130,38 @@
 	return 0;
 }
 
+static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc)
+{
+	std::lock_guard<std::mutex> lock(mod->initialization_mutex);
+
+	if (mod->initialized)
+		return 0;
+
+	mod->driver = std::make_unique<cros_gralloc_driver>();
+	if (mod->driver->init()) {
+		cros_gralloc_error("Failed to initialize driver.");
+		return -ENODEV;
+	}
+
+	if (initialize_alloc) {
+		mod->alloc = std::make_unique<alloc_device_t>();
+		mod->alloc->alloc = gralloc0_alloc;
+		mod->alloc->free = gralloc0_free;
+		mod->alloc->common.tag = HARDWARE_DEVICE_TAG;
+		mod->alloc->common.version = 0;
+		mod->alloc->common.module = (hw_module_t *)mod;
+		mod->alloc->common.close = gralloc0_close;
+	}
+
+	mod->initialized = true;
+	return 0;
+}
+
 static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev)
 {
 	auto module = (struct gralloc0_module *)mod;
 
-	if (module->alloc) {
+	if (module->initialized) {
 		*dev = &module->alloc->common;
 		return 0;
 	}
@@ -142,20 +171,8 @@
 		return -EINVAL;
 	}
 
-	module->driver = std::make_unique<cros_gralloc_driver>();
-	if (module->driver->init()) {
-		cros_gralloc_error("Failed to initialize driver.");
-		return -ENOMEM;
-	}
-
-	module->alloc = std::make_unique<alloc_device_t>();
-
-	module->alloc->alloc = gralloc0_alloc;
-	module->alloc->free = gralloc0_free;
-	module->alloc->common.tag = HARDWARE_DEVICE_TAG;
-	module->alloc->common.version = 0;
-	module->alloc->common.module = (hw_module_t *)mod;
-	module->alloc->common.close = gralloc0_close;
+	if (gralloc0_init(module, true))
+		return -ENODEV;
 
 	*dev = &module->alloc->common;
 	return 0;
@@ -165,13 +182,9 @@
 {
 	auto mod = (struct gralloc0_module *)module;
 
-	if (!mod->driver) {
-		mod->driver = std::make_unique<cros_gralloc_driver>();
-		if (mod->driver->init()) {
-			cros_gralloc_error("Failed to initialize driver.");
-			return -ENOMEM;
-		}
-	}
+	if (!mod->initialized)
+		if (gralloc0_init(mod, false))
+			return -ENODEV;
 
 	return mod->driver->retain(handle);
 }
@@ -380,4 +393,5 @@
 
 	.alloc = nullptr,
 	.driver = nullptr,
+	.initialized = false,
 };