LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_memory.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 30 0.0 %
Date: 2022-04-01 14:58:12 Functions: 0 7 0.0 %
Branches: 0 24 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * \file drm_memory.c
       3                 :            :  * Memory management wrappers for DRM
       4                 :            :  *
       5                 :            :  * \author Rickard E. (Rik) Faith <faith@valinux.com>
       6                 :            :  * \author Gareth Hughes <gareth@valinux.com>
       7                 :            :  */
       8                 :            : 
       9                 :            : /*
      10                 :            :  * Created: Thu Feb  4 14:00:34 1999 by faith@valinux.com
      11                 :            :  *
      12                 :            :  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
      13                 :            :  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
      14                 :            :  * All Rights Reserved.
      15                 :            :  *
      16                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a
      17                 :            :  * copy of this software and associated documentation files (the "Software"),
      18                 :            :  * to deal in the Software without restriction, including without limitation
      19                 :            :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      20                 :            :  * and/or sell copies of the Software, and to permit persons to whom the
      21                 :            :  * Software is furnished to do so, subject to the following conditions:
      22                 :            :  *
      23                 :            :  * The above copyright notice and this permission notice (including the next
      24                 :            :  * paragraph) shall be included in all copies or substantial portions of the
      25                 :            :  * Software.
      26                 :            :  *
      27                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      28                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      29                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      30                 :            :  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
      31                 :            :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      32                 :            :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      33                 :            :  * OTHER DEALINGS IN THE SOFTWARE.
      34                 :            :  */
      35                 :            : 
      36                 :            : #include <linux/export.h>
      37                 :            : #include <linux/highmem.h>
      38                 :            : #include <linux/pci.h>
      39                 :            : #include <linux/vmalloc.h>
      40                 :            : #include <xen/xen.h>
      41                 :            : 
      42                 :            : #include <drm/drm_agpsupport.h>
      43                 :            : #include <drm/drm_cache.h>
      44                 :            : #include <drm/drm_device.h>
      45                 :            : 
      46                 :            : #include "drm_legacy.h"
      47                 :            : 
      48                 :            : #if IS_ENABLED(CONFIG_AGP)
      49                 :            : 
      50                 :            : #ifdef HAVE_PAGE_AGP
      51                 :            : # include <asm/agp.h>
      52                 :            : #else
      53                 :            : # ifdef __powerpc__
      54                 :            : #  define PAGE_AGP      pgprot_noncached_wc(PAGE_KERNEL)
      55                 :            : # else
      56                 :            : #  define PAGE_AGP      PAGE_KERNEL
      57                 :            : # endif
      58                 :            : #endif
      59                 :            : 
      60                 :            : static void *agp_remap(unsigned long offset, unsigned long size,
      61                 :            :                        struct drm_device *dev)
      62                 :            : {
      63                 :            :         unsigned long i, num_pages =
      64                 :            :             PAGE_ALIGN(size) / PAGE_SIZE;
      65                 :            :         struct drm_agp_mem *agpmem;
      66                 :            :         struct page **page_map;
      67                 :            :         struct page **phys_page_map;
      68                 :            :         void *addr;
      69                 :            : 
      70                 :            :         size = PAGE_ALIGN(size);
      71                 :            : 
      72                 :            : #ifdef __alpha__
      73                 :            :         offset -= dev->hose->mem_space->start;
      74                 :            : #endif
      75                 :            : 
      76                 :            :         list_for_each_entry(agpmem, &dev->agp->memory, head)
      77                 :            :                 if (agpmem->bound <= offset
      78                 :            :                     && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
      79                 :            :                     (offset + size))
      80                 :            :                         break;
      81                 :            :         if (&agpmem->head == &dev->agp->memory)
      82                 :            :                 return NULL;
      83                 :            : 
      84                 :            :         /*
      85                 :            :          * OK, we're mapping AGP space on a chipset/platform on which memory accesses by
      86                 :            :          * the CPU do not get remapped by the GART.  We fix this by using the kernel's
      87                 :            :          * page-table instead (that's probably faster anyhow...).
      88                 :            :          */
      89                 :            :         /* note: use vmalloc() because num_pages could be large... */
      90                 :            :         page_map = vmalloc(array_size(num_pages, sizeof(struct page *)));
      91                 :            :         if (!page_map)
      92                 :            :                 return NULL;
      93                 :            : 
      94                 :            :         phys_page_map = (agpmem->memory->pages + (offset - agpmem->bound) / PAGE_SIZE);
      95                 :            :         for (i = 0; i < num_pages; ++i)
      96                 :            :                 page_map[i] = phys_page_map[i];
      97                 :            :         addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
      98                 :            :         vfree(page_map);
      99                 :            : 
     100                 :            :         return addr;
     101                 :            : }
     102                 :            : 
     103                 :            : /** Wrapper around agp_free_memory() */
     104                 :          0 : void drm_free_agp(struct agp_memory *handle, int pages)
     105                 :            : {
     106                 :          0 :         agp_free_memory(handle);
     107                 :          0 : }
     108                 :            : 
     109                 :            : /** Wrapper around agp_bind_memory() */
     110                 :          0 : int drm_bind_agp(struct agp_memory *handle, unsigned int start)
     111                 :            : {
     112                 :          0 :         return agp_bind_memory(handle, start);
     113                 :            : }
     114                 :            : 
     115                 :            : /** Wrapper around agp_unbind_memory() */
     116                 :          0 : int drm_unbind_agp(struct agp_memory *handle)
     117                 :            : {
     118                 :          0 :         return agp_unbind_memory(handle);
     119                 :            : }
     120                 :            : 
     121                 :            : #else /*  CONFIG_AGP  */
     122                 :            : static inline void *agp_remap(unsigned long offset, unsigned long size,
     123                 :            :                               struct drm_device *dev)
     124                 :            : {
     125                 :            :         return NULL;
     126                 :            : }
     127                 :            : 
     128                 :            : #endif /* CONFIG_AGP */
     129                 :            : 
     130                 :          0 : void drm_legacy_ioremap(struct drm_local_map *map, struct drm_device *dev)
     131                 :            : {
     132   [ #  #  #  #  :          0 :         if (dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
                   #  # ]
     133                 :          0 :                 map->handle = agp_remap(map->offset, map->size, dev);
     134                 :            :         else
     135                 :          0 :                 map->handle = ioremap(map->offset, map->size);
     136                 :          0 : }
     137                 :            : EXPORT_SYMBOL(drm_legacy_ioremap);
     138                 :            : 
     139                 :          0 : void drm_legacy_ioremap_wc(struct drm_local_map *map, struct drm_device *dev)
     140                 :            : {
     141   [ #  #  #  #  :          0 :         if (dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
                   #  # ]
     142                 :          0 :                 map->handle = agp_remap(map->offset, map->size, dev);
     143                 :            :         else
     144                 :          0 :                 map->handle = ioremap_wc(map->offset, map->size);
     145                 :          0 : }
     146                 :            : EXPORT_SYMBOL(drm_legacy_ioremap_wc);
     147                 :            : 
     148                 :          0 : void drm_legacy_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
     149                 :            : {
     150   [ #  #  #  # ]:          0 :         if (!map->handle || !map->size)
     151                 :            :                 return;
     152                 :            : 
     153   [ #  #  #  #  :          0 :         if (dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
                   #  # ]
     154                 :          0 :                 vunmap(map->handle);
     155                 :            :         else
     156                 :          0 :                 iounmap(map->handle);
     157                 :            : }
     158                 :            : EXPORT_SYMBOL(drm_legacy_ioremapfree);
     159                 :            : 
     160                 :          0 : bool drm_need_swiotlb(int dma_bits)
     161                 :            : {
     162                 :          0 :         struct resource *tmp;
     163                 :          0 :         resource_size_t max_iomem = 0;
     164                 :            : 
     165                 :            :         /*
     166                 :            :          * Xen paravirtual hosts require swiotlb regardless of requested dma
     167                 :            :          * transfer size.
     168                 :            :          *
     169                 :            :          * NOTE: Really, what it requires is use of the dma_alloc_coherent
     170                 :            :          *       allocator used in ttm_dma_populate() instead of
     171                 :            :          *       ttm_populate_and_map_pages(), which bounce buffers so much in
     172                 :            :          *       Xen it leads to swiotlb buffer exhaustion.
     173                 :            :          */
     174                 :          0 :         if (xen_pv_domain())
     175                 :            :                 return true;
     176                 :            : 
     177                 :            :         /*
     178                 :            :          * Enforce dma_alloc_coherent when memory encryption is active as well
     179                 :            :          * for the same reasons as for Xen paravirtual hosts.
     180                 :            :          */
     181                 :          0 :         if (mem_encrypt_active())
     182                 :            :                 return true;
     183                 :            : 
     184         [ #  # ]:          0 :         for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
     185                 :          0 :                 max_iomem = max(max_iomem,  tmp->end);
     186                 :            :         }
     187                 :            : 
     188                 :          0 :         return max_iomem > ((u64)1 << dma_bits);
     189                 :            : }
     190                 :            : EXPORT_SYMBOL(drm_need_swiotlb);

Generated by: LCOV version 1.14