edgetpu: sync critical fixes: GSA failure, UAF on mapping

Sync the following CLs from darwinn-2.0:

950f4f74 edgetpu: abrolhos fail firmware run on GSA fails
93cd0c2c edgetpu: fix UAF in edgetpu_device_group_map

Bug: 192641593
Bug: 194942314
Signed-off-by: David Chiang <davidchiang@google.com>
Change-Id: Id4382b28af3deb67ae5cddbc5af8e21f6a9f5cb0
diff --git a/drivers/edgetpu/abrolhos-firmware.c b/drivers/edgetpu/abrolhos-firmware.c
index 5a8cd2e..063d010 100644
--- a/drivers/edgetpu/abrolhos-firmware.c
+++ b/drivers/edgetpu/abrolhos-firmware.c
@@ -108,10 +108,8 @@
 	tpu_state = gsa_send_tpu_cmd(abpdev->gsa_dev, GSA_TPU_GET_STATE);
 
 	if (tpu_state < GSA_TPU_STATE_INACTIVE) {
-		etdev_warn(etdev, "GSA failed to retrieve current status: %d\n",
-			   tpu_state);
-		etdev_warn(etdev, "Assuming device is inactive\n");
-		tpu_state = GSA_TPU_STATE_INACTIVE;
+		etdev_err(etdev, "GSA failed to retrieve current status: %d\n", tpu_state);
+		return tpu_state;
 	}
 
 	etdev_dbg(etdev, "GSA Reports TPU state: %d\n", tpu_state);
diff --git a/drivers/edgetpu/edgetpu-device-group.c b/drivers/edgetpu/edgetpu-device-group.c
index 1b668f5..3b8ddf8 100644
--- a/drivers/edgetpu/edgetpu-device-group.c
+++ b/drivers/edgetpu/edgetpu-device-group.c
@@ -1433,6 +1433,7 @@
 	const u32 mmu_flags = map_to_mmu_flags(flags) | EDGETPU_MMU_HOST;
 	int i;
 	bool readonly;
+	tpu_addr_t tpu_addr;
 
 	if (!valid_dma_direction(flags & EDGETPU_MAP_DIR_MASK))
 		return -EINVAL;
@@ -1488,15 +1489,19 @@
 			goto error;
 	}
 
+	/*
+	 * @map can be freed (by another thread) once it's added to the mappings, record the address
+	 * before that.
+	 */
+	tpu_addr = map->device_address;
 	ret = edgetpu_mapping_add(&group->host_mappings, map);
 	if (ret) {
-		etdev_dbg(etdev, "duplicate mapping %u:0x%llx",
-			  group->workload_id, map->device_address);
+		etdev_dbg(etdev, "duplicate mapping %u:0x%llx", group->workload_id, tpu_addr);
 		goto error;
 	}
 
 	mutex_unlock(&group->lock);
-	arg->device_address = map->device_address;
+	arg->device_address = tpu_addr;
 	kvfree(pages);
 	return 0;