/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * * (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation, and any use by you of this program is subject to the terms * of such GNU license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you can access it online at * http://www.gnu.org/licenses/gpl-2.0.html. * */ #ifndef _MEMORY_GROUP_MANAGER_H_ #define _MEMORY_GROUP_MANAGER_H_ #include #include #include #if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) typedef int vm_fault_t; #endif #define MEMORY_GROUP_MANAGER_NR_GROUPS (16) #define PTE_PBHA_SHIFT (59) #define PTE_PBHA_MASK ((uint64_t)0xf << PTE_PBHA_SHIFT) #define PTE_RES_BIT_MULTI_AS_SHIFT (63) #define PTE_FLAGS_NONE (0) #define PBHA_ID_DEFAULT (0) struct memory_group_manager_device; struct memory_group_manager_import_data; /** * enum mgm_pte_flags - Memory Group Manager PTE Flags * @MMA_VIOLATION: Bit-number of flag used to indicate that Mismatched Memory Attributes (MMA) * exist for a page. Specifically, this means CPU-uncached, GPU-cached. */ enum mgm_pte_flags { MMA_VIOLATION = 0, }; /** * struct memory_group_manager_ops - Callbacks for memory group manager * operations * * @mgm_alloc_page: Callback to allocate physical memory in a group * @mgm_free_page: Callback to free physical memory in a group * @mgm_get_import_memory_id: Callback to get the group ID for imported memory * @mgm_update_gpu_pte: Callback to modify a GPU page table entry * @mgm_pte_to_original_pte: Callback to get the original PTE entry as given * to mgm_update_gpu_pte * @mgm_vmf_insert_pfn_prot: Callback to map a physical memory page for the CPU * @mgm_get_import_memory_cached_access_permitted: Callback to query if a given imported * memory is allowed to be accessed as cached or not by the GPU */ struct memory_group_manager_ops { /* * mgm_alloc_page - Allocate a physical memory page in a group * * @mgm_dev: The memory group manager through which the request is * being made. * @group_id: A physical memory group ID. The meaning of this is defined * by the systems integrator. Its valid range is * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. * @gfp_mask: Bitmask of Get Free Page flags affecting allocator * behavior. * @order: Page order for physical page size. * order = 0 refers to small pages * order != 0 refers to 2 MB pages, so * order = 9 (when small page size is 4KB, 2^9 * 4KB = 2 MB) * order = 7 (when small page size is 16KB, 2^7 * 16KB = 2 MB) * order = 5 (when small page size is 64KB, 2^5 * 64KB = 2 MB) * * Return: Pointer to allocated page, or NULL if allocation failed. */ struct page *(*mgm_alloc_page)(struct memory_group_manager_device *mgm_dev, unsigned int group_id, gfp_t gfp_mask, unsigned int order); /* * mgm_free_page - Free a physical memory page in a group * * @mgm_dev: The memory group manager through which the request * is being made. * @group_id: A physical memory group ID. The meaning of this is * defined by the systems integrator. Its valid range is * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. * @page: Address of the struct associated with a page of physical * memory that was allocated by calling the mgm_alloc_page * method of the same memory pool with the same values of * @group_id and @order. * @order: Page order for physical page size. * order = 0 refers to small pages * order != 0 refers to 2 MB pages. */ void (*mgm_free_page)(struct memory_group_manager_device *mgm_dev, unsigned int group_id, struct page *page, unsigned int order); /* * mgm_get_import_memory_id - Get the physical memory group ID for the * imported memory * * @mgm_dev: The memory group manager through which the request * is being made. * @import_data: Pointer to the data which describes imported memory. * * Note that provision of this call back is optional, where it is not * provided this call back pointer must be set to NULL to indicate it * is not in use. * * Return: The memory group ID to use when mapping pages from this * imported memory. */ int (*mgm_get_import_memory_id)(struct memory_group_manager_device *mgm_dev, struct memory_group_manager_import_data *import_data); /* * mgm_update_gpu_pte - Modify a GPU page table entry for a memory group * * @mgm_dev: The memory group manager through which the request * is being made. * @group_id: A physical memory group ID. The meaning of this is * defined by the systems integrator. Its valid range is * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. * * @pbha_id: PBHA Override ID to encode into the PTE * @pte_flags: PTE related flags, defined in enum mgm_pte_flags * * * @mmu_level: The level of the page table entry in @ate. * @pte: The page table entry to modify, in LPAE or AArch64 format * (depending on the driver's configuration). This should be * decoded to determine the physical address and any other * properties of the mapping the manager requires. * * This function allows the memory group manager to modify a GPU page table entry before it * is stored by the kbase module (controller driver). It may set certain bits in the page * table entry attributes or modify the physical address, based on the physical memory * group ID, PBHA ID, PTE flags and/or additional data in * struct memory_group_manager_device. * * If mgm_pte_flags has the MMA_VIOLATION bit set - ie, 1<