]>
Commit | Line | Data |
---|---|---|
2707e444 ZW |
1 | /* |
2 | * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice (including the next | |
12 | * paragraph) shall be included in all copies or substantial portions of the | |
13 | * Software. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
21 | * SOFTWARE. | |
22 | * | |
23 | * Authors: | |
24 | * Zhi Wang <zhi.a.wang@intel.com> | |
25 | * Zhenyu Wang <zhenyuw@linux.intel.com> | |
26 | * Xiao Zheng <xiao.zheng@intel.com> | |
27 | * | |
28 | * Contributors: | |
29 | * Min He <min.he@intel.com> | |
30 | * Bing Niu <bing.niu@intel.com> | |
31 | * | |
32 | */ | |
33 | ||
34 | #ifndef _GVT_GTT_H_ | |
35 | #define _GVT_GTT_H_ | |
36 | ||
9556e118 | 37 | #define I915_GTT_PAGE_SHIFT 12 |
2707e444 ZW |
38 | |
39 | struct intel_vgpu_mm; | |
40 | ||
2707e444 ZW |
41 | #define INTEL_GVT_INVALID_ADDR (~0UL) |
42 | ||
43 | struct intel_gvt_gtt_entry { | |
44 | u64 val64; | |
45 | int type; | |
46 | }; | |
47 | ||
48 | struct intel_gvt_gtt_pte_ops { | |
4b2dbbc2 CD |
49 | int (*get_entry)(void *pt, |
50 | struct intel_gvt_gtt_entry *e, | |
51 | unsigned long index, | |
52 | bool hypervisor_access, | |
53 | unsigned long gpa, | |
54 | struct intel_vgpu *vgpu); | |
55 | int (*set_entry)(void *pt, | |
56 | struct intel_gvt_gtt_entry *e, | |
57 | unsigned long index, | |
58 | bool hypervisor_access, | |
59 | unsigned long gpa, | |
60 | struct intel_vgpu *vgpu); | |
2707e444 ZW |
61 | bool (*test_present)(struct intel_gvt_gtt_entry *e); |
62 | void (*clear_present)(struct intel_gvt_gtt_entry *e); | |
655c64ef | 63 | void (*set_present)(struct intel_gvt_gtt_entry *e); |
2707e444 | 64 | bool (*test_pse)(struct intel_gvt_gtt_entry *e); |
c3e69763 | 65 | void (*clear_pse)(struct intel_gvt_gtt_entry *e); |
6fd79378 CD |
66 | bool (*test_ips)(struct intel_gvt_gtt_entry *e); |
67 | void (*clear_ips)(struct intel_gvt_gtt_entry *e); | |
71634848 CD |
68 | bool (*test_64k_splited)(struct intel_gvt_gtt_entry *e); |
69 | void (*clear_64k_splited)(struct intel_gvt_gtt_entry *e); | |
70 | void (*set_64k_splited)(struct intel_gvt_gtt_entry *e); | |
2707e444 ZW |
71 | void (*set_pfn)(struct intel_gvt_gtt_entry *e, unsigned long pfn); |
72 | unsigned long (*get_pfn)(struct intel_gvt_gtt_entry *e); | |
73 | }; | |
74 | ||
75 | struct intel_gvt_gtt_gma_ops { | |
76 | unsigned long (*gma_to_ggtt_pte_index)(unsigned long gma); | |
77 | unsigned long (*gma_to_pte_index)(unsigned long gma); | |
78 | unsigned long (*gma_to_pde_index)(unsigned long gma); | |
79 | unsigned long (*gma_to_l3_pdp_index)(unsigned long gma); | |
80 | unsigned long (*gma_to_l4_pdp_index)(unsigned long gma); | |
81 | unsigned long (*gma_to_pml4_index)(unsigned long gma); | |
82 | }; | |
83 | ||
84 | struct intel_gvt_gtt { | |
85 | struct intel_gvt_gtt_pte_ops *pte_ops; | |
86 | struct intel_gvt_gtt_gma_ops *gma_ops; | |
87 | int (*mm_alloc_page_table)(struct intel_vgpu_mm *mm); | |
88 | void (*mm_free_page_table)(struct intel_vgpu_mm *mm); | |
89 | struct list_head oos_page_use_list_head; | |
90 | struct list_head oos_page_free_list_head; | |
72aabfb8 | 91 | struct mutex ppgtt_mm_lock; |
ede9d0cf | 92 | struct list_head ppgtt_mm_lru_list_head; |
d650ac06 | 93 | |
22115cef ZW |
94 | struct page *scratch_page; |
95 | unsigned long scratch_mfn; | |
2707e444 ZW |
96 | }; |
97 | ||
0cf8f58d AG |
98 | enum intel_gvt_gtt_type { |
99 | GTT_TYPE_INVALID = 0, | |
3b6411c2 PG |
100 | |
101 | GTT_TYPE_GGTT_PTE, | |
102 | ||
103 | GTT_TYPE_PPGTT_PTE_4K_ENTRY, | |
b294657d | 104 | GTT_TYPE_PPGTT_PTE_64K_ENTRY, |
3b6411c2 PG |
105 | GTT_TYPE_PPGTT_PTE_2M_ENTRY, |
106 | GTT_TYPE_PPGTT_PTE_1G_ENTRY, | |
107 | ||
108 | GTT_TYPE_PPGTT_PTE_ENTRY, | |
109 | ||
110 | GTT_TYPE_PPGTT_PDE_ENTRY, | |
111 | GTT_TYPE_PPGTT_PDP_ENTRY, | |
112 | GTT_TYPE_PPGTT_PML4_ENTRY, | |
113 | ||
114 | GTT_TYPE_PPGTT_ROOT_ENTRY, | |
115 | ||
116 | GTT_TYPE_PPGTT_ROOT_L3_ENTRY, | |
117 | GTT_TYPE_PPGTT_ROOT_L4_ENTRY, | |
118 | ||
119 | GTT_TYPE_PPGTT_ENTRY, | |
120 | ||
121 | GTT_TYPE_PPGTT_PTE_PT, | |
122 | GTT_TYPE_PPGTT_PDE_PT, | |
123 | GTT_TYPE_PPGTT_PDP_PT, | |
124 | GTT_TYPE_PPGTT_PML4_PT, | |
125 | ||
126 | GTT_TYPE_MAX, | |
0cf8f58d | 127 | }; |
3b6411c2 | 128 | |
ede9d0cf CD |
129 | enum intel_gvt_mm_type { |
130 | INTEL_GVT_MM_GGTT, | |
131 | INTEL_GVT_MM_PPGTT, | |
132 | }; | |
2707e444 | 133 | |
ede9d0cf | 134 | #define GVT_RING_CTX_NR_PDPS GEN8_3LVL_PDPES |
2707e444 | 135 | |
bc0686ff HY |
136 | struct intel_gvt_partial_pte { |
137 | unsigned long offset; | |
138 | u64 data; | |
139 | struct list_head list; | |
140 | }; | |
141 | ||
ede9d0cf CD |
142 | struct intel_vgpu_mm { |
143 | enum intel_gvt_mm_type type; | |
144 | struct intel_vgpu *vgpu; | |
2707e444 | 145 | |
2707e444 ZW |
146 | struct kref ref; |
147 | atomic_t pincount; | |
ede9d0cf CD |
148 | |
149 | union { | |
150 | struct { | |
0cf8f58d | 151 | enum intel_gvt_gtt_type root_entry_type; |
ede9d0cf CD |
152 | /* |
153 | * The 4 PDPs in ring context. For 48bit addressing, | |
154 | * only PDP0 is valid and point to PML4. For 32it | |
155 | * addressing, all 4 are used as true PDPs. | |
156 | */ | |
157 | u64 guest_pdps[GVT_RING_CTX_NR_PDPS]; | |
158 | u64 shadow_pdps[GVT_RING_CTX_NR_PDPS]; | |
159 | bool shadowed; | |
160 | ||
161 | struct list_head list; | |
162 | struct list_head lru_list; | |
163 | } ppgtt_mm; | |
164 | struct { | |
165 | void *virtual_ggtt; | |
bc0686ff | 166 | struct list_head partial_pte_list; |
ede9d0cf CD |
167 | } ggtt_mm; |
168 | }; | |
2707e444 ZW |
169 | }; |
170 | ||
ede9d0cf | 171 | struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu, |
0cf8f58d | 172 | enum intel_gvt_gtt_type root_entry_type, u64 pdps[]); |
1bc25851 CD |
173 | |
174 | static inline void intel_vgpu_mm_get(struct intel_vgpu_mm *mm) | |
175 | { | |
176 | kref_get(&mm->ref); | |
177 | } | |
178 | ||
179 | void _intel_vgpu_mm_release(struct kref *mm_ref); | |
180 | ||
181 | static inline void intel_vgpu_mm_put(struct intel_vgpu_mm *mm) | |
182 | { | |
183 | kref_put(&mm->ref, _intel_vgpu_mm_release); | |
184 | } | |
185 | ||
186 | static inline void intel_vgpu_destroy_mm(struct intel_vgpu_mm *mm) | |
187 | { | |
188 | intel_vgpu_mm_put(mm); | |
189 | } | |
2707e444 ZW |
190 | |
191 | struct intel_vgpu_guest_page; | |
192 | ||
5c35258d | 193 | struct intel_vgpu_scratch_pt { |
3b6411c2 | 194 | struct page *page; |
5c35258d | 195 | unsigned long page_mfn; |
3b6411c2 PG |
196 | }; |
197 | ||
2707e444 ZW |
198 | struct intel_vgpu_gtt { |
199 | struct intel_vgpu_mm *ggtt_mm; | |
200 | unsigned long active_ppgtt_mm_bitmap; | |
ede9d0cf | 201 | struct list_head ppgtt_mm_list_head; |
b6c126a3 | 202 | struct radix_tree_root spt_tree; |
2707e444 ZW |
203 | struct list_head oos_page_list_head; |
204 | struct list_head post_shadow_list_head; | |
5c35258d | 205 | struct intel_vgpu_scratch_pt scratch_pt[GTT_TYPE_MAX]; |
2707e444 ZW |
206 | }; |
207 | ||
208 | extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); | |
209 | extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu); | |
f4c43db3 | 210 | void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old); |
730c8ead | 211 | void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu); |
2707e444 ZW |
212 | |
213 | extern int intel_gvt_init_gtt(struct intel_gvt *gvt); | |
4d3e67bb | 214 | void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu); |
2707e444 ZW |
215 | extern void intel_gvt_clean_gtt(struct intel_gvt *gvt); |
216 | ||
217 | extern struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu, | |
218 | int page_table_level, void *root_entry); | |
219 | ||
2707e444 | 220 | struct intel_vgpu_oos_page { |
44b46733 | 221 | struct intel_vgpu_ppgtt_spt *spt; |
2707e444 ZW |
222 | struct list_head list; |
223 | struct list_head vm_list; | |
224 | int id; | |
ed47c5cb | 225 | void *mem; |
2707e444 ZW |
226 | }; |
227 | ||
228 | #define GTT_ENTRY_NUM_IN_ONE_PAGE 512 | |
229 | ||
44b46733 | 230 | /* Represent a vgpu shadow page table. */ |
2707e444 | 231 | struct intel_vgpu_ppgtt_spt { |
2707e444 ZW |
232 | atomic_t refcount; |
233 | struct intel_vgpu *vgpu; | |
44b46733 CD |
234 | |
235 | struct { | |
0cf8f58d | 236 | enum intel_gvt_gtt_type type; |
40b27176 | 237 | bool pde_ips; /* for 64KB PTEs */ |
44b46733 CD |
238 | void *vaddr; |
239 | struct page *page; | |
240 | unsigned long mfn; | |
241 | } shadow_page; | |
242 | ||
243 | struct { | |
0cf8f58d | 244 | enum intel_gvt_gtt_type type; |
40b27176 | 245 | bool pde_ips; /* for 64KB PTEs */ |
44b46733 CD |
246 | unsigned long gfn; |
247 | unsigned long write_cnt; | |
44b46733 CD |
248 | struct intel_vgpu_oos_page *oos_page; |
249 | } guest_page; | |
250 | ||
2707e444 ZW |
251 | DECLARE_BITMAP(post_shadow_bitmap, GTT_ENTRY_NUM_IN_ONE_PAGE); |
252 | struct list_head post_shadow_list; | |
253 | }; | |
254 | ||
2707e444 ZW |
255 | int intel_vgpu_sync_oos_pages(struct intel_vgpu *vgpu); |
256 | ||
257 | int intel_vgpu_flush_post_shadow(struct intel_vgpu *vgpu); | |
258 | ||
2707e444 ZW |
259 | int intel_vgpu_pin_mm(struct intel_vgpu_mm *mm); |
260 | ||
261 | void intel_vgpu_unpin_mm(struct intel_vgpu_mm *mm); | |
262 | ||
263 | unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, | |
264 | unsigned long gma); | |
265 | ||
266 | struct intel_vgpu_mm *intel_vgpu_find_ppgtt_mm(struct intel_vgpu *vgpu, | |
ede9d0cf | 267 | u64 pdps[]); |
2707e444 | 268 | |
e6e9c46f | 269 | struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu, |
0cf8f58d | 270 | enum intel_gvt_gtt_type root_entry_type, u64 pdps[]); |
2707e444 | 271 | |
e6e9c46f | 272 | int intel_vgpu_put_ppgtt_mm(struct intel_vgpu *vgpu, u64 pdps[]); |
2707e444 | 273 | |
a143cef7 | 274 | int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, |
2707e444 ZW |
275 | unsigned int off, void *p_data, unsigned int bytes); |
276 | ||
a143cef7 | 277 | int intel_vgpu_emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, |
2707e444 ZW |
278 | unsigned int off, void *p_data, unsigned int bytes); |
279 | ||
280 | #endif /* _GVT_GTT_H_ */ |