1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Gasket Page Table functionality. This file describes the address 4 * translation/paging functionality supported by the Gasket driver framework. 5 * As much as possible, internal details are hidden to simplify use - 6 * all calls are thread-safe (protected by an internal mutex) except where 7 * indicated otherwise. 8 * 9 * Copyright (C) 2018 Google, Inc. 10 */ 11 12 #ifndef __GASKET_PAGE_TABLE_H__ 13 #define __GASKET_PAGE_TABLE_H__ 14 15 #include <linux/pci.h> 16 #include <linux/types.h> 17 18 #include "gasket_constants.h" 19 #include "gasket_core.h" 20 21 /* 22 * Structure used for managing address translation on a device. All details are 23 * internal to the implementation. 24 */ 25 struct gasket_page_table; 26 27 /* 28 * Allocate and init address translation data. 29 * @ppage_table: Pointer to Gasket page table pointer. Set by this call. 30 * @att_base_reg: [Mapped] pointer to the first entry in the device's address 31 * translation table. 32 * @extended_offset_reg: [Mapped] pointer to the device's register containing 33 * the starting index of the extended translation table. 34 * @extended_bit_location: The index of the bit indicating whether an address 35 * is extended. 36 * @total_entries: The total number of entries in the device's address 37 * translation table. 38 * @device: Device structure for the underlying device. Only used for logging. 39 * @pci_dev: PCI system descriptor for the underlying device. 40 * whether the driver will supply its own. 41 * 42 * Description: Allocates and initializes data to track address translation - 43 * simple and extended page table metadata. Initially, the page table is 44 * partitioned such that all addresses are "simple" (single-level lookup). 45 * gasket_partition_page_table can be called to change this paritioning. 46 * 47 * Returns 0 on success, a negative error code otherwise. 48 */ 49 int gasket_page_table_init(struct gasket_page_table **ppg_tbl, 50 const struct gasket_bar_data *bar_data, 51 const struct gasket_page_table_config *page_table_config, 52 struct device *device, struct pci_dev *pci_dev); 53 54 /* 55 * Deallocate and cleanup page table data. 56 * @page_table: Gasket page table pointer. 57 * 58 * Description: The inverse of gasket_init; frees page_table and its contained 59 * elements. 60 * 61 * Because this call destroys the page table, it cannot be 62 * thread-safe (mutex-protected)! 63 */ 64 void gasket_page_table_cleanup(struct gasket_page_table *page_table); 65 66 /* 67 * Sets the size of the simple page table. 68 * @page_table: Gasket page table pointer. 69 * @num_simple_entries: Desired size of the simple page table (in entries). 70 * 71 * Description: gasket_partition_page_table checks to see if the simple page 72 * size can be changed (i.e., if there are no active extended 73 * mappings in the new simple size range), and, if so, 74 * sets the new simple and extended page table sizes. 75 * 76 * Returns 0 if successful, or non-zero if the page table entries 77 * are not free. 78 */ 79 int gasket_page_table_partition(struct gasket_page_table *page_table, 80 uint num_simple_entries); 81 82 /* 83 * Get and map [host] user space pages into device memory. 84 * @page_table: Gasket page table pointer. 85 * @host_addr: Starting host virtual memory address of the pages. 86 * @dev_addr: Starting device address of the pages. 87 * @num_pages: Number of [4kB] pages to map. 88 * 89 * Description: Maps the "num_pages" pages of host memory pointed to by 90 * host_addr to the address "dev_addr" in device memory. 91 * 92 * The caller is responsible for checking the addresses ranges. 93 * 94 * Returns 0 if successful or a non-zero error number otherwise. 95 * If there is an error, no pages are mapped. 96 */ 97 int gasket_page_table_map(struct gasket_page_table *page_table, ulong host_addr, 98 ulong dev_addr, uint num_pages); 99 100 /* 101 * Un-map host pages from device memory. 102 * @page_table: Gasket page table pointer. 103 * @dev_addr: Starting device address of the pages to unmap. 104 * @num_pages: The number of [4kB] pages to unmap. 105 * 106 * Description: The inverse of gasket_map_pages. Unmaps pages from the device. 107 */ 108 void gasket_page_table_unmap(struct gasket_page_table *page_table, 109 ulong dev_addr, uint num_pages); 110 111 /* 112 * Unmap ALL host pages from device memory. 113 * @page_table: Gasket page table pointer. 114 */ 115 void gasket_page_table_unmap_all(struct gasket_page_table *page_table); 116 117 /* 118 * Unmap all host pages from device memory and reset the table to fully simple 119 * addressing. 120 * @page_table: Gasket page table pointer. 121 */ 122 void gasket_page_table_reset(struct gasket_page_table *page_table); 123 124 /* 125 * Reclaims unused page table memory. 126 * @page_table: Gasket page table pointer. 127 * 128 * Description: Examines the page table and frees any currently-unused 129 * allocations. Called internally on gasket_cleanup(). 130 */ 131 void gasket_page_table_garbage_collect(struct gasket_page_table *page_table); 132 133 /* 134 * Retrieve the backing page for a device address. 135 * @page_table: Gasket page table pointer. 136 * @dev_addr: Gasket device address. 137 * @ppage: Pointer to a page pointer for the returned page. 138 * @poffset: Pointer to an unsigned long for the returned offset. 139 * 140 * Description: Interprets the address and looks up the corresponding page 141 * in the page table and the offset in that page. (We need an 142 * offset because the host page may be larger than the Gasket chip 143 * page it contains.) 144 * 145 * Returns 0 if successful, -1 for an error. The page pointer 146 * and offset are returned through the pointers, if successful. 147 */ 148 int gasket_page_table_lookup_page(struct gasket_page_table *page_table, 149 ulong dev_addr, struct page **page, 150 ulong *poffset); 151 152 /* 153 * Checks validity for input addrs and size. 154 * @page_table: Gasket page table pointer. 155 * @host_addr: Host address to check. 156 * @dev_addr: Gasket device address. 157 * @bytes: Size of the range to check (in bytes). 158 * 159 * Description: This call performs a number of checks to verify that the ranges 160 * specified by both addresses and the size are valid for mapping pages into 161 * device memory. 162 * 163 * Returns true if the mapping is bad, false otherwise. 164 */ 165 bool gasket_page_table_are_addrs_bad(struct gasket_page_table *page_table, 166 ulong host_addr, ulong dev_addr, 167 ulong bytes); 168 169 /* 170 * Checks validity for input dev addr and size. 171 * @page_table: Gasket page table pointer. 172 * @dev_addr: Gasket device address. 173 * @bytes: Size of the range to check (in bytes). 174 * 175 * Description: This call performs a number of checks to verify that the range 176 * specified by the device address and the size is valid for mapping pages into 177 * device memory. 178 * 179 * Returns true if the address is bad, false otherwise. 180 */ 181 bool gasket_page_table_is_dev_addr_bad(struct gasket_page_table *page_table, 182 ulong dev_addr, ulong bytes); 183 184 /* 185 * Gets maximum size for the given page table. 186 * @page_table: Gasket page table pointer. 187 */ 188 uint gasket_page_table_max_size(struct gasket_page_table *page_table); 189 190 /* 191 * Gets the total number of entries in the arg. 192 * @page_table: Gasket page table pointer. 193 */ 194 uint gasket_page_table_num_entries(struct gasket_page_table *page_table); 195 196 /* 197 * Gets the number of simple entries. 198 * @page_table: Gasket page table pointer. 199 */ 200 uint gasket_page_table_num_simple_entries(struct gasket_page_table *page_table); 201 202 /* 203 * Gets the number of actively pinned pages. 204 * @page_table: Gasket page table pointer. 205 */ 206 uint gasket_page_table_num_active_pages(struct gasket_page_table *page_table); 207 208 /* 209 * Get status of page table managed by @page_table. 210 * @page_table: Gasket page table pointer. 211 */ 212 int gasket_page_table_system_status(struct gasket_page_table *page_table); 213 214 /* 215 * Allocate a block of coherent memory. 216 * @gasket_dev: Gasket Device. 217 * @size: Size of the memory block. 218 * @dma_address: Dma address allocated by the kernel. 219 * @index: Index of the gasket_page_table within this Gasket device 220 * 221 * Description: Allocate a contiguous coherent memory block, DMA'ble 222 * by this device. 223 */ 224 int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, uint64_t size, 225 dma_addr_t *dma_address, uint64_t index); 226 /* Release a block of contiguous coherent memory, in use by a device. */ 227 int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, uint64_t size, 228 dma_addr_t dma_address, uint64_t index); 229 230 /* Release all coherent memory. */ 231 void gasket_free_coherent_memory_all(struct gasket_dev *gasket_dev, 232 uint64_t index); 233 234 /* 235 * Records the host_addr to coherent dma memory mapping. 236 * @gasket_dev: Gasket Device. 237 * @size: Size of the virtual address range to map. 238 * @dma_address: Dma address within the coherent memory range. 239 * @vma: Virtual address we wish to map to coherent memory. 240 * 241 * Description: For each page in the virtual address range, record the 242 * coherent page mapping. 243 * 244 * Does not perform validity checking. 245 */ 246 int gasket_set_user_virt(struct gasket_dev *gasket_dev, uint64_t size, 247 dma_addr_t dma_address, ulong vma); 248 249 #endif /* __GASKET_PAGE_TABLE_H__ */