Linux Audio

Check our new training course

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