xref: /openbmc/linux/drivers/gpu/drm/i915/gvt/gtt.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
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  
37  #include <linux/kernel.h>
38  #include <linux/kref.h>
39  #include <linux/mutex.h>
40  #include <linux/radix-tree.h>
41  
42  #include "gt/intel_gtt.h"
43  
44  struct intel_gvt;
45  struct intel_vgpu;
46  struct intel_vgpu_mm;
47  
48  #define I915_GTT_PAGE_SHIFT         12
49  
50  #define INTEL_GVT_INVALID_ADDR (~0UL)
51  
52  struct intel_gvt_gtt_entry {
53  	u64 val64;
54  	int type;
55  };
56  
57  struct intel_gvt_gtt_pte_ops {
58  	int (*get_entry)(void *pt,
59  			 struct intel_gvt_gtt_entry *e,
60  			 unsigned long index,
61  			 bool hypervisor_access,
62  			 unsigned long gpa,
63  			 struct intel_vgpu *vgpu);
64  	int (*set_entry)(void *pt,
65  			 struct intel_gvt_gtt_entry *e,
66  			 unsigned long index,
67  			 bool hypervisor_access,
68  			 unsigned long gpa,
69  			 struct intel_vgpu *vgpu);
70  	bool (*test_present)(struct intel_gvt_gtt_entry *e);
71  	void (*clear_present)(struct intel_gvt_gtt_entry *e);
72  	void (*set_present)(struct intel_gvt_gtt_entry *e);
73  	bool (*test_pse)(struct intel_gvt_gtt_entry *e);
74  	void (*clear_pse)(struct intel_gvt_gtt_entry *e);
75  	bool (*test_ips)(struct intel_gvt_gtt_entry *e);
76  	void (*clear_ips)(struct intel_gvt_gtt_entry *e);
77  	bool (*test_64k_splited)(struct intel_gvt_gtt_entry *e);
78  	void (*clear_64k_splited)(struct intel_gvt_gtt_entry *e);
79  	void (*set_64k_splited)(struct intel_gvt_gtt_entry *e);
80  	void (*set_pfn)(struct intel_gvt_gtt_entry *e, unsigned long pfn);
81  	unsigned long (*get_pfn)(struct intel_gvt_gtt_entry *e);
82  };
83  
84  struct intel_gvt_gtt_gma_ops {
85  	unsigned long (*gma_to_ggtt_pte_index)(unsigned long gma);
86  	unsigned long (*gma_to_pte_index)(unsigned long gma);
87  	unsigned long (*gma_to_pde_index)(unsigned long gma);
88  	unsigned long (*gma_to_l3_pdp_index)(unsigned long gma);
89  	unsigned long (*gma_to_l4_pdp_index)(unsigned long gma);
90  	unsigned long (*gma_to_pml4_index)(unsigned long gma);
91  };
92  
93  struct intel_gvt_gtt {
94  	const struct intel_gvt_gtt_pte_ops *pte_ops;
95  	const struct intel_gvt_gtt_gma_ops *gma_ops;
96  	int (*mm_alloc_page_table)(struct intel_vgpu_mm *mm);
97  	void (*mm_free_page_table)(struct intel_vgpu_mm *mm);
98  	struct list_head oos_page_use_list_head;
99  	struct list_head oos_page_free_list_head;
100  	struct mutex ppgtt_mm_lock;
101  	struct list_head ppgtt_mm_lru_list_head;
102  
103  	struct page *scratch_page;
104  	unsigned long scratch_mfn;
105  };
106  
107  enum intel_gvt_gtt_type {
108  	GTT_TYPE_INVALID = 0,
109  
110  	GTT_TYPE_GGTT_PTE,
111  
112  	GTT_TYPE_PPGTT_PTE_4K_ENTRY,
113  	GTT_TYPE_PPGTT_PTE_64K_ENTRY,
114  	GTT_TYPE_PPGTT_PTE_2M_ENTRY,
115  	GTT_TYPE_PPGTT_PTE_1G_ENTRY,
116  
117  	GTT_TYPE_PPGTT_PTE_ENTRY,
118  
119  	GTT_TYPE_PPGTT_PDE_ENTRY,
120  	GTT_TYPE_PPGTT_PDP_ENTRY,
121  	GTT_TYPE_PPGTT_PML4_ENTRY,
122  
123  	GTT_TYPE_PPGTT_ROOT_ENTRY,
124  
125  	GTT_TYPE_PPGTT_ROOT_L3_ENTRY,
126  	GTT_TYPE_PPGTT_ROOT_L4_ENTRY,
127  
128  	GTT_TYPE_PPGTT_ENTRY,
129  
130  	GTT_TYPE_PPGTT_PTE_PT,
131  	GTT_TYPE_PPGTT_PDE_PT,
132  	GTT_TYPE_PPGTT_PDP_PT,
133  	GTT_TYPE_PPGTT_PML4_PT,
134  
135  	GTT_TYPE_MAX,
136  };
137  
138  enum intel_gvt_mm_type {
139  	INTEL_GVT_MM_GGTT,
140  	INTEL_GVT_MM_PPGTT,
141  };
142  
143  #define GVT_RING_CTX_NR_PDPS	GEN8_3LVL_PDPES
144  
145  struct intel_gvt_partial_pte {
146  	unsigned long offset;
147  	u64 data;
148  	struct list_head list;
149  };
150  
151  struct intel_vgpu_mm {
152  	enum intel_gvt_mm_type type;
153  	struct intel_vgpu *vgpu;
154  
155  	struct kref ref;
156  	atomic_t pincount;
157  
158  	union {
159  		struct {
160  			enum intel_gvt_gtt_type root_entry_type;
161  			/*
162  			 * The 4 PDPs in ring context. For 48bit addressing,
163  			 * only PDP0 is valid and point to PML4. For 32it
164  			 * addressing, all 4 are used as true PDPs.
165  			 */
166  			u64 guest_pdps[GVT_RING_CTX_NR_PDPS];
167  			u64 shadow_pdps[GVT_RING_CTX_NR_PDPS];
168  			bool shadowed;
169  
170  			struct list_head list;
171  			struct list_head lru_list;
172  			struct list_head link; /* possible LRI shadow mm list */
173  		} ppgtt_mm;
174  		struct {
175  			void *virtual_ggtt;
176  			/* Save/restore for PM */
177  			u64 *host_ggtt_aperture;
178  			u64 *host_ggtt_hidden;
179  			struct list_head partial_pte_list;
180  		} ggtt_mm;
181  	};
182  };
183  
184  struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu,
185  		enum intel_gvt_gtt_type root_entry_type, u64 pdps[]);
186  
intel_vgpu_mm_get(struct intel_vgpu_mm * mm)187  static inline void intel_vgpu_mm_get(struct intel_vgpu_mm *mm)
188  {
189  	kref_get(&mm->ref);
190  }
191  
192  void _intel_vgpu_mm_release(struct kref *mm_ref);
193  
intel_vgpu_mm_put(struct intel_vgpu_mm * mm)194  static inline void intel_vgpu_mm_put(struct intel_vgpu_mm *mm)
195  {
196  	kref_put(&mm->ref, _intel_vgpu_mm_release);
197  }
198  
intel_vgpu_destroy_mm(struct intel_vgpu_mm * mm)199  static inline void intel_vgpu_destroy_mm(struct intel_vgpu_mm *mm)
200  {
201  	intel_vgpu_mm_put(mm);
202  }
203  
204  struct intel_vgpu_guest_page;
205  
206  struct intel_vgpu_scratch_pt {
207  	struct page *page;
208  	unsigned long page_mfn;
209  };
210  
211  struct intel_vgpu_gtt {
212  	struct intel_vgpu_mm *ggtt_mm;
213  	unsigned long active_ppgtt_mm_bitmap;
214  	struct list_head ppgtt_mm_list_head;
215  	struct radix_tree_root spt_tree;
216  	struct list_head oos_page_list_head;
217  	struct list_head post_shadow_list_head;
218  	struct intel_vgpu_scratch_pt scratch_pt[GTT_TYPE_MAX];
219  };
220  
221  int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
222  void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
223  void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old);
224  void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);
225  
226  int intel_gvt_init_gtt(struct intel_gvt *gvt);
227  void intel_gvt_clean_gtt(struct intel_gvt *gvt);
228  
229  struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu,
230  					      int page_table_level,
231  					      void *root_entry);
232  
233  struct intel_vgpu_oos_page {
234  	struct intel_vgpu_ppgtt_spt *spt;
235  	struct list_head list;
236  	struct list_head vm_list;
237  	int id;
238  	void *mem;
239  };
240  
241  #define GTT_ENTRY_NUM_IN_ONE_PAGE 512
242  
243  /* Represent a vgpu shadow page table. */
244  struct intel_vgpu_ppgtt_spt {
245  	atomic_t refcount;
246  	struct intel_vgpu *vgpu;
247  
248  	struct {
249  		enum intel_gvt_gtt_type type;
250  		bool pde_ips; /* for 64KB PTEs */
251  		void *vaddr;
252  		struct page *page;
253  		unsigned long mfn;
254  	} shadow_page;
255  
256  	struct {
257  		enum intel_gvt_gtt_type type;
258  		bool pde_ips; /* for 64KB PTEs */
259  		unsigned long gfn;
260  		unsigned long write_cnt;
261  		struct intel_vgpu_oos_page *oos_page;
262  	} guest_page;
263  
264  	DECLARE_BITMAP(post_shadow_bitmap, GTT_ENTRY_NUM_IN_ONE_PAGE);
265  	struct list_head post_shadow_list;
266  };
267  
268  int intel_vgpu_sync_oos_pages(struct intel_vgpu *vgpu);
269  
270  int intel_vgpu_flush_post_shadow(struct intel_vgpu *vgpu);
271  
272  int intel_vgpu_pin_mm(struct intel_vgpu_mm *mm);
273  
274  void intel_vgpu_unpin_mm(struct intel_vgpu_mm *mm);
275  
276  unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm,
277  		unsigned long gma);
278  
279  struct intel_vgpu_mm *intel_vgpu_find_ppgtt_mm(struct intel_vgpu *vgpu,
280  		u64 pdps[]);
281  
282  struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu,
283  		enum intel_gvt_gtt_type root_entry_type, u64 pdps[]);
284  
285  int intel_vgpu_put_ppgtt_mm(struct intel_vgpu *vgpu, u64 pdps[]);
286  
287  int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu,
288  	unsigned int off, void *p_data, unsigned int bytes);
289  
290  int intel_vgpu_emulate_ggtt_mmio_write(struct intel_vgpu *vgpu,
291  	unsigned int off, void *p_data, unsigned int bytes);
292  
293  void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu);
294  void intel_gvt_restore_ggtt(struct intel_gvt *gvt);
295  
296  #endif /* _GVT_GTT_H_ */
297