bound = vma ? vma->bound : 0;
        if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
+               /* In true PPGTT, bind has possibly changed PDEs, which
+                * means we must do a context switch before the GPU can
+                * accurately read some of the VMAs.
+                */
                vma = i915_gem_object_bind_to_vm(obj, vm, ggtt_view, alignment,
                                                 flags);
                if (IS_ERR(vma))
 
                                      struct intel_context *from,
                                      struct intel_context *to)
 {
-       if (from == to && !to->remap_slice)
-               return true;
+       struct drm_i915_private *dev_priv = ring->dev->dev_private;
+
+       if (to->remap_slice)
+               return false;
+
+       if (to->ppgtt) {
+               if (from == to && !test_bit(ring->id,
+                               &to->ppgtt->pd_dirty_rings))
+                       return true;
+       } else if (dev_priv->mm.aliasing_ppgtt) {
+               if (from == to && !test_bit(ring->id,
+                               &dev_priv->mm.aliasing_ppgtt->pd_dirty_rings))
+                       return true;
+       }
 
        return false;
 }
        if (ring != &dev_priv->ring[RCS])
                return false;
 
-       if (!to->legacy_hw_ctx.initialized)
-               return true;
-
-       if (i915_gem_context_is_default(to))
+       if (to->ppgtt->pd_dirty_rings)
                return true;
 
        return false;
                ret = to->ppgtt->switch_mm(to->ppgtt, ring);
                if (ret)
                        goto unpin_out;
+
+               /* Doing a PD load always reloads the page dirs */
+               clear_bit(ring->id, &to->ppgtt->pd_dirty_rings);
        }
 
        if (ring != &dev_priv->ring[RCS]) {
 
        if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
                hw_flags |= MI_RESTORE_INHIBIT;
+       else if (to->ppgtt && test_and_clear_bit(ring->id, &to->ppgtt->pd_dirty_rings))
+               hw_flags |= MI_FORCE_RESTORE;
 
        ret = mi_set_context(ring, to, hw_flags);
        if (ret)
 
        if (ret)
                goto error;
 
+       if (ctx->ppgtt)
+               WARN(ctx->ppgtt->pd_dirty_rings & (1<<ring->id),
+                       "%s didn't clear reload\n", ring->name);
+       else if (dev_priv->mm.aliasing_ppgtt)
+               WARN(dev_priv->mm.aliasing_ppgtt->pd_dirty_rings &
+                       (1<<ring->id), "%s didn't clear reload\n", ring->name);
+
        instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
        instp_mask = I915_EXEC_CONSTANTS_MASK;
        switch (instp_mode) {
 
                               4096, PCI_DMA_BIDIRECTIONAL);
 }
 
+/* PDE TLBs are a pain invalidate pre GEN8. It requires a context reload. If we
+ * are switching between contexts with the same LRCA, we also must do a force
+ * restore.
+ */
+static inline void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt)
+{
+       /* If current vm != vm, */
+       ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.dev)->ring_mask;
+}
+
 static int gen6_alloc_va_range(struct i915_address_space *vm,
                               uint64_t start, uint64_t length)
 {
                                GEN6_PTES);
        }
 
+       mark_tlbs_dirty(ppgtt);
        return 0;
 }
 
 
        struct i915_address_space base;
        struct kref ref;
        struct drm_mm_node node;
+       unsigned long pd_dirty_rings;
        unsigned num_pd_entries;
        unsigned num_pd_pages; /* gen8+ */
        union {