Index: /trunk/src/VBox/Additions/linux/drm/vbox_drv.h
===================================================================
--- /trunk/src/VBox/Additions/linux/drm/vbox_drv.h	(revision 64829)
+++ /trunk/src/VBox/Additions/linux/drm/vbox_drv.h	(revision 64830)
@@ -183,5 +183,4 @@
     struct drm_fb_helper helper;
     struct vbox_framebuffer afb;
-    void *sysram;
     int size;
     struct ttm_bo_kmap_obj mapping;
Index: /trunk/src/VBox/Additions/linux/drm/vbox_fb.c
===================================================================
--- /trunk/src/VBox/Additions/linux/drm/vbox_fb.c	(revision 64829)
+++ /trunk/src/VBox/Additions/linux/drm/vbox_fb.c	(revision 64830)
@@ -75,12 +75,7 @@
                  int x, int y, int width, int height)
 {
-    int i;
-
     struct drm_gem_object *obj;
     struct vbox_bo *bo;
-    int src_offset, dst_offset;
-    int bpp = (fbdev->afb.base.bits_per_pixel + 7)/8;
     int ret = -EBUSY;
-    bool unmap = false;
     bool store_for_later = false;
     int x2, y2;
@@ -131,18 +126,4 @@
     spin_unlock_irqrestore(&fbdev->dirty_lock, flags);
 
-    if (!bo->kmap.virtual) {
-        ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
-        if (ret) {
-            DRM_ERROR("failed to kmap fb updates\n");
-            vbox_bo_unreserve(bo);
-            return;
-        }
-        unmap = true;
-    }
-    for (i = y; i <= y2; i++) {
-        /* assume equal stride for now */
-        src_offset = dst_offset = i * fbdev->afb.base.pitches[0] + (x * bpp);
-        memcpy_toio(bo->kmap.virtual + src_offset, (char *)fbdev->sysram + src_offset, (x2 - x + 1) * bpp);
-    }
     /* Not sure why the original code subtracted 1 here, but I will keep it that
      * way to avoid unnecessary differences. */
@@ -152,6 +133,4 @@
     rect.y2 = y2 + 1;
     vbox_framebuffer_dirty_rectangles(&fbdev->afb.base, &rect, 1);
-    if (unmap)
-        ttm_bo_kunmap(&bo->kmap);
 
     vbox_bo_unreserve(bo);
@@ -271,5 +250,4 @@
     int size, ret;
     struct device *device = &dev->pdev->dev;
-    void *sysram;
     struct drm_gem_object *gobj = NULL;
     struct vbox_bo *bo = NULL;
@@ -294,22 +272,33 @@
         return ret;
     }
+
+    ret = vbox_framebuffer_init(dev, &fbdev->afb, &mode_cmd, gobj);
+    if (ret)
+        return ret;
+
     bo = gem_to_vbox_bo(gobj);
 
-    sysram = vmalloc(size);
-    if (!sysram)
+    ret = vbox_bo_reserve(bo, false);
+    if (ret)
+        return ret;
+
+    ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
+    if (ret) {
+        vbox_bo_unreserve(bo);
+        return ret;
+    }
+
+    ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+    vbox_bo_unreserve(bo);
+    if (ret) {
+        DRM_ERROR("failed to kmap fbcon\n");
+        return ret;
+    }
+
+    info = framebuffer_alloc(0, device);
+    if (!info)
         return -ENOMEM;
-
-    info = framebuffer_alloc(0, device);
-    if (!info) {
-        ret = -ENOMEM;
-        goto out;
-    }
     info->par = fbdev;
 
-    ret = vbox_framebuffer_init(dev, &fbdev->afb, &mode_cmd, gobj);
-    if (ret)
-        goto out;
-
-    fbdev->sysram = sysram;
     fbdev->size = size;
 
@@ -327,16 +316,12 @@
 
     ret = fb_alloc_cmap(&info->cmap, 256, 0);
-    if (ret) {
-        ret = -ENOMEM;
-        goto out;
-    }
+    if (ret)
+        return -ENOMEM;
 
     /* This seems to be done for safety checking that the framebuffer is not
      * registered twice by different drivers. */
     info->apertures = alloc_apertures(1);
-    if (!info->apertures) {
-        ret = -ENOMEM;
-        goto out;
-    }
+    if (!info->apertures)
+        return -ENOMEM;
     info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
     info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
@@ -345,5 +330,5 @@
     drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, sizes->fb_height);
 
-    info->screen_base = sysram;
+    info->screen_base = bo->kmap.virtual;
     info->screen_size = size;
 
@@ -359,6 +344,4 @@
 
     return 0;
-out:
-    return ret;
 }
 
@@ -397,4 +380,13 @@
 
     if (afb->obj) {
+        struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
+        if (!vbox_bo_reserve(bo, false)) {
+            if (bo->kmap.virtual)
+                ttm_bo_kunmap(&bo->kmap);
+            /* QXL does this, but is it really needed before freeing? */
+            if (bo->pin_count)
+                vbox_bo_unpin(bo);
+            vbox_bo_unreserve(bo);
+        }
         drm_gem_object_unreference_unlocked(afb->obj);
         afb->obj = NULL;
@@ -402,5 +394,4 @@
     drm_fb_helper_fini(&fbdev->helper);
 
-    vfree(fbdev->sysram);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
     drm_framebuffer_unregister_private(&afb->base);
Index: /trunk/src/VBox/Additions/linux/drm/vbox_mode.c
===================================================================
--- /trunk/src/VBox/Additions/linux/drm/vbox_mode.c	(revision 64829)
+++ /trunk/src/VBox/Additions/linux/drm/vbox_mode.c	(revision 64830)
@@ -171,8 +171,7 @@
 }
 
-/* We move buffers which are not in active use out of VRAM to save memory. */
 static int vbox_crtc_do_set_base(struct drm_crtc *crtc,
-                struct drm_framebuffer *fb,
-                int x, int y, int atomic)
+                struct drm_framebuffer *old_fb,
+                int x, int y)
 {
     struct vbox_private *vbox = crtc->dev->dev_private;
@@ -184,7 +183,7 @@
     u64 gpu_addr;
 
-    /* push the previous fb to system ram */
-    if (!atomic && fb) {
-        vbox_fb = to_vbox_framebuffer(fb);
+    /* Unpin the previous fb. */
+    if (old_fb) {
+        vbox_fb = to_vbox_framebuffer(old_fb);
         obj = vbox_fb->obj;
         bo = gem_to_vbox_bo(obj);
@@ -192,5 +191,5 @@
         if (ret)
             return ret;
-        vbox_bo_push_sysram(bo);
+        vbox_bo_unpin(bo);
         vbox_bo_unreserve(bo);
     }
@@ -210,12 +209,6 @@
     }
 
-    if (&vbox->fbdev->afb == vbox_fb) {
-        /* if pushing console in kmap it */
-        ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
-        if (ret)
-            DRM_ERROR("failed to kmap fbcon\n");
-        else
-            vbox_fbdev_set_base(vbox, gpu_addr);
-    }
+    if (&vbox->fbdev->afb == vbox_fb)
+        vbox_fbdev_set_base(vbox, gpu_addr);
     vbox_bo_unreserve(bo);
 
@@ -232,5 +225,5 @@
                  struct drm_framebuffer *old_fb)
 {
-    return vbox_crtc_do_set_base(crtc, old_fb, x, y, 0);
+    return vbox_crtc_do_set_base(crtc, old_fb, x, y);
 }
 
