diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 2a192d4..9514645 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -866,32 +866,35 @@ static void* guc_get_write_buffer(struct intel_guc *guc)
 	return relay_reserve(guc->log.relay_chan, guc->log.obj->base.size);
 }
 
-static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all)
+static void guc_read_update_log_buffer(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_guc *guc = &dev_priv->guc;
 	struct guc_log_buffer_state *log_buffer_state;
 	struct guc_log_buffer_state *log_buffer_copy_state;
 	void *src_ptr, *dst_ptr;
-	u32 num_pages_to_copy;
-	int i;
+	bool new_overflow;
+	u32 i, buffer_size, read_offset, write_offset, bytes_to_copy;
 
 	if (!guc->log.obj || !guc->log.buf_addr)
 		return;
 
-	num_pages_to_copy = guc->log.obj->base.size / PAGE_SIZE;
-	/* Don't really need to copy crash buffer area in regular cases as there
-	 * won't be any unread data there.
-	 */
-	if (!capture_all)
-		num_pages_to_copy -= (GUC_LOG_CRASH_PAGES + 1);
-
 	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);
 
+	/* Actual logs are present from the 2nd page */
+	src_ptr += PAGE_SIZE;
+	dst_ptr += PAGE_SIZE;
+
 	for (i = 0; i < GUC_MAX_LOG_BUFFER; i++) {
+		buffer_size = log_buffer_state->size;
+		read_offset = log_buffer_state->read_ptr;
+		write_offset = log_buffer_state->sampled_write_ptr;
+		new_overflow = 0;
+
+		/* First copy the state structure */
 		if (log_buffer_copy_state) {
 			memcpy(log_buffer_copy_state, log_buffer_state,
 					sizeof(struct guc_log_buffer_state));
@@ -907,6 +910,10 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all)
 			log_buffer_copy_state++;
 		}
 
+		if (log_buffer_state->buffer_full_cnt !=
+					guc->log.overflow_count[i])
+			new_overflow = 1;
+
 		guc->log.overflow_count[i] = log_buffer_state->buffer_full_cnt;
 		guc->log.flush_count[i] += log_buffer_state->flush_to_file;
 
@@ -917,13 +924,36 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all)
 		/* Clear the 'flush to file' flag */
 		log_buffer_state->flush_to_file = 0;
 		log_buffer_state++;
-	}
 
-	/* Now copy the actual logs */
-	for (i=1; (i < num_pages_to_copy) && dst_ptr; i++) {
-		dst_ptr += PAGE_SIZE;
-		src_ptr += PAGE_SIZE;
-		memcpy(dst_ptr, src_ptr, PAGE_SIZE);
+		if (!log_buffer_copy_state)
+			continue;
+
+		/* Now copy the actual logs */
+		if ((read_offset > buffer_size) || (write_offset > buffer_size)) {
+			DRM_ERROR("invalid log buffer state\n");
+			/* copy the whole buffer, as offsets are unreliable */
+			memcpy(dst_ptr, src_ptr, buffer_size);
+		} else if (new_overflow) {
+			/* Need to copy the whole buffer in case of overflow */
+			memcpy(dst_ptr, src_ptr, buffer_size);
+		} else {
+			/* Just copy the new data */
+			if (read_offset <= write_offset) {
+				bytes_to_copy = write_offset - read_offset;
+				memcpy(dst_ptr + read_offset,
+					src_ptr + read_offset, bytes_to_copy);
+			} else {
+				bytes_to_copy = buffer_size - read_offset;
+				memcpy(dst_ptr + read_offset,
+					src_ptr + read_offset, bytes_to_copy);
+
+				bytes_to_copy = write_offset;
+				memcpy(dst_ptr, src_ptr, bytes_to_copy);
+			}
+		}
+
+		src_ptr += buffer_size;
+		dst_ptr += buffer_size;
 	}
 }
 
@@ -1370,11 +1400,11 @@ int intel_guc_resume(struct drm_device *dev)
 	return host2guc_action(guc, data, ARRAY_SIZE(data));
 }
 
-void i915_guc_capture_logs(struct drm_device *dev, bool capture_all)
+void i915_guc_capture_logs(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	guc_read_update_log_buffer(dev, capture_all);
+	guc_read_update_log_buffer(dev);
 
 	host2guc_logbuffer_flush_complete(&dev_priv->guc);
 }
@@ -1395,7 +1425,7 @@ void i915_guc_capture_logs_on_reset(struct drm_device *dev)
 	host2guc_force_logbuffer_flush(&dev_priv->guc);
 
 	/* GuC would have updated the log buffer by now, so capture it */
-	i915_guc_capture_logs(dev, true);
+	i915_guc_capture_logs(dev);
 
 end:
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e2cbe1e..99af3b5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1255,8 +1255,7 @@ static void gen9_guc2host_events_work(struct work_struct *work)
 	msg = I915_READ(SOFT_SCRATCH(15));
 	if (msg & (GUC2HOST_MSG_CRASH_DUMP_POSTED |
 		   GUC2HOST_MSG_FLUSH_LOG_BUFFER)) {
-		i915_guc_capture_logs(dev_priv->dev,
-			msg & GUC2HOST_MSG_CRASH_DUMP_POSTED);
+		i915_guc_capture_logs(dev_priv->dev);
 
 		/* Clear GuC to Host msg bits that are handled */
 		if (msg & GUC2HOST_MSG_FLUSH_LOG_BUFFER)
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index bd299d3..d9f50be 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -182,7 +182,7 @@ int i915_guc_wq_check_space(struct drm_i915_gem_request *rq);
 int i915_guc_submit(struct drm_i915_gem_request *rq);
 void i915_guc_submission_disable(struct drm_i915_private *dev_priv);
 void i915_guc_submission_fini(struct drm_i915_private *dev_priv);
-void i915_guc_capture_logs(struct drm_device *dev, bool capture_all);
+void i915_guc_capture_logs(struct drm_device *dev);
 void i915_guc_capture_logs_on_reset(struct drm_device *dev);
 void i915_guc_register(struct drm_device *dev);
 void i915_guc_unregister(struct drm_device *dev);
