diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 85102ad..439f149 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3025,6 +3025,18 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
 void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj);
 
 /**
+ * i915_object_mapped_address - address at which a GEM object is mapped
+ * @obj - the object (presumably already mapped into kernel address space)
+ *
+ * Returns the address at which an object has been mapped by a call to
+ * i915_gem_object_pin_map() above, or NULL if not currently mapped and pinned
+ */
+static inline void *i915_object_mapped_address(struct drm_i915_gem_object *obj)
+{
+       return obj->pages_pin_count == 0 ? NULL : obj->mapping;
+}
+
+/**
  * i915_gem_object_unpin_map - releases an earlier mapping
  * @obj - the object to unmap
  *
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index da86bdb..de96306 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -179,15 +179,11 @@ static void guc_init_doorbell(struct intel_guc *guc,
 			      struct i915_guc_client *client)
 {
 	struct guc_doorbell_info *doorbell;
-	void *base;
 
-	base = kmap_atomic(i915_gem_object_get_page(client->client_obj, 0));
-	doorbell = base + client->doorbell_offset;
+	doorbell = client->client_base + client->doorbell_offset;
 
-	doorbell->db_status = 1;
+	doorbell->db_status = GUC_DOORBELL_ENABLED;
 	doorbell->cookie = 0;
-
-	kunmap_atomic(base);
 }
 
 static int guc_ring_doorbell(struct i915_guc_client *gc)
@@ -256,16 +252,12 @@ static void guc_disable_doorbell(struct intel_guc *guc,
 {
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
 	struct guc_doorbell_info *doorbell;
-	void *base;
 	i915_reg_t drbreg = GEN8_DRBREGL(client->doorbell_id);
 	int value;
 
-	base = kmap_atomic(i915_gem_object_get_page(client->client_obj, 0));
-	doorbell = base + client->doorbell_offset;
-
-	doorbell->db_status = 0;
+	doorbell = client->client_base + client->doorbell_offset;
 
-	kunmap_atomic(base);
+	doorbell->db_status = GUC_DOORBELL_DISABLED;
 
 	I915_WRITE(drbreg, I915_READ(drbreg) & ~GEN8_DRB_VALID);
 
@@ -341,10 +333,8 @@ static void guc_init_proc_desc(struct intel_guc *guc,
 			       struct i915_guc_client *client)
 {
 	struct guc_process_desc *desc;
-	void *base;
 
-	base = kmap_atomic(i915_gem_object_get_page(client->client_obj, 0));
-	desc = base + client->proc_desc_offset;
+	desc = client->client_base + client->proc_desc_offset;
 
 	memset(desc, 0, sizeof(*desc));
 
@@ -361,8 +351,6 @@ static void guc_init_proc_desc(struct intel_guc *guc,
 	desc->wq_size_bytes = client->wq_size;
 	desc->wq_status = WQ_STATUS_ACTIVE;
 	desc->priority = client->priority;
-
-	kunmap_atomic(base);
 }
 
 /*
@@ -607,6 +595,7 @@ int i915_guc_submit(struct i915_guc_client *client,
  * This is a wrapper to create a gem obj. In order to use it inside GuC, the
  * object needs to be pinned lifetime. Also we must pin it to gtt space other
  * than [0, GUC_WOPCM_TOP) because this range is reserved inside GuC.
+ * The object is also pinned & mapped into kernel address space.
  *
  * Return:	A drm_i915_gem_object if successful, otherwise NULL.
  */
@@ -620,13 +609,14 @@ static struct drm_i915_gem_object *gem_allocate_guc_obj(struct drm_device *dev,
 	if (!obj)
 		return NULL;
 
-	if (i915_gem_object_get_pages(obj)) {
+	if (IS_ERR(i915_gem_object_pin_map(obj))) {
 		drm_gem_object_unreference(&obj->base);
 		return NULL;
 	}
 
 	if (i915_gem_obj_ggtt_pin(obj, PAGE_SIZE,
 			PIN_OFFSET_BIAS | GUC_WOPCM_TOP)) {
+		i915_gem_object_unpin_map(obj);
 		drm_gem_object_unreference(&obj->base);
 		return NULL;
 	}
@@ -649,6 +639,9 @@ static void gem_release_guc_obj(struct drm_i915_gem_object *obj)
 	if (i915_gem_obj_is_pinned(obj))
 		i915_gem_object_ggtt_unpin(obj);
 
+	if (i915_object_mapped_address(obj))
+		i915_gem_object_unpin_map(obj);
+
 	drm_gem_object_unreference(&obj->base);
 }
 
@@ -729,6 +722,8 @@ static struct i915_guc_client *guc_client_alloc(struct drm_device *dev,
 		goto err;
 
 	client->client_obj = obj;
+	client->client_base = i915_object_mapped_address(obj);
+	WARN_ON(!client->client_base);
 	client->wq_offset = GUC_DB_SIZE;
 	client->wq_size = GUC_WQ_SIZE;
 
@@ -841,7 +836,6 @@ static void guc_create_ads(struct intel_guc *guc)
 	struct guc_policies *policies;
 	struct guc_mmio_reg_state *reg_state;
 	struct intel_engine_cs *engine;
-	struct page *page;
 	u32 size;
 
 	/* The ads obj includes the struct itself and buffers passed to GuC */
@@ -857,9 +851,7 @@ static void guc_create_ads(struct intel_guc *guc)
 
 		guc->ads_obj = obj;
 	}
-
-	page = i915_gem_object_get_page(obj, 0);
-	ads = kmap(page);
+	ads = i915_object_mapped_address(obj);
 
 	/*
 	 * The GuC requires a "Golden Context" when it reinitialises
@@ -897,8 +889,6 @@ static void guc_create_ads(struct intel_guc *guc)
 
 	ads->reg_state_buffer = ads->reg_state_addr +
 			sizeof(struct guc_mmio_reg_state);
-
-	kunmap(page);
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 3bb85b1..f2c051e 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -29,8 +29,31 @@
 
 struct drm_i915_gem_request;
 
+/*
+ * This structure primarily describes the GEM object shared with the GuC.
+ * The GEM object is held for the entire lifetime of our interaction with
+ * the GuC, being allocated before the GuC is loaded with its firmware. 
+ * Because there's no way to update the address used by the GuC after
+ * initialisation, the shared object must stay pinned into the GGTT as
+ * long as the GuC is in use. We also keep it mapped into kernel address
+ * space, as it includes shared data that must be updated on every request
+ * submission.
+ *
+ * The single GEM object described here is actually made up of several
+ * separate areas, as far as the GuC is concerned. The first page includes
+ * the "process decriptor" which holds sequence data for the doorbell, and
+ * one cacheline which actually *is* the doorbell; a write to this will
+ * "ring" the doorbell (i.e. send an interrupt to the GuC). The subsequent
+ * pages of the client object constitute the work queue (a circular array
+ * of work items), again described in the process descriptor.
+ *
+ * Finally, we also keep a few statistics here, including the number of
+ * submissions to each engine, and a record of the last submission failure
+ * (if any).
+ */
 struct i915_guc_client {
 	struct drm_i915_gem_object *client_obj;
+	void *client_base;		/* Mapped address of above	*/
 	struct intel_context *owner;
 	struct intel_guc *guc;
 	uint32_t priority;
@@ -52,6 +75,7 @@ struct i915_guc_client {
 	uint32_t q_fail;
 	uint32_t b_fail;
 	int retcode;
+	int spare;			/* pad to 32 DWords		*/
 };
 
 enum intel_guc_fw_status {
