*seqno = atomic_add_return(1, &dev_priv->marker_seq);
        } while (*seqno == 0);
 
-       if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE)) {
+       if (!vmw_has_fences(dev_priv)) {
 
                /*
                 * Don't request hardware to send a fence. The
 
                outl(status, vmw->io_start + SVGA_IRQSTATUS_PORT);
 }
 
+static inline bool vmw_has_fences(struct vmw_private *vmw)
+{
+       if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
+                                 SVGA_CAP_CMD_BUFFERS_2)) != 0)
+               return true;
+       return (vmw_fifo_caps(vmw) & SVGA_FIFO_CAP_FENCE) != 0;
+}
+
 #endif
 
        return container_of(fence->base.lock, struct vmw_fence_manager, lock);
 }
 
+static u32 vmw_fence_goal_read(struct vmw_private *vmw)
+{
+       if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
+               return vmw_read(vmw, SVGA_REG_FENCE_GOAL);
+       else
+               return vmw_fifo_mem_read(vmw, SVGA_FIFO_FENCE_GOAL);
+}
+
+static void vmw_fence_goal_write(struct vmw_private *vmw, u32 value)
+{
+       if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
+               vmw_write(vmw, SVGA_REG_FENCE_GOAL, value);
+       else
+               vmw_fifo_mem_write(vmw, SVGA_FIFO_FENCE_GOAL, value);
+}
+
 /*
  * Note on fencing subsystem usage of irqs:
  * Typically the vmw_fences_update function is called
        if (likely(!fman->seqno_valid))
                return false;
 
-       goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
+       goal_seqno = vmw_fence_goal_read(fman->dev_priv);
        if (likely(passed_seqno - goal_seqno >= VMW_FENCE_WRAP))
                return false;
 
        list_for_each_entry(fence, &fman->fence_list, head) {
                if (!list_empty(&fence->seq_passed_actions)) {
                        fman->seqno_valid = true;
-                       vmw_fifo_mem_write(fman->dev_priv,
-                                          SVGA_FIFO_FENCE_GOAL,
-                                          fence->base.seqno);
+                       vmw_fence_goal_write(fman->dev_priv,
+                                            fence->base.seqno);
                        break;
                }
        }
        if (dma_fence_is_signaled_locked(&fence->base))
                return false;
 
-       goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
+       goal_seqno = vmw_fence_goal_read(fman->dev_priv);
        if (likely(fman->seqno_valid &&
                   goal_seqno - fence->base.seqno < VMW_FENCE_WRAP))
                return false;
 
-       vmw_fifo_mem_write(fman->dev_priv, SVGA_FIFO_FENCE_GOAL,
-                          fence->base.seqno);
+       vmw_fence_goal_write(fman->dev_priv, fence->base.seqno);
        fman->seqno_valid = true;
 
        return true;
 
 
 #define VMW_FENCE_WRAP (1 << 24)
 
+static u32 vmw_irqflag_fence_goal(struct vmw_private *vmw)
+{
+       if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
+               return SVGA_IRQFLAG_REG_FENCE_GOAL;
+       else
+               return SVGA_IRQFLAG_FENCE_GOAL;
+}
+
 /**
  * vmw_thread_fn - Deferred (process context) irq handler
  *
                wake_up_all(&dev_priv->fifo_queue);
 
        if ((masked_status & (SVGA_IRQFLAG_ANY_FENCE |
-                             SVGA_IRQFLAG_FENCE_GOAL)) &&
+                             vmw_irqflag_fence_goal(dev_priv))) &&
            !test_and_set_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending))
                ret = IRQ_WAKE_THREAD;
 
        if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP))
                return true;
 
-       if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE) &&
-           vmw_fifo_idle(dev_priv, seqno))
+       if (!vmw_has_fences(dev_priv) && vmw_fifo_idle(dev_priv, seqno))
                return true;
 
        /**
                      unsigned long timeout)
 {
        struct vmw_fifo_state *fifo_state = dev_priv->fifo;
+       bool fifo_down = false;
 
        uint32_t count = 0;
        uint32_t signal_seq;
         */
 
        if (fifo_idle) {
-               down_read(&fifo_state->rwsem);
                if (dev_priv->cman) {
                        ret = vmw_cmdbuf_idle(dev_priv->cman, interruptible,
                                              10*HZ);
                        if (ret)
                                goto out_err;
+               } else if (fifo_state) {
+                       down_read(&fifo_state->rwsem);
+                       fifo_down = true;
                }
        }
 
                }
        }
        finish_wait(&dev_priv->fence_queue, &__wait);
-       if (ret == 0 && fifo_idle)
+       if (ret == 0 && fifo_idle && fifo_state)
                vmw_fence_write(dev_priv, signal_seq);
 
        wake_up_all(&dev_priv->fence_queue);
 out_err:
-       if (fifo_idle)
+       if (fifo_down)
                up_read(&fifo_state->rwsem);
 
        return ret;
 
 void vmw_goal_waiter_add(struct vmw_private *dev_priv)
 {
-       vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_FENCE_GOAL,
+       vmw_generic_waiter_add(dev_priv, vmw_irqflag_fence_goal(dev_priv),
                               &dev_priv->goal_queue_waiters);
 }
 
 void vmw_goal_waiter_remove(struct vmw_private *dev_priv)
 {
-       vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_FENCE_GOAL,
+       vmw_generic_waiter_remove(dev_priv, vmw_irqflag_fence_goal(dev_priv),
                                  &dev_priv->goal_queue_waiters);
 }
 
 
                ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
                                                      mode_cmd,
                                                      is_bo_proxy);
-
                /*
                 * vmw_create_bo_proxy() adds a reference that is no longer
                 * needed
        ret = vmw_user_lookup_handle(dev_priv, file_priv,
                                     mode_cmd->handles[0],
                                     &surface, &bo);
-       if (ret)
+       if (ret) {
+               DRM_ERROR("Invalid buffer object handle %u (0x%x).\n",
+                         mode_cmd->handles[0], mode_cmd->handles[0]);
                goto err_out;
+       }
 
 
        if (!bo &&
            !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
-               DRM_ERROR("Surface size cannot exceed %dx%d",
+               DRM_ERROR("Surface size cannot exceed %dx%d\n",
                        dev_priv->texture_max_width,
                        dev_priv->texture_max_height);
                goto err_out;