diff --git a/drivers/video/tegra/nvmap/nvmap_alloc.c b/drivers/video/tegra/nvmap/nvmap_alloc.c index 4acd3b2a..7f3a64a4 100644 --- a/drivers/video/tegra/nvmap/nvmap_alloc.c +++ b/drivers/video/tegra/nvmap/nvmap_alloc.c @@ -13,9 +13,10 @@ #include #include #include - #include -#include "nvmap_priv.h" +#include +#include +#include "nvmap_stats.h" #include "nvmap_dev.h" #include "nvmap_alloc.h" #include "nvmap_alloc_int.h" @@ -580,4 +581,4 @@ void nvmap_alloc_free(struct page **pages, unsigned int nr_page, bool from_va, phys_addr_t nvmap_alloc_get_co_base(struct nvmap_handle *h) { return h->carveout->base; -} +} \ No newline at end of file diff --git a/drivers/video/tegra/nvmap/nvmap_alloc.h b/drivers/video/tegra/nvmap/nvmap_alloc.h index 27fa4d18..cec9f5ed 100644 --- a/drivers/video/tegra/nvmap/nvmap_alloc.h +++ b/drivers/video/tegra/nvmap/nvmap_alloc.h @@ -6,9 +6,27 @@ #define DMA_MEMORY_NOMAP 0x02 +/* bit 31-29: IVM peer + * bit 28-16: offset (aligned to 32K) + * bit 15-00: len (aligned to page_size) + */ +#define NVMAP_IVM_LENGTH_SHIFT (0) +#define NVMAP_IVM_LENGTH_WIDTH (16) +#define NVMAP_IVM_LENGTH_MASK ((1 << NVMAP_IVM_LENGTH_WIDTH) - 1) +#define NVMAP_IVM_OFFSET_SHIFT (NVMAP_IVM_LENGTH_SHIFT + NVMAP_IVM_LENGTH_WIDTH) +#define NVMAP_IVM_OFFSET_WIDTH (13) +#define NVMAP_IVM_OFFSET_MASK ((1 << NVMAP_IVM_OFFSET_WIDTH) - 1) +#define NVMAP_IVM_IVMID_SHIFT (NVMAP_IVM_OFFSET_SHIFT + NVMAP_IVM_OFFSET_WIDTH) +#define NVMAP_IVM_IVMID_WIDTH (3) +#define NVMAP_IVM_IVMID_MASK ((1 << NVMAP_IVM_IVMID_WIDTH) - 1) +#define NVMAP_IVM_ALIGNMENT (SZ_32K) +#define NVMAP_IVM_INVALID_PEER (-1) + struct nvmap_heap; struct debugfs_info; struct nvmap_carveout_node; +struct nvmap_client; +struct nvmap_handle; void *nvmap_altalloc(size_t len); @@ -117,4 +135,36 @@ unsigned int nvmap_get_heap_bit(struct nvmap_carveout_node *co_heap); struct nvmap_heap *nvmap_get_heap_ptr(struct nvmap_carveout_node *co_heap); +struct rb_root *nvmap_get_device_names(struct nvmap_carveout_node *co_heap); + +static inline bool nvmap_page_dirty(struct page *page) +{ + return (unsigned long)page & 1UL; +} + +static inline bool nvmap_page_mkdirty(struct page **page) +{ + if (nvmap_page_dirty(*page)) + return false; + *page = (struct page *)((unsigned long)*page | 1UL); + return true; +} + +static inline bool nvmap_page_mkclean(struct page **page) +{ + if (!nvmap_page_dirty(*page)) + return false; + *page = (struct page *)((unsigned long)*page & ~1UL); + return true; +} + +static inline void nvmap_acquire_mmap_read_lock(struct mm_struct *mm) +{ + down_read(&mm->mmap_lock); +} + +static inline void nvmap_release_mmap_read_lock(struct mm_struct *mm) +{ + up_read(&mm->mmap_lock); +} #endif /* __NVMAP_ALLOC_H */ diff --git a/drivers/video/tegra/nvmap/nvmap_cache.c b/drivers/video/tegra/nvmap/nvmap_cache.c index 7ed8df8a..93951b5a 100644 --- a/drivers/video/tegra/nvmap/nvmap_cache.c +++ b/drivers/video/tegra/nvmap/nvmap_cache.c @@ -17,13 +17,19 @@ __weak struct arm64_ftr_reg arm64_ftr_reg_ctrel0; #include - -#include "nvmap_priv.h" +#include #include "nvmap_dev.h" #include "nvmap_alloc.h" #include "nvmap_alloc_int.h" #include "nvmap_handle.h" #include "nvmap_dmabuf.h" +#include "nvmap_debug.h" + +#ifdef CONFIG_ARM64 +#define PG_PROT_KERNEL PAGE_KERNEL +#else +#define PG_PROT_KERNEL pgprot_kernel +#endif extern void __clean_dcache_area_poc(void *addr, size_t len); diff --git a/drivers/video/tegra/nvmap/nvmap_carveout.c b/drivers/video/tegra/nvmap/nvmap_carveout.c index 10f259b7..38250835 100644 --- a/drivers/video/tegra/nvmap/nvmap_carveout.c +++ b/drivers/video/tegra/nvmap/nvmap_carveout.c @@ -6,13 +6,13 @@ */ #include - #include - -#include "nvmap_priv.h" +#include +#include +#include #include "nvmap_dev.h" -#include "nvmap_handle.h" #include "nvmap_alloc.h" +#include "nvmap_handle.h" #include "nvmap_alloc_int.h" bool vpr_cpu_access; @@ -181,105 +181,6 @@ free_mem: return err; } -#ifdef NVMAP_CONFIG_DEBUG_MAPS -struct nvmap_device_list *nvmap_is_device_present(char *device_name, u32 heap_type) -{ - struct rb_node *node = NULL; - int i; - - if (heap_type == NVMAP_HEAP_IOVMM) { - node = nvmap_dev->device_names.rb_node; - } else { - for (i = 0; i < nvmap_dev->nr_carveouts; i++) { - if ((heap_type & nvmap_dev->heaps[i]->heap_bit) && - nvmap_dev->heaps[i]->carveout) { - node = nvmap_dev->heaps[i]->carveout->device_names.rb_node; - break; - } - } - } - while (node) { - struct nvmap_device_list *dl = container_of(node, - struct nvmap_device_list, node); - if (strcmp(dl->device_name, device_name) > 0) - node = node->rb_left; - else if (strcmp(dl->device_name, device_name) < 0) - node = node->rb_right; - else - return dl; - } - return NULL; -} - -void nvmap_add_device_name(char *device_name, u64 dma_mask, u32 heap_type) -{ - struct rb_root *root = NULL; - struct rb_node **new = NULL, *parent = NULL; - struct nvmap_device_list *dl = NULL; - int i; - - if (heap_type == NVMAP_HEAP_IOVMM) { - root = &nvmap_dev->device_names; - } else { - for (i = 0; i < nvmap_dev->nr_carveouts; i++) { - if ((heap_type & nvmap_dev->heaps[i]->heap_bit) && - nvmap_dev->heaps[i]->carveout) { - root = &nvmap_dev->heaps[i]->carveout->device_names; - break; - } - } - } - if (root) { - new = &(root->rb_node); - while (*new) { - dl = container_of(*new, struct nvmap_device_list, node); - parent = *new; - if (strcmp(dl->device_name, device_name) > 0) - new = &((*new)->rb_left); - else if (strcmp(dl->device_name, device_name) < 0) - new = &((*new)->rb_right); - } - dl = kzalloc(sizeof(*dl), GFP_KERNEL); - if (!dl) - return; - dl->device_name = kzalloc(strlen(device_name) + 1, GFP_KERNEL); - if (!dl->device_name) - return; - strcpy(dl->device_name, device_name); - dl->dma_mask = dma_mask; - rb_link_node(&dl->node, parent, new); - rb_insert_color(&dl->node, root); - } -} - -void nvmap_remove_device_name(char *device_name, u32 heap_type) -{ - struct nvmap_device_list *dl = NULL; - int i; - - dl = nvmap_is_device_present(device_name, heap_type); - if (dl) { - if (heap_type == NVMAP_HEAP_IOVMM) { - rb_erase(&dl->node, - &nvmap_dev->device_names); - kfree(dl->device_name); - kfree(dl); - return; - } - for (i = 0; i < nvmap_dev->nr_carveouts; i++) { - if ((heap_type & nvmap_dev->heaps[i]->heap_bit) && - nvmap_dev->heaps[i]->carveout) { - rb_erase(&dl->node, - &nvmap_dev->heaps[i]->carveout->device_names); - kfree(dl->device_name); - kfree(dl); - return; - } - } - } -} -#endif /* NVMAP_CONFIG_DEBUG_MAPS */ - static struct nvmap_heap_block *do_nvmap_carveout_alloc(struct nvmap_client *client, struct nvmap_handle *handle, diff --git a/drivers/video/tegra/nvmap/nvmap_core.c b/drivers/video/tegra/nvmap/nvmap_core.c index 41bb8141..91daf088 100644 --- a/drivers/video/tegra/nvmap/nvmap_core.c +++ b/drivers/video/tegra/nvmap/nvmap_core.c @@ -24,10 +24,15 @@ #include #include "nvmap_dev.h" -#include "nvmap_priv.h" #include "nvmap_alloc.h" #include "nvmap_handle.h" +#ifdef CONFIG_ARM64 +#define PG_PROT_KERNEL PAGE_KERNEL +#else +#define PG_PROT_KERNEL pgprot_kernel +#endif + static phys_addr_t handle_phys(struct nvmap_handle *h) { if (h->heap_pgalloc) diff --git a/drivers/video/tegra/nvmap/nvmap_debug.c b/drivers/video/tegra/nvmap/nvmap_debug.c index 4e67c85e..6a08b8ef 100644 --- a/drivers/video/tegra/nvmap/nvmap_debug.c +++ b/drivers/video/tegra/nvmap/nvmap_debug.c @@ -8,15 +8,18 @@ #include #include -#include "nvmap_priv.h" +#include +#include +#include #include "nvmap_dev.h" +#include "nvmap_alloc.h" #include "nvmap_handle.h" #include "nvmap_debug.h" -#include "nvmap_alloc.h" #include "nvmap_stats.h" #include "nvmap_dmabuf.h" struct debugfs_info *iovmm_debugfs_info; +extern ulong nvmap_init_time; #define DEBUGFS_OPEN_FOPS_STATIC(name) \ static int nvmap_debug_##name##_open(struct inode *inode, \ diff --git a/drivers/video/tegra/nvmap/nvmap_debug.h b/drivers/video/tegra/nvmap/nvmap_debug.h index d29b0509..5655d767 100644 --- a/drivers/video/tegra/nvmap/nvmap_debug.h +++ b/drivers/video/tegra/nvmap/nvmap_debug.h @@ -6,6 +6,7 @@ #ifndef __NVMAP_DEBUG_H #define __NVMAP_DEBUG_H +#include "nvmap_stats.h" #if defined(CONFIG_DEBUG_FS) void nvmap_debug_init(struct dentry **nvmap_debug_root); void nvmap_debug_free(struct dentry *nvmap_debug_root); diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c index f0040137..a78b3c23 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev.c +++ b/drivers/video/tegra/nvmap/nvmap_dev.c @@ -40,8 +40,7 @@ #define CREATE_TRACE_POINTS #include - -#include "nvmap_priv.h" +#include #include "nvmap_dev.h" #include "nvmap_alloc.h" #include "nvmap_dmabuf.h" @@ -57,6 +56,9 @@ struct nvmap_device *nvmap_dev; EXPORT_SYMBOL(nvmap_dev); ulong nvmap_init_time; +extern bool nvmap_convert_iovmm_to_carveout; +extern bool nvmap_convert_carveout_to_iovmm; + static struct device_dma_parameters nvmap_dma_parameters = { .max_segment_size = UINT_MAX, }; @@ -734,3 +736,101 @@ int nvmap_remove(struct platform_device *pdev) nvmap_dev = NULL; return 0; } + +#ifdef NVMAP_CONFIG_DEBUG_MAPS +struct nvmap_device_list *nvmap_is_device_present(char *device_name, u32 heap_type) +{ + struct rb_node *node = NULL; + int i; + + if (heap_type == NVMAP_HEAP_IOVMM) { + node = nvmap_dev->device_names.rb_node; + } else { + for (i = 0; i < nvmap_dev->nr_carveouts; i++) { + if ((heap_type & nvmap_get_heap_bit(nvmap_dev->heaps[i])) && + nvmap_get_heap_ptr(nvmap_dev->heaps[i])) { + node = nvmap_get_device_names(nvmap_dev->heaps[i])->rb_node; + break; + } + } + } + while (node) { + struct nvmap_device_list *dl = container_of(node, + struct nvmap_device_list, node); + if (strcmp(dl->device_name, device_name) > 0) + node = node->rb_left; + else if (strcmp(dl->device_name, device_name) < 0) + node = node->rb_right; + else + return dl; + } + return NULL; +} + +void nvmap_add_device_name(char *device_name, u64 dma_mask, u32 heap_type) +{ + struct rb_root *root = NULL; + struct rb_node **new = NULL, *parent = NULL; + struct nvmap_device_list *dl = NULL; + int i; + + if (heap_type == NVMAP_HEAP_IOVMM) { + root = &nvmap_dev->device_names; + } else { + for (i = 0; i < nvmap_dev->nr_carveouts; i++) { + if ((heap_type & nvmap_get_heap_bit(nvmap_dev->heaps[i])) && + nvmap_get_heap_ptr(nvmap_dev->heaps[i])) { + root = nvmap_get_device_names(nvmap_dev->heaps[i]); + break; + } + } + } + if (root) { + new = &(root->rb_node); + while (*new) { + dl = container_of(*new, struct nvmap_device_list, node); + parent = *new; + if (strcmp(dl->device_name, device_name) > 0) + new = &((*new)->rb_left); + else if (strcmp(dl->device_name, device_name) < 0) + new = &((*new)->rb_right); + } + dl = kzalloc(sizeof(*dl), GFP_KERNEL); + if (!dl) + return; + dl->device_name = kzalloc(strlen(device_name) + 1, GFP_KERNEL); + if (!dl->device_name) + return; + strcpy(dl->device_name, device_name); + dl->dma_mask = dma_mask; + rb_link_node(&dl->node, parent, new); + rb_insert_color(&dl->node, root); + } +} + +void nvmap_remove_device_name(char *device_name, u32 heap_type) +{ + struct nvmap_device_list *dl = NULL; + int i; + + dl = nvmap_is_device_present(device_name, heap_type); + if (dl) { + if (heap_type == NVMAP_HEAP_IOVMM) { + rb_erase(&dl->node, + &nvmap_dev->device_names); + kfree(dl->device_name); + kfree(dl); + return; + } + for (i = 0; i < nvmap_dev->nr_carveouts; i++) { + if ((heap_type & nvmap_get_heap_bit(nvmap_dev->heaps[i])) && + nvmap_get_heap_ptr(nvmap_dev->heaps[i])) { + rb_erase(&dl->node, nvmap_get_device_names(nvmap_dev->heaps[i])); + kfree(dl->device_name); + kfree(dl); + return; + } + } + } +} +#endif /* NVMAP_CONFIG_DEBUG_MAPS */ diff --git a/drivers/video/tegra/nvmap/nvmap_dev.h b/drivers/video/tegra/nvmap/nvmap_dev.h index b4b88a1b..29e4f5a8 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev.h +++ b/drivers/video/tegra/nvmap/nvmap_dev.h @@ -3,8 +3,10 @@ #ifndef __NVMAP_DEV_H #define __NVMAP_DEV_H -#define NVMAP_HEAP_IOVMM (1ul<<30) +#include + +#define NVMAP_HEAP_IOVMM (1ul<<30) /* common carveout heaps */ #define NVMAP_HEAP_CARVEOUT_VPR (1ul<<28) #define NVMAP_HEAP_CARVEOUT_TSEC (1ul<<27) @@ -80,9 +82,60 @@ struct nvmap_pid_data { struct dentry *handles_file; }; +struct nvmap_device { + struct rb_root handles; + spinlock_t handle_lock; + struct miscdevice dev_user; + struct nvmap_carveout_node **heaps; + int nr_heaps; + int nr_carveouts; +#ifdef NVMAP_CONFIG_PAGE_POOLS + struct nvmap_page_pool *pool; +#endif + struct list_head clients; + struct rb_root pids; + struct mutex clients_lock; + struct list_head lru_handles; + spinlock_t lru_lock; + struct dentry *handles_by_pid; + struct dentry *debug_root; + struct nvmap_platform_data *plat; + struct rb_root tags; + struct mutex tags_lock; + struct mutex carveout_lock; /* needed to serialize carveout creation */ + u32 dynamic_dma_map_mask; + u32 cpu_access_mask; +#ifdef NVMAP_CONFIG_DEBUG_MAPS + struct rb_root device_names; +#endif /* NVMAP_CONFIG_DEBUG_MAPS */ + u64 serial_id_counter; /* This is global counter common across different client processes */ +}; + +#define NVMAP_TAG_TRACE(x, ...) \ +do { \ + if (x##_enabled()) { \ + mutex_lock(&nvmap_dev->tags_lock); \ + x(__VA_ARGS__); \ + mutex_unlock(&nvmap_dev->tags_lock); \ + } \ +} while (0) + bool is_nvmap_memory_available(size_t size, uint32_t heap, int numa_nid); void kasan_memcpy_toio(void __iomem *to, const void *from, size_t count); +char *__nvmap_tag_name(struct nvmap_device *dev, u32 tag); + +#ifdef NVMAP_CONFIG_DEBUG_MAPS +struct nvmap_device_list { + struct rb_node node; + u64 dma_mask; + char *device_name; +}; + +struct nvmap_device_list *nvmap_is_device_present(char *device_name, u32 heap_type); +void nvmap_add_device_name(char *device_name, u64 dma_mask, u32 heap_type); +void nvmap_remove_device_name(char *device_name, u32 heap_type); +#endif /* NVMAP_CONFIG_DEBUG_MAPS */ #endif /* __NVMAP_DEV_H */ diff --git a/drivers/video/tegra/nvmap/nvmap_dev_int.h b/drivers/video/tegra/nvmap/nvmap_dev_int.h index 3d073bf8..330860af 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev_int.h +++ b/drivers/video/tegra/nvmap/nvmap_dev_int.h @@ -4,6 +4,8 @@ #ifndef __NVMAP_DEV_INT_H #define __NVMAP_DEV_INT_H +#define ACCESS_OK(type, addr, size) access_ok(addr, size) + int nvmap_probe(struct platform_device *pdev); int nvmap_remove(struct platform_device *pdev); @@ -53,4 +55,10 @@ int nvmap_ioctl_dup_handle(struct file *filp, void __user *arg); int nvmap_ioctl_get_fd_from_list(struct file *filp, void __user *arg); +int nvmap_define_tag(struct nvmap_device *dev, u32 tag, + const char __user *name, u32 len); + +int nvmap_remove_tag(struct nvmap_device *dev, u32 tag); + +unsigned int nvmap_get_tag_maxlen(void); #endif /* __NVMAP_DEV_INT_H */ diff --git a/drivers/video/tegra/nvmap/nvmap_dmabuf.c b/drivers/video/tegra/nvmap/nvmap_dmabuf.c index 012b2c94..eba99bc5 100644 --- a/drivers/video/tegra/nvmap/nvmap_dmabuf.c +++ b/drivers/video/tegra/nvmap/nvmap_dmabuf.c @@ -30,7 +30,6 @@ #include -#include "nvmap_priv.h" #include "nvmap_dev.h" #include "nvmap_alloc.h" #include "nvmap_dmabuf.h" diff --git a/drivers/video/tegra/nvmap/nvmap_dmabuf.h b/drivers/video/tegra/nvmap/nvmap_dmabuf.h index af496370..86d38e4a 100644 --- a/drivers/video/tegra/nvmap/nvmap_dmabuf.h +++ b/drivers/video/tegra/nvmap/nvmap_dmabuf.h @@ -50,6 +50,12 @@ struct nvmap_vma_list { atomic_t ref; }; +struct nvmap_vma_priv { + struct nvmap_handle *handle; + size_t offs; + atomic_t count; /* number of processes cloning the VMA */ +}; + int is_nvmap_vma(struct vm_area_struct *vma); void nvmap_vma_open(struct vm_area_struct *vma); diff --git a/drivers/video/tegra/nvmap/nvmap_fault.c b/drivers/video/tegra/nvmap/nvmap_fault.c index 35079c3e..9dbf5af0 100644 --- a/drivers/video/tegra/nvmap/nvmap_fault.c +++ b/drivers/video/tegra/nvmap/nvmap_fault.c @@ -7,8 +7,8 @@ #include #include +#include -#include "nvmap_priv.h" #include "nvmap_dev.h" #include "nvmap_alloc.h" #include "nvmap_handle.h" diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c index f6455052..b5f191d0 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.c +++ b/drivers/video/tegra/nvmap/nvmap_handle.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -25,12 +26,12 @@ #include -#include "nvmap_priv.h" #include "nvmap_dev.h" #include "nvmap_alloc.h" #include "nvmap_dmabuf.h" #include "nvmap_handle.h" #include "nvmap_handle_int.h" +#include "nvmap_debug.h" u32 nvmap_max_handle_count; diff --git a/drivers/video/tegra/nvmap/nvmap_handle.h b/drivers/video/tegra/nvmap/nvmap_handle.h index 07589925..6fafd58d 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.h +++ b/drivers/video/tegra/nvmap/nvmap_handle.h @@ -10,6 +10,8 @@ #include #include +extern struct nvmap_device *nvmap_dev; + /* handles allocated as collection of pages */ struct nvmap_pgalloc { struct page **pages; @@ -178,6 +180,9 @@ static inline pgprot_t nvmap_pgprot(struct nvmap_handle *h, pgprot_t prot) return prot; } +static inline bool nvmap_page_mkdirty(struct page **page); +static inline bool nvmap_page_mkclean(struct page **page); + /* * FIXME: assume user space requests for reserve operations * are page aligned @@ -355,6 +360,10 @@ struct nvmap_handle *nvmap_handle_get_from_id(struct nvmap_client *client, u32 nvmap_handle_get_max_handle_count(void); +void *__nvmap_mmap(struct nvmap_handle *h); + +void __nvmap_munmap(struct nvmap_handle *h, void *addr); + #ifdef NVMAP_CONFIG_SCIIPC int nvmap_sci_ipc_init(void); void nvmap_sci_ipc_exit(void); diff --git a/drivers/video/tegra/nvmap/nvmap_heap.c b/drivers/video/tegra/nvmap/nvmap_heap.c index c2c252dd..77a127bc 100644 --- a/drivers/video/tegra/nvmap/nvmap_heap.c +++ b/drivers/video/tegra/nvmap/nvmap_heap.c @@ -25,10 +25,10 @@ #include #include #include -#include "nvmap_priv.h" +#include #include "nvmap_dev.h" -#include "nvmap_handle.h" #include "nvmap_alloc.h" +#include "nvmap_handle.h" #include "nvmap_alloc_int.h" #include "nvmap_dmabuf.h" @@ -57,6 +57,10 @@ static struct kmem_cache *heap_block_cache; +extern bool nvmap_convert_iovmm_to_carveout; +extern bool nvmap_convert_carveout_to_iovmm; +extern ulong nvmap_init_time; + /* * This function calculates allocatable free memory using following formula: * free_mem = avail mem - cma free @@ -1178,3 +1182,9 @@ struct nvmap_heap *nvmap_get_heap_ptr(struct nvmap_carveout_node *co_heap) return co_heap->carveout; } +#ifdef NVMAP_CONFIG_DEBUG_MAPS +struct rb_root *nvmap_get_device_names(struct nvmap_carveout_node *co_heap) +{ + return &co_heap->carveout->device_names; +} +#endif /* NVMAP_CONFIG_DEBUG_MAPS */ diff --git a/drivers/video/tegra/nvmap/nvmap_id_array.c b/drivers/video/tegra/nvmap/nvmap_id_array.c index 84645c66..556071ec 100644 --- a/drivers/video/tegra/nvmap/nvmap_id_array.c +++ b/drivers/video/tegra/nvmap/nvmap_id_array.c @@ -5,8 +5,9 @@ #include #include -#include "nvmap_priv.h" +#include #include "nvmap_dev.h" +#include "nvmap_alloc.h" #include "nvmap_handle.h" /* diff --git a/drivers/video/tegra/nvmap/nvmap_init.c b/drivers/video/tegra/nvmap/nvmap_init.c index 4f43c78b..6543269f 100644 --- a/drivers/video/tegra/nvmap/nvmap_init.c +++ b/drivers/video/tegra/nvmap/nvmap_init.c @@ -6,7 +6,6 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ #include - #include #include #include @@ -14,18 +13,17 @@ #include #include #include - #include - +#include +#include #include #include #include -#include "include/linux/nvmap_exports.h" -#include "nvmap_priv.h" +#include "include/linux/nvmap_exports.h" #include "nvmap_dev.h" -#include "nvmap_handle.h" #include "nvmap_alloc.h" +#include "nvmap_handle.h" #include "nvmap_dev_int.h" #ifdef CONFIG_TEGRA_VIRTUALIZATION @@ -42,6 +40,7 @@ struct device __weak tegra_generic_cma_dev; struct device __weak tegra_vpr_cma_dev; static struct platform_device *pdev; +extern ulong nvmap_init_time; const struct of_device_id nvmap_of_ids[] = { { .compatible = "nvidia,carveouts" }, diff --git a/drivers/video/tegra/nvmap/nvmap_ioctl.c b/drivers/video/tegra/nvmap/nvmap_ioctl.c index 040fcefb..b7c39f9c 100644 --- a/drivers/video/tegra/nvmap/nvmap_ioctl.c +++ b/drivers/video/tegra/nvmap/nvmap_ioctl.c @@ -31,9 +31,9 @@ #include #include #endif - +#include +#include #include "nvmap_dev.h" -#include "nvmap_priv.h" #include "nvmap_alloc.h" #include "nvmap_dmabuf.h" #include "nvmap_handle.h" @@ -48,8 +48,10 @@ MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); #define SIZE_2MB 0x200000 #define ALIGN_2MB(size) ((size + SIZE_2MB - 1) & ~(SIZE_2MB - 1)) +#define NVMAP_TAG_LABEL_MAXLEN (63 - sizeof(struct nvmap_tag_entry)) extern bool vpr_cpu_access; +extern struct nvmap_device *nvmap_dev; int nvmap_ioctl_getfd(struct file *filp, void __user *arg) { @@ -638,7 +640,7 @@ int nvmap_ioctl_free(struct file *filp, unsigned long arg) return 0; } close_fd: - return SYS_CLOSE(arg); + return close_fd(arg); } int nvmap_ioctl_get_ivcid(struct file *filp, void __user *arg) @@ -859,12 +861,14 @@ int nvmap_ioctl_set_tag_label(struct file *filp, void __user *arg) struct nvmap_set_tag_label op; struct nvmap_device *dev = nvmap_dev; int err; + unsigned int nvmap_tag_label_maxlen = 0; if (copy_from_user(&op, arg, sizeof(op))) return -EFAULT; - if (op.len > NVMAP_TAG_LABEL_MAXLEN) - op.len = NVMAP_TAG_LABEL_MAXLEN; + nvmap_tag_label_maxlen = nvmap_get_tag_maxlen(); + if (op.len > nvmap_tag_label_maxlen) + op.len = nvmap_tag_label_maxlen; if (op.len) err = nvmap_define_tag(dev, op.tag, diff --git a/drivers/video/tegra/nvmap/nvmap_pp.c b/drivers/video/tegra/nvmap/nvmap_pp.c index d1565095..67b933e7 100644 --- a/drivers/video/tegra/nvmap/nvmap_pp.c +++ b/drivers/video/tegra/nvmap/nvmap_pp.c @@ -22,8 +22,7 @@ #include #include #include - -#include "nvmap_priv.h" +#include #include "nvmap_dev.h" #include "nvmap_alloc.h" #include "nvmap_alloc_int.h" @@ -33,6 +32,7 @@ extern u64 nvmap_big_page_allocs; extern u64 nvmap_total_page_allocs; +extern struct nvmap_device *nvmap_dev; static bool enable_pp = 1; static u32 pool_size; diff --git a/drivers/video/tegra/nvmap/nvmap_priv.h b/drivers/video/tegra/nvmap/nvmap_priv.h deleted file mode 100644 index c23c8da0..00000000 --- a/drivers/video/tegra/nvmap/nvmap_priv.h +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only - * SPDX-FileCopyrightText: Copyright (c) 2009-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * - * GPU memory management driver for Tegra - */ - -#ifndef __VIDEO_TEGRA_NVMAP_NVMAP_H -#define __VIDEO_TEGRA_NVMAP_NVMAP_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#ifndef CONFIG_ARM64 -#include -#endif -#include "nvmap_stats.h" - -#include - -#define NVMAP_TAG_LABEL_MAXLEN (63 - sizeof(struct nvmap_tag_entry)) - -#define NVMAP_TAG_TRACE(x, ...) \ -do { \ - if (x##_enabled()) { \ - mutex_lock(&nvmap_dev->tags_lock); \ - x(__VA_ARGS__); \ - mutex_unlock(&nvmap_dev->tags_lock); \ - } \ -} while (0) - -#define ACCESS_OK(type, addr, size) access_ok(addr, size) -#define SYS_CLOSE(arg) close_fd(arg) - -struct page; -struct nvmap_device; - -extern bool nvmap_convert_iovmm_to_carveout; -extern bool nvmap_convert_carveout_to_iovmm; - -#ifdef CONFIG_ARM64 -#define PG_PROT_KERNEL PAGE_KERNEL -#else -#define PG_PROT_KERNEL pgprot_kernel -#endif - -#ifdef NVMAP_CONFIG_DEBUG_MAPS -struct nvmap_device_list { - struct rb_node node; - u64 dma_mask; - char *device_name; -}; -#endif /* NVMAP_CONFIG_DEBUG_MAPS */ - -/* bit 31-29: IVM peer - * bit 28-16: offset (aligned to 32K) - * bit 15-00: len (aligned to page_size) - */ -#define NVMAP_IVM_LENGTH_SHIFT (0) -#define NVMAP_IVM_LENGTH_WIDTH (16) -#define NVMAP_IVM_LENGTH_MASK ((1 << NVMAP_IVM_LENGTH_WIDTH) - 1) -#define NVMAP_IVM_OFFSET_SHIFT (NVMAP_IVM_LENGTH_SHIFT + NVMAP_IVM_LENGTH_WIDTH) -#define NVMAP_IVM_OFFSET_WIDTH (13) -#define NVMAP_IVM_OFFSET_MASK ((1 << NVMAP_IVM_OFFSET_WIDTH) - 1) -#define NVMAP_IVM_IVMID_SHIFT (NVMAP_IVM_OFFSET_SHIFT + NVMAP_IVM_OFFSET_WIDTH) -#define NVMAP_IVM_IVMID_WIDTH (3) -#define NVMAP_IVM_IVMID_MASK ((1 << NVMAP_IVM_IVMID_WIDTH) - 1) -#define NVMAP_IVM_ALIGNMENT (SZ_32K) - -struct nvmap_tag_entry { - struct rb_node node; - atomic_t ref; /* reference count (i.e., # of duplications) */ - u32 tag; -}; - -#define NVMAP_IVM_INVALID_PEER (-1) - -struct nvmap_vma_priv { - struct nvmap_handle *handle; - size_t offs; - atomic_t count; /* number of processes cloning the VMA */ -}; - -struct nvmap_device { - struct rb_root handles; - spinlock_t handle_lock; - struct miscdevice dev_user; - struct nvmap_carveout_node **heaps; - int nr_heaps; - int nr_carveouts; -#ifdef NVMAP_CONFIG_PAGE_POOLS - struct nvmap_page_pool *pool; -#endif - struct list_head clients; - struct rb_root pids; - struct mutex clients_lock; - struct list_head lru_handles; - spinlock_t lru_lock; - struct dentry *handles_by_pid; - struct dentry *debug_root; - struct nvmap_platform_data *plat; - struct rb_root tags; - struct mutex tags_lock; - struct mutex carveout_lock; /* needed to serialize carveout creation */ - u32 dynamic_dma_map_mask; - u32 cpu_access_mask; -#ifdef NVMAP_CONFIG_DEBUG_MAPS - struct rb_root device_names; -#endif /* NVMAP_CONFIG_DEBUG_MAPS */ - u64 serial_id_counter; /* This is global counter common across different client processes */ -}; - -extern struct nvmap_device *nvmap_dev; -extern ulong nvmap_init_time; - -static inline void nvmap_acquire_mmap_read_lock(struct mm_struct *mm) -{ - down_read(&mm->mmap_lock); -} - -static inline void nvmap_release_mmap_read_lock(struct mm_struct *mm) -{ - up_read(&mm->mmap_lock); -} - -struct nvmap_carveout_node; - -void outer_cache_maint(unsigned int op, phys_addr_t paddr, size_t size); - -void *__nvmap_mmap(struct nvmap_handle *h); -void __nvmap_munmap(struct nvmap_handle *h, void *addr); - -static inline bool nvmap_page_dirty(struct page *page) -{ - return (unsigned long)page & 1UL; -} - -static inline bool nvmap_page_mkdirty(struct page **page) -{ - if (nvmap_page_dirty(*page)) - return false; - *page = (struct page *)((unsigned long)*page | 1UL); - return true; -} - -static inline bool nvmap_page_mkclean(struct page **page) -{ - if (!nvmap_page_dirty(*page)) - return false; - *page = (struct page *)((unsigned long)*page & ~1UL); - return true; -} - -struct nvmap_tag_entry *nvmap_search_tag_entry(struct rb_root *root, u32 tag); - -int nvmap_define_tag(struct nvmap_device *dev, u32 tag, - const char __user *name, u32 len); - -int nvmap_remove_tag(struct nvmap_device *dev, u32 tag); - -/* must hold tag_lock */ -static inline char *__nvmap_tag_name(struct nvmap_device *dev, u32 tag) -{ - struct nvmap_tag_entry *entry; - - entry = nvmap_search_tag_entry(&dev->tags, tag); - return entry ? (char *)(entry + 1) : ""; -} - -#ifdef NVMAP_CONFIG_DEBUG_MAPS -struct nvmap_device_list *nvmap_is_device_present(char *device_name, u32 heap_type); -void nvmap_add_device_name(char *device_name, u64 dma_mask, u32 heap_type); -void nvmap_remove_device_name(char *device_name, u32 heap_type); -#endif /* NVMAP_CONFIG_DEBUG_MAPS */ - -#endif /* __VIDEO_TEGRA_NVMAP_NVMAP_H */ diff --git a/drivers/video/tegra/nvmap/nvmap_sci_ipc.c b/drivers/video/tegra/nvmap/nvmap_sci_ipc.c index f7233c5a..ca87650c 100644 --- a/drivers/video/tegra/nvmap/nvmap_sci_ipc.c +++ b/drivers/video/tegra/nvmap/nvmap_sci_ipc.c @@ -20,9 +20,9 @@ #include #include -#include "nvmap_priv.h" #include "nvmap_dev.h" #include "nvmap_dmabuf.h" +#include "nvmap_alloc.h" #include "nvmap_handle.h" #include "nvmap_handle_int.h" diff --git a/drivers/video/tegra/nvmap/nvmap_stats.c b/drivers/video/tegra/nvmap/nvmap_stats.c index 6870c618..a05d6f8f 100644 --- a/drivers/video/tegra/nvmap/nvmap_stats.c +++ b/drivers/video/tegra/nvmap/nvmap_stats.c @@ -6,8 +6,7 @@ */ #include - -#include "nvmap_priv.h" +#include "nvmap_stats.h" struct nvmap_stats nvmap_stats; diff --git a/drivers/video/tegra/nvmap/nvmap_tag.c b/drivers/video/tegra/nvmap/nvmap_tag.c index 87dbe79d..016096ed 100644 --- a/drivers/video/tegra/nvmap/nvmap_tag.c +++ b/drivers/video/tegra/nvmap/nvmap_tag.c @@ -10,10 +10,23 @@ #include #include +#include +#include +#include "nvmap_dev.h" +#include "nvmap_dev_int.h" -#include "nvmap_priv.h" +struct nvmap_tag_entry { + struct rb_node node; + atomic_t ref; /* reference count (i.e., # of duplications) */ + u32 tag; +}; -struct nvmap_tag_entry *nvmap_search_tag_entry(struct rb_root *root, u32 tag) +unsigned int nvmap_get_tag_maxlen(void) +{ + return 63 - sizeof(struct nvmap_tag_entry); +} + +static struct nvmap_tag_entry *nvmap_search_tag_entry(struct rb_root *root, u32 tag) { struct rb_node *node = root->rb_node; /* top of the tree */ struct nvmap_tag_entry *entry; @@ -101,3 +114,12 @@ int nvmap_remove_tag(struct nvmap_device *dev, u32 tag) return 0; } + +/* must hold tag_lock */ +char *__nvmap_tag_name(struct nvmap_device *dev, u32 tag) +{ + struct nvmap_tag_entry *entry; + + entry = nvmap_search_tag_entry(&dev->tags, tag); + return entry ? (char *)(entry + 1) : ""; +} \ No newline at end of file