Subject: Fix build errors with linux 5.14 Upstream-Status: backport svn-id: r89690 Signed-off-by: Bruce Ashfield Index: a/src/VBox/Additions/linux/drm/vbox_drv.h =================================================================== --- a/src/VBox/Additions/linux/drm/vbox_drv.h (revision 89690) +++ a/src/VBox/Additions/linux/drm/vbox_drv.h (revision 90498) @@ -227,6 +227,15 @@ sizeof(HGSMIHOSTFLAGS)) #define HOST_FLAGS_OFFSET GUEST_HEAP_USABLE_SIZE +/** Field @pdev of struct drm_device was removed in 5.14. This macro + * transparently handles this change. Input argument is a pointer + * to struct drm_device. */ +#if RTLNX_VER_MIN(5,14,0) +# define VBOX_DRM_TO_PCI_DEV(_dev) to_pci_dev(_dev->dev) +#else +# define VBOX_DRM_TO_PCI_DEV(_dev) _dev->pdev +#endif + /** How frequently we refresh if the guest is not providing dirty rectangles. */ #define VBOX_REFRESH_PERIOD (HZ / 2) Index: a/src/VBox/Additions/linux/drm/vbox_main.c =================================================================== --- a/src/VBox/Additions/linux/drm/vbox_main.c (revision 89690) +++ a/src/VBox/Additions/linux/drm/vbox_main.c (revision 90498) @@ -290,7 +290,7 @@ /* Take a command buffer for each screen from the end of usable VRAM. */ vbox->available_vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE; - vbox->vbva_buffers = pci_iomap_range(vbox->dev->pdev, 0, + vbox->vbva_buffers = pci_iomap_range(VBOX_DRM_TO_PCI_DEV(vbox->dev), 0, vbox->available_vram_size, vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE); @@ -311,7 +311,7 @@ return 0; err_pci_iounmap: - pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers); + pci_iounmap(VBOX_DRM_TO_PCI_DEV(vbox->dev), vbox->vbva_buffers); return ret; } @@ -318,7 +318,7 @@ static void vbox_accel_fini(struct vbox_private *vbox) { vbox_disable_accel(vbox); - pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers); + pci_iounmap(VBOX_DRM_TO_PCI_DEV(vbox->dev), vbox->vbva_buffers); } /** Do we support the 4.3 plus mode hint reporting interface? */ @@ -393,7 +393,7 @@ /* Map guest-heap at end of vram */ vbox->guest_heap = - pci_iomap_range(vbox->dev->pdev, 0, GUEST_HEAP_OFFSET(vbox), + pci_iomap_range(VBOX_DRM_TO_PCI_DEV(vbox->dev), 0, GUEST_HEAP_OFFSET(vbox), GUEST_HEAP_SIZE); if (!vbox->guest_heap) return -ENOMEM; @@ -442,7 +442,7 @@ err_destroy_guest_pool: gen_pool_destroy(vbox->guest_pool); err_unmap_guest_heap: - pci_iounmap(vbox->dev->pdev, vbox->guest_heap); + pci_iounmap(VBOX_DRM_TO_PCI_DEV(vbox->dev), vbox->guest_heap); return ret; } @@ -452,7 +452,7 @@ cancel_delayed_work(&vbox->refresh_work); vbox_accel_fini(vbox); gen_pool_destroy(vbox->guest_pool); - pci_iounmap(vbox->dev->pdev, vbox->guest_heap); + pci_iounmap(VBOX_DRM_TO_PCI_DEV(vbox->dev), vbox->guest_heap); } #if RTLNX_VER_MIN(4,19,0) || RTLNX_RHEL_MIN(8,3) @@ -567,12 +567,16 @@ size = roundup(size, PAGE_SIZE); if (size == 0) + { + DRM_ERROR("bad size\n"); return -EINVAL; + } ret = vbox_bo_create(dev, size, 0, 0, &vboxbo); if (ret) { if (ret != -ERESTARTSYS) DRM_ERROR("failed to allocate GEM object\n"); + DRM_ERROR("failed to allocate GEM (%d)\n", ret); return ret; } @@ -628,6 +632,21 @@ { struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj); +#if RTLNX_VER_MIN(5,14,0) + /* Starting from kernel 5.14, there is a warning appears in dmesg + * on attempt to desroy pinned buffer object. Make sure it is unpinned. */ + while (vbox_bo->bo.pin_count) + { + int ret; + ret = vbox_bo_unpin(vbox_bo); + if (ret) + { + DRM_ERROR("unable to unpin buffer object\n"); + break; + } + } +#endif + ttm_bo_put(&vbox_bo->bo); } @@ -648,7 +667,7 @@ u32 handle, u64 *offset) { struct drm_gem_object *obj; - int ret; + int ret = 0; struct vbox_bo *bo; mutex_lock(&dev->struct_mutex); @@ -665,8 +684,15 @@ bo = gem_to_vbox_bo(obj); *offset = vbox_bo_mmap_offset(bo); +#if RTLNX_VER_MIN(5,14,0) + ret = drm_vma_node_allow(&bo->bo.base.vma_node, file); + if (ret) + { + DRM_ERROR("unable to grant previladges to user"); + } +#endif + drm_gem_object_put(obj); - ret = 0; out_unlock: mutex_unlock(&dev->struct_mutex); Index: a/src/VBox/Additions/linux/drm/vbox_mode.c =================================================================== --- a/src/VBox/Additions/linux/drm/vbox_mode.c (revision 89690) +++ a/src/VBox/Additions/linux/drm/vbox_mode.c (revision 90498) @@ -245,6 +245,10 @@ vbox_bo_unpin(bo); vbox_bo_unreserve(bo); } + else + { + DRM_ERROR("unable to lock buffer object: error %d\n", ret); + } } if (&vbox->fbdev->afb == vbox_fb) @@ -856,7 +860,9 @@ vbox->cursor_data_size = data_size; dst = vbox->cursor_data; -#if RTLNX_VER_MIN(5,12,0) +#if RTLNX_VER_MIN(5,14,0) + ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.resource->num_pages, &uobj_map); +#elif RTLNX_VER_MIN(5,12,0) ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.mem.num_pages, &uobj_map); #else ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map); Index: a/src/VBox/Additions/linux/drm/vbox_ttm.c =================================================================== --- a/src/VBox/Additions/linux/drm/vbox_ttm.c (revision 89690) +++ a/src/VBox/Additions/linux/drm/vbox_ttm.c (revision 90498) @@ -41,6 +41,10 @@ # include #endif +#if RTLNX_VER_MIN(5,14,0) +# include +#endif + #if RTLNX_VER_MAX(3,18,0) && !RTLNX_RHEL_MAJ_PREREQ(7,2) #define PLACEMENT_FLAGS(placement) (placement) #else @@ -174,11 +178,13 @@ *pl = vboxbo->placement; } +#if RTLNX_VER_MAX(5,14,0) static int vbox_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp) { return 0; } +#endif #if RTLNX_VER_MAX(5,10,0) static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev, @@ -234,10 +240,10 @@ mem->bus.caching = ttm_write_combined; # endif # if RTLNX_VER_MIN(5,10,0) - mem->bus.offset = (mem->start << PAGE_SHIFT) + pci_resource_start(vbox->dev->pdev, 0); + mem->bus.offset = (mem->start << PAGE_SHIFT) + pci_resource_start(VBOX_DRM_TO_PCI_DEV(vbox->dev), 0); # else mem->bus.offset = mem->start << PAGE_SHIFT; - mem->start = pci_resource_start(vbox->dev->pdev, 0); + mem->start = pci_resource_start(VBOX_DRM_TO_PCI_DEV(vbox->dev), 0); # endif mem->bus.is_iomem = true; break; @@ -373,7 +379,9 @@ .eviction_valuable = ttm_bo_eviction_valuable, #endif .evict_flags = vbox_bo_evict_flags, +#if RTLNX_VER_MAX(5,14,0) .verify_access = vbox_bo_verify_access, +#endif .io_mem_reserve = &vbox_ttm_io_mem_reserve, .io_mem_free = &vbox_ttm_io_mem_free, #if RTLNX_VER_MIN(4,12,0) || RTLNX_RHEL_MAJ_PREREQ(7,5) @@ -451,12 +459,12 @@ } #ifdef DRM_MTRR_WC - vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0), + vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(VBOX_DRM_TO_PCI_DEV(dev), 0), + pci_resource_len(VBOX_DRM_TO_PCI_DEV(dev), 0), DRM_MTRR_WC); #else - vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0)); + vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(VBOX_DRM_TO_PCI_DEV(dev), 0), + pci_resource_len(VBOX_DRM_TO_PCI_DEV(dev), 0)); #endif return 0; @@ -477,8 +485,8 @@ { #ifdef DRM_MTRR_WC drm_mtrr_del(vbox->fb_mtrr, - pci_resource_start(vbox->dev->pdev, 0), - pci_resource_len(vbox->dev->pdev, 0), DRM_MTRR_WC); + pci_resource_start(VBOX_DRM_TO_PCI_DEV(vbox->dev), 0), + pci_resource_len(VBOX_DRM_TO_PCI_DEV(vbox->dev), 0), DRM_MTRR_WC); #else arch_phys_wc_del(vbox->fb_mtrr); #endif @@ -560,6 +568,9 @@ static const struct drm_gem_object_funcs vbox_drm_gem_object_funcs = { .free = vbox_gem_free_object, .print_info = drm_gem_ttm_print_info, +# if RTLNX_VER_MIN(5,14,0) + .mmap = drm_gem_ttm_mmap, +# endif }; #endif @@ -598,6 +609,17 @@ sizeof(struct vbox_bo)); #endif +#if RTLNX_VER_MIN(5,14,0) + /* Initialization of the following was removed from DRM stack + * in 5.14, so we need to do it manually. */ + vboxbo->bo.base.funcs = &vbox_drm_gem_object_funcs; + kref_init(&vboxbo->bo.base.refcount); + vboxbo->bo.base.size = size; + vboxbo->bo.base.dev = dev; + dma_resv_init(&vboxbo->bo.base._resv); + drm_vma_node_reset(&vboxbo->bo.base.vma_node); +#endif + ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size, ttm_bo_type_device, &vboxbo->placement, #if RTLNX_VER_MAX(4,17,0) && !RTLNX_RHEL_MAJ_PREREQ(7,6) && !RTLNX_SUSE_MAJ_PREREQ(15,1) && !RTLNX_SUSE_MAJ_PREREQ(12,5) @@ -613,7 +635,11 @@ NULL, vbox_bo_ttm_destroy); #endif if (ret) - goto err_free_vboxbo; + { + /* In case of failure, ttm_bo_init() supposed to call + * vbox_bo_ttm_destroy() which in turn will free @vboxbo. */ + goto err_exit; + } *pvboxbo = vboxbo; @@ -621,12 +647,15 @@ err_free_vboxbo: kfree(vboxbo); +err_exit: return ret; } static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo) { -#if RTLNX_VER_MIN(5,9,0) || RTLNX_RHEL_MIN(8,4) || RTLNX_SUSE_MAJ_PREREQ(15,3) +#if RTLNX_VER_MIN(5,14,0) + return bo->bo.resource->start << PAGE_SHIFT; +#elif RTLNX_VER_MIN(5,9,0) || RTLNX_RHEL_MIN(8,4) || RTLNX_SUSE_MAJ_PREREQ(15,3) return bo->bo.mem.start << PAGE_SHIFT; #else return bo->bo.offset; @@ -685,7 +714,7 @@ struct ttm_operation_ctx ctx = { false, false }; # endif #endif - int ret; + int ret = 0; #if RTLNX_VER_MAX(5,11,0) int i; #endif @@ -765,6 +794,7 @@ { struct drm_file *file_priv; struct vbox_private *vbox; + int ret = -EINVAL; if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) return -EINVAL; @@ -772,5 +802,12 @@ file_priv = filp->private_data; vbox = file_priv->minor->dev->dev_private; - return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev); +#if RTLNX_VER_MIN(5,14,0) + if (drm_dev_is_unplugged(file_priv->minor->dev)) + return -ENODEV; + ret = drm_gem_mmap(filp, vma); +#else + ret = ttm_bo_mmap(filp, vma, &vbox->ttm.bdev); +#endif + return ret; } Index: a/src/VBox/Additions/linux/drm/vbox_fb.c =================================================================== --- a/src/VBox/Additions/linux/drm/vbox_fb.c (revision 89690) +++ a/src/VBox/Additions/linux/drm/vbox_fb.c (revision 90498) @@ -301,7 +301,9 @@ return ret; } -#if RTLNX_VER_MIN(5,12,0) +#if RTLNX_VER_MIN(5,14,0) + ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.resource->num_pages, &bo->kmap); +#elif RTLNX_VER_MIN(5,12,0) ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.mem.num_pages, &bo->kmap); #else ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); @@ -337,8 +339,8 @@ * This seems to be done for safety checking that the framebuffer * is not registered twice by different drivers. */ - info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0); - info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); + info->apertures->ranges[0].base = pci_resource_start(VBOX_DRM_TO_PCI_DEV(dev), 0); + info->apertures->ranges[0].size = pci_resource_len(VBOX_DRM_TO_PCI_DEV(dev), 0); #if RTLNX_VER_MIN(5,2,0) || RTLNX_RHEL_MAJ_PREREQ(8,2) /* Index: a/src/VBox/Additions/linux/drm/vbox_drv.c =================================================================== --- a/src/VBox/Additions/linux/drm/vbox_drv.c (revision 89690) +++ a/src/VBox/Additions/linux/drm/vbox_drv.c (revision 90498) @@ -43,6 +43,10 @@ # include #endif +#if RTLNX_VER_MIN(5,14,0) +# include +#endif + #include "version-generated.h" #include "revision-generated.h" @@ -65,12 +69,23 @@ struct drm_device *dev = NULL; int ret = 0; +# if RTLNX_VER_MIN(5,14,0) + ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "vboxvideofb"); + if (ret) + { + printk("unable to remove conflicting framebuffer devices\n"); + return ret; + } +# endif /* 5.14 */ + dev = drm_dev_alloc(&driver, &pdev->dev); if (IS_ERR(dev)) { ret = PTR_ERR(dev); goto err_drv_alloc; } +#if RTLNX_VER_MAX(5,14,0) dev->pdev = pdev; +#endif pci_set_drvdata(pdev, dev); ret = vbox_driver_load(dev); @@ -125,7 +140,7 @@ drm_kms_helper_poll_disable(dev); - pci_save_state(dev->pdev); + pci_save_state(VBOX_DRM_TO_PCI_DEV(dev)); drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, true); @@ -147,7 +162,7 @@ { int ret; - if (pci_enable_device(dev->pdev)) + if (pci_enable_device(VBOX_DRM_TO_PCI_DEV(dev))) return -EIO; ret = vbox_drm_thaw(dev); Index: a/src/VBox/Additions/linux/drm/vbox_irq.c =================================================================== --- a/src/VBox/Additions/linux/drm/vbox_irq.c (revision 89690) +++ a/src/VBox/Additions/linux/drm/vbox_irq.c (revision 90498) @@ -206,7 +206,7 @@ INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker); vbox_update_mode_hints(vbox); #if RTLNX_VER_MIN(3,16,0) || RTLNX_RHEL_MAJ_PREREQ(7,1) - return drm_irq_install(vbox->dev, vbox->dev->pdev->irq); + return drm_irq_install(vbox->dev, VBOX_DRM_TO_PCI_DEV(vbox->dev)->irq); #else return drm_irq_install(vbox->dev); #endif