diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index ec68a6d..4d76588 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -874,7 +874,7 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all)
 	u32 num_pages_to_copy;
 	int i;
 
-	if (!guc->log.obj)
+	if (!guc->log.obj || !guc->log.buf_addr)
 		return;
 
 	num_pages_to_copy = guc->log.obj->base.size / PAGE_SIZE;
@@ -884,8 +884,7 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all)
 	if (!capture_all)
 		num_pages_to_copy -= (GUC_LOG_CRASH_PAGES + 1);
 
-	log_buffer_state = src_ptr =
-		kmap_atomic(i915_gem_object_get_page(guc->log.obj, 0));
+	log_buffer_state = src_ptr = guc->log.buf_addr;
 
 	/* Get the pointer to local buffer to store the logs */
 	dst_ptr = log_buffer_copy_state = guc_get_write_buffer(guc);
@@ -906,8 +905,6 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all)
 			log_buffer_copy_state++;
 		}
 
-		/* FIXME: invalidate/flush for log buffer needed */
-
 		/* Update the read pointer in the shared log buffer */
 		log_buffer_state->read_ptr =
 			log_buffer_state->sampled_write_ptr;
@@ -917,14 +914,11 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all)
 		log_buffer_state++;
 	}
 
-	kunmap_atomic(src_ptr);
-
 	/* Now copy the actual logs */
 	for (i=1; (i < num_pages_to_copy) && dst_ptr; i++) {
 		dst_ptr += PAGE_SIZE;
-		src_ptr = kmap_atomic(i915_gem_object_get_page(guc->log.obj, i));
+		src_ptr += PAGE_SIZE;
 		memcpy(dst_ptr, src_ptr, PAGE_SIZE);
-		kunmap_atomic(src_ptr);
 	}
 }
 
@@ -1016,7 +1010,7 @@ static int guc_create_log_relay_file(struct intel_guc *guc)
 
 	/* Keep the size of sub buffers same as shared log buffer */
 	subbuf_size = guc->log.obj->base.size;
-	n_subbufs = i915.guc_log_buffer_nr
+	n_subbufs = i915.guc_log_buffer_nr;
 
 	guc_log_relay_chan = relay_open("guc_log", log_dir,
 			subbuf_size, n_subbufs, &relay_callbacks, dev);
@@ -1051,6 +1045,7 @@ static int guc_log_late_setup(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_guc *guc = &dev_priv->guc;
+	void *vaddr;
 	int ret;
 
 	lockdep_assert_held(&dev->struct_mutex);
@@ -1061,9 +1056,26 @@ static int guc_log_late_setup(struct drm_device *dev)
 	if (WARN_ON(guc->log.relay_chan))
 		return -EINVAL;
 
+	/* If log_level was set as -1 at boot time, then vmalloc mapping would
+	 * not have been created for the log buffer, so create one now.
+	 */
+	if (!guc->log.buf_addr) {
+		vaddr = i915_gem_object_pin_map(guc->log.obj, true);
+		if (IS_ERR(vaddr)) {
+			ret = PTR_ERR(vaddr);
+			DRM_DEBUG_DRIVER("Couldn't map log buffer %d\n", ret);
+			goto err;
+		}
+		guc->log.buf_addr = vaddr;
+	}
+
+
 	ret = guc_create_log_relay_file(guc);
-	if (ret)
+	if (ret) {
+		guc->log.buf_addr = NULL;
+		i915_gem_object_unpin_map(guc->log.obj);
 		goto err;
+	}
 
 	return 0;
 err:
@@ -1098,6 +1110,25 @@ static void guc_create_log(struct intel_guc *guc)
 			return;
 		}
 
+		if (i915.guc_log_level >= 0) {
+			/* Create a WC (Uncached for read) mapping so that we
+			 * can directly get the data (up-to-date) from memory.
+			 * Also create the mapping now only to properly handle
+			 * the flush interrupts which can come before we create
+			 * a relay channel at the end of Driver load.
+			 */
+			void *vaddr = i915_gem_object_pin_map(obj, true);
+			if (IS_ERR(vaddr)) {
+				DRM_DEBUG_DRIVER("Couldn't map log buffer %ld\n",
+				PTR_ERR(vaddr));
+				gem_release_guc_obj(obj);
+				i915.guc_log_level = -1;
+				return;
+			}
+
+			guc->log.buf_addr = vaddr;
+		}
+
 		guc->log.obj = obj;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 3e90279..5e6accb 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -127,6 +127,7 @@ struct intel_guc_log {
 	struct drm_i915_gem_object *obj;
 	struct workqueue_struct *wq;
 	struct rchan *relay_chan;
+	void *buf_addr;
 };
 
 struct intel_guc {
