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)
        struct guc_process_desc *desc;
        union guc_doorbell_qw db_cmp, db_exc, db_ret;
        union guc_doorbell_qw *db;
-       void *base;
        int attempt = 2, ret = -EAGAIN;
 
-       base = kmap_atomic(i915_gem_object_get_page(gc->client_obj, 0));
-       desc = base + gc->proc_desc_offset;
+       desc = gc->client_base + gc->proc_desc_offset;
 
        /* Update the tail so it is visible to GuC */
        desc->tail = gc->wq_tail;
                db_exc.cookie = 1;
 
        /* pointer of current doorbell cacheline */
-       db = base + gc->doorbell_offset;
+       db = gc->client_base + gc->doorbell_offset;
 
        while (attempt--) {
                /* lets ring the doorbell */
        /* Finally, update the cached copy of the GuC's WQ head */
        gc->wq_head = desc->head;
 
-       kunmap_atomic(base);
        return ret;
 }
 
 {
        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 = client->client_base + client->doorbell_offset;
 
-       doorbell->db_status = 0;
-
-       kunmap_atomic(base);
+       doorbell->db_status = GUC_DOORBELL_DISABLED;
 
        I915_WRITE(drbreg, I915_READ(drbreg) & ~GEN8_DRB_VALID);
 
                               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));
 
        desc->wq_size_bytes = client->wq_size;
        desc->wq_status = WQ_STATUS_ACTIVE;
        desc->priority = client->priority;
-
-       kunmap_atomic(base);
 }
 
 /*
 int i915_guc_wq_check_space(struct i915_guc_client *gc)
 {
        struct guc_process_desc *desc;
-       void *base;
        u32 size = sizeof(struct guc_wq_item);
        int ret = -ETIMEDOUT, timeout_counter = 200;
 
        if (CIRC_SPACE(gc->wq_tail, gc->wq_head, gc->wq_size) >= size)
                return 0;
 
-       base = kmap_atomic(i915_gem_object_get_page(gc->client_obj, 0));
-       desc = base + gc->proc_desc_offset;
+       desc = gc->client_base + gc->proc_desc_offset;
 
        while (timeout_counter-- > 0) {
                gc->wq_head = desc->head;
                        usleep_range(1000, 2000);
        };
 
-       kunmap_atomic(base);
-
        return ret;
 }
 
        if (!client)
                return;
 
-       if (client->doorbell_id != GUC_INVALID_DOORBELL_ID) {
-               /*
-                * First disable the doorbell, then tell the GuC we've
-                * finished with it, finally deallocate it in our bitmap
-                */
-               guc_disable_doorbell(guc, client);
-               host2guc_release_doorbell(guc, client);
-               release_doorbell(guc, client->doorbell_id);
-       }
-
        /*
         * XXX: wait for any outstanding submissions before freeing memory.
         * Be sure to drop any locks
         */
 
+       if (client->client_base) {
+               /*
+                * If we got as far as setting up a doorbell, make sure
+                * we shut it down before unmapping & deallocating the
+                * memory. So first disable the doorbell, then tell the
+                * GuC that we've finished with it, finally deallocate
+                * it in our bitmap
+                */
+               if (client->doorbell_id != GUC_INVALID_DOORBELL_ID) {
+                       guc_disable_doorbell(guc, client);
+                       host2guc_release_doorbell(guc, client);
+                       release_doorbell(guc, client->doorbell_id);
+               }
+
+               kunmap(kmap_to_page(client->client_base));
+       }
+
        gem_release_guc_obj(client->client_obj);
 
        if (client->ctx_index != GUC_INVALID_CTX_ID) {
  * @ctx:       the context that owns the client (we use the default render
  *             context)
  *
- * Return:     An i915_guc_client object if success.
+ * Return:     An i915_guc_client object if success, else NULL.
  */
 static struct i915_guc_client *guc_client_alloc(struct drm_device *dev,
                                                uint32_t priority,
        if (!obj)
                goto err;
 
+       /* We'll keep just the first (doorbell/proc) page permanently kmap'd. */
        client->client_obj = obj;
+       client->client_base = kmap(i915_gem_object_get_page(obj, 0));
        client->wq_offset = GUC_DB_SIZE;
        client->wq_size = GUC_WQ_SIZE;