VirtualBox

Changeset 62550 in vbox


Ignore:
Timestamp:
Jul 25, 2016 6:32:58 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
109119
Message:

bugref:8087: Additions/x11: support non-root X server: do not map all of the guest VRAM when we only need the guest/host communication areas. This could fail on 32-bit guests (and possibly 64-bit too) with large VRAM sizes, making the guest unusable.

Location:
trunk/src/VBox/Additions/linux/drm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/drm/vbox_drv.h

    r62527 r62550  
    8888#define CURSOR_DATA_SIZE CURSOR_PIXEL_COUNT * 4 + CURSOR_PIXEL_COUNT / 8
    8989
     90#define VBOX_MAX_SCREENS  32
     91
    9092struct vbox_fbdev;
    9193
     
    9395    struct drm_device *dev;
    9496
    95     uint8_t __iomem *vram;
     97    uint8_t __iomem *mapped_vram;
    9698    HGSMIGUESTCOMMANDCONTEXT submit_info;
    9799    struct VBVABUFFERCONTEXT *vbva_info;
     
    102104    uint32_t full_vram_size;
    103105    /** Amount of available VRAM, not including space used for buffers. */
    104     uint32_t vram_size;
     106    uint32_t available_vram_size;
     107    /** Offset of host communication area in mapped VRAM. */
     108    uint32_t vram_host_offset;
    105109    /** Offset to the host flags in the VRAM. */
    106110    uint32_t host_flags_offset;
  • trunk/src/VBox/Additions/linux/drm/vbox_fb.c

    r62527 r62550  
    498498                vbox->fbdev->helper.fbdev->apertures->ranges[0].base +
    499499                gpu_addr;
    500         vbox->fbdev->helper.fbdev->fix.smem_len = vbox->vram_size - gpu_addr;
    501 }
     500        vbox->fbdev->helper.fbdev->fix.smem_len = vbox->available_vram_size - gpu_addr;
     501}
  • trunk/src/VBox/Additions/linux/drm/vbox_irq.c

    r62470 r62550  
    5757static uint32_t vbox_get_flags(struct vbox_private *vbox)
    5858{
    59     return (uint32_t)readl(vbox->vram + vbox->host_flags_offset);
     59    return (uint32_t)readl(vbox->mapped_vram + vbox->host_flags_offset);
    6060}
    6161
  • trunk/src/VBox/Additions/linux/drm/vbox_main.c

    r62527 r62550  
    7575        if (vbox->vbva_info[i].pVBVA == NULL) {
    7676            LogFunc(("vboxvideo: enabling VBVA.\n"));
    77             vbva = (struct VBVABUFFER *) (  ((uint8_t *)vbox->vram)
    78                                            + vbox->vram_size
     77            vbva = (struct VBVABUFFER *) (  ((uint8_t *)vbox->mapped_vram)
     78                                           + vbox->vram_host_offset
    7979                                           + i * VBVA_MIN_BUFFER_SIZE);
    8080            if (!VBoxVBVAEnable(&vbox->vbva_info[i], &vbox->submit_info, vbva, i))
     
    255255    }
    256256    /* Take a command buffer for each screen from the end of usable VRAM. */
    257     vbox->vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE;
     257    vbox->vram_host_offset = (VBOX_MAX_SCREENS - vbox->num_crtcs) * VBVA_MIN_BUFFER_SIZE;
     258    vbox->available_vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE;
    258259    for (i = 0; i < vbox->num_crtcs; ++i)
    259260        VBoxVBVASetupBufferContext(&vbox->vbva_info[i],
    260                                    vbox->vram_size + i * VBVA_MIN_BUFFER_SIZE,
     261                                   vbox->available_vram_size + i * VBVA_MIN_BUFFER_SIZE,
    261262                                   VBVA_MIN_BUFFER_SIZE);
    262     LogFunc(("vboxvideo: %d: vbox->vbva_info=%p, vbox->vram_size=%u\n",
    263              __LINE__, vbox->vbva_info, (unsigned)vbox->vram_size));
     263    LogFunc(("vboxvideo: %d: vbox->vbva_info=%p, vbox->available_vram_size=%u\n",
     264             __LINE__, vbox->vbva_info, (unsigned)vbox->available_vram_size));
    264265    return 0;
    265266}
     
    301302}
    302303
     304#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
     305# define pci_iomap_range(dev, bar, offset, maxlen) \
     306    ioremap(pci_resource_start(dev, bar) + offset, maxlen)
     307#endif
    303308
    304309/** Set up our heaps and data exchange buffers in VRAM before handing the rest
     
    306311static int vbox_hw_init(struct vbox_private *vbox)
    307312{
    308     uint32_t base_offset, guest_heap_offset, guest_heap_size, host_flags_offset;
     313    uint32_t base_offset, map_start, guest_heap_offset, guest_heap_size, host_flags_offset;
    309314    void *guest_heap;
    310315
     
    314319    VBoxHGSMIGetBaseMappingInfo(vbox->full_vram_size, &base_offset, NULL,
    315320                                &guest_heap_offset, &guest_heap_size, &host_flags_offset);
    316     guest_heap =   ((uint8_t *)vbox->vram) + base_offset + guest_heap_offset;
    317     vbox->host_flags_offset = base_offset + host_flags_offset;
     321    map_start = (uint32_t)max((int)base_offset
     322                              - VBOX_MAX_SCREENS * VBVA_MIN_BUFFER_SIZE, 0);
     323    vbox->mapped_vram = pci_iomap_range(vbox->dev->pdev, 0, map_start,
     324                                        vbox->full_vram_size - map_start);
     325    if (!vbox->mapped_vram)
     326        return -ENOMEM;
     327    guest_heap = ((uint8_t *)vbox->mapped_vram) + base_offset - map_start
     328                   + guest_heap_offset;
     329    vbox->host_flags_offset = base_offset - map_start + host_flags_offset;
    318330    if (RT_FAILURE(VBoxHGSMISetupGuestContext(&vbox->submit_info, guest_heap,
    319331                                              guest_heap_size,
     
    322334        return -ENOMEM;
    323335    /* Reduce available VRAM size to reflect the guest heap. */
    324     vbox->vram_size = base_offset;
     336    vbox->available_vram_size = base_offset;
    325337    /* Linux drm represents monitors as a 32-bit array. */
    326     vbox->num_crtcs = RT_MIN(VBoxHGSMIGetMonitorCount(&vbox->submit_info), 32);
     338    vbox->num_crtcs = min(VBoxHGSMIGetMonitorCount(&vbox->submit_info),
     339                          (uint32_t)VBOX_MAX_SCREENS);
    327340    if (!have_hgsmi_mode_hints(vbox))
    328341        return -ENOTSUPP;
     
    357370
    358371    mutex_init(&vbox->hw_mutex);
    359     /* I hope this won't interfere with the memory manager. */
    360     vbox->vram = pci_iomap(dev->pdev, 0, 0);
    361     if (!vbox->vram) {
    362         ret = -EIO;
    363         goto out_free;
    364     }
    365372
    366373    ret = vbox_hw_init(vbox);
     
    392399    if (ret)
    393400        goto out_free;
    394     LogFunc(("vboxvideo: %d: vbox=%p, vbox->vram=%p, vbox->full_vram_size=%u\n",
    395              __LINE__, vbox, vbox->vram, (unsigned)vbox->full_vram_size));
     401    LogFunc(("vboxvideo: %d: vbox=%p, vbox->mapped_vram=%p, vbox->full_vram_size=%u\n",
     402             __LINE__, vbox, vbox->mapped_vram, (unsigned)vbox->full_vram_size));
    396403    return 0;
    397404out_free:
     
    414421    vbox_hw_fini(vbox);
    415422    vbox_mm_fini(vbox);
    416     if (vbox->vram)
    417         pci_iounmap(dev->pdev, vbox->vram);
     423    if (vbox->mapped_vram)
     424        pci_iounmap(dev->pdev, vbox->mapped_vram);
    418425    kfree(vbox);
    419426    dev->dev_private = NULL;
  • trunk/src/VBox/Additions/linux/drm/vbox_mode.c

    r62527 r62550  
    133133        pInfo->u32ViewIndex = vbox_crtc->crtc_id;
    134134        pInfo->u32ViewOffset = vbox_crtc->fb_offset;
    135         pInfo->u32ViewSize =   vbox->vram_size - vbox_crtc->fb_offset
     135        pInfo->u32ViewSize =   vbox->available_vram_size - vbox_crtc->fb_offset
    136136                             + vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
    137         pInfo->u32MaxScreenSize = vbox->vram_size - vbox_crtc->fb_offset;
     137        pInfo->u32MaxScreenSize = vbox->available_vram_size - vbox_crtc->fb_offset;
    138138        VBoxHGSMIBufferSubmit(&vbox->submit_info, p);
    139139        VBoxHGSMIBufferFree(&vbox->submit_info, p);
  • trunk/src/VBox/Additions/linux/drm/vbox_ttm.c

    r62527 r62550  
    301301
    302302    ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
    303                  vbox->vram_size >> PAGE_SHIFT);
     303                 vbox->available_vram_size >> PAGE_SHIFT);
    304304    if (ret) {
    305305        DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette