Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.17-rc7 152 lines 4.6 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright © 2022 Intel Corporation 4 */ 5#ifndef __XE_PT_WALK__ 6#define __XE_PT_WALK__ 7 8#include <linux/pagewalk.h> 9#include <linux/types.h> 10 11/** 12 * struct xe_ptw - base class for driver pagetable subclassing. 13 * @children: Pointer to an array of children if any. 14 * @staging: Pointer to an array of staging if any. 15 * 16 * Drivers could subclass this, and if it's a page-directory, typically 17 * embed an array of xe_ptw pointers. 18 */ 19struct xe_ptw { 20 struct xe_ptw **children; 21 struct xe_ptw **staging; 22}; 23 24/** 25 * struct xe_pt_walk - Embeddable struct for walk parameters 26 */ 27struct xe_pt_walk { 28 /** @ops: The walk ops used for the pagewalk */ 29 const struct xe_pt_walk_ops *ops; 30 /** 31 * @shifts: Array of page-table entry shifts used for the 32 * different levels, starting out with the leaf level 0 33 * page-shift as the first entry. It's legal for this pointer to be 34 * changed during the walk. 35 */ 36 const u64 *shifts; 37 /** @max_level: Highest populated level in @sizes */ 38 unsigned int max_level; 39 /** 40 * @shared_pt_mode: Whether to skip all entries that are private 41 * to the address range and called only for entries that are 42 * shared with other address ranges. Such entries are referred to 43 * as shared pagetables. 44 */ 45 bool shared_pt_mode; 46 /** @staging: Walk staging PT structure */ 47 bool staging; 48}; 49 50/** 51 * typedef xe_pt_entry_fn - gpu page-table-walk callback-function 52 * @parent: The parent page.table. 53 * @offset: The offset (number of entries) into the page table. 54 * @level: The level of @parent. 55 * @addr: The virtual address. 56 * @next: The virtual address for the next call, or end address. 57 * @child: Pointer to pointer to child page-table at this @offset. The 58 * function may modify the value pointed to if, for example, allocating a 59 * child page table. 60 * @action: The walk action to take upon return. See <linux/pagewalk.h>. 61 * @walk: The walk parameters. 62 */ 63typedef int (*xe_pt_entry_fn)(struct xe_ptw *parent, pgoff_t offset, 64 unsigned int level, u64 addr, u64 next, 65 struct xe_ptw **child, 66 enum page_walk_action *action, 67 struct xe_pt_walk *walk); 68 69/** 70 * struct xe_pt_walk_ops - Walk callbacks. 71 */ 72struct xe_pt_walk_ops { 73 /** 74 * @pt_entry: Callback to be called for each page table entry prior 75 * to descending to the next level. The returned value of the action 76 * function parameter is honored. 77 */ 78 xe_pt_entry_fn pt_entry; 79 /** 80 * @pt_post_descend: Callback to be called for each page table entry 81 * after return from descending to the next level. The returned value 82 * of the action function parameter is ignored. 83 */ 84 xe_pt_entry_fn pt_post_descend; 85}; 86 87int xe_pt_walk_range(struct xe_ptw *parent, unsigned int level, 88 u64 addr, u64 end, struct xe_pt_walk *walk); 89 90int xe_pt_walk_shared(struct xe_ptw *parent, unsigned int level, 91 u64 addr, u64 end, struct xe_pt_walk *walk); 92 93/** 94 * xe_pt_covers - Whether the address range covers an entire entry in @level 95 * @addr: Start of the range. 96 * @end: End of range + 1. 97 * @level: Page table level. 98 * @walk: Page table walk info. 99 * 100 * This function is a helper to aid in determining whether a leaf page table 101 * entry can be inserted at this @level. 102 * 103 * Return: Whether the range provided covers exactly an entry at this level. 104 */ 105static inline bool xe_pt_covers(u64 addr, u64 end, unsigned int level, 106 const struct xe_pt_walk *walk) 107{ 108 u64 pt_size = 1ull << walk->shifts[level]; 109 110 return end - addr == pt_size && IS_ALIGNED(addr, pt_size); 111} 112 113/** 114 * xe_pt_num_entries: Number of page-table entries of a given range at this 115 * level 116 * @addr: Start address. 117 * @end: End address. 118 * @level: Page table level. 119 * @walk: Walk info. 120 * 121 * Return: The number of page table entries at this level between @start and 122 * @end. 123 */ 124static inline pgoff_t 125xe_pt_num_entries(u64 addr, u64 end, unsigned int level, 126 const struct xe_pt_walk *walk) 127{ 128 u64 pt_size = 1ull << walk->shifts[level]; 129 130 return (round_up(end, pt_size) - round_down(addr, pt_size)) >> 131 walk->shifts[level]; 132} 133 134/** 135 * xe_pt_offset: Offset of the page-table entry for a given address. 136 * @addr: The address. 137 * @level: Page table level. 138 * @walk: Walk info. 139 * 140 * Return: The page table entry offset for the given address in a 141 * page table with size indicated by @level. 142 */ 143static inline pgoff_t 144xe_pt_offset(u64 addr, unsigned int level, const struct xe_pt_walk *walk) 145{ 146 if (level < walk->max_level) 147 addr &= ((1ull << walk->shifts[level + 1]) - 1); 148 149 return addr >> walk->shifts[level]; 150} 151 152#endif