linux/drivers/gpu/drm/i915/gvt/gtt.h
<<
>>
Prefs
   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#define I915_GTT_PAGE_SHIFT         12
  38
  39struct intel_vgpu_mm;
  40
  41#define INTEL_GVT_INVALID_ADDR (~0UL)
  42
  43struct intel_gvt_gtt_entry {
  44        u64 val64;
  45        int type;
  46};
  47
  48struct intel_gvt_gtt_pte_ops {
  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);
  61        bool (*test_present)(struct intel_gvt_gtt_entry *e);
  62        void (*clear_present)(struct intel_gvt_gtt_entry *e);
  63        void (*set_present)(struct intel_gvt_gtt_entry *e);
  64        bool (*test_pse)(struct intel_gvt_gtt_entry *e);
  65        void (*clear_pse)(struct intel_gvt_gtt_entry *e);
  66        bool (*test_ips)(struct intel_gvt_gtt_entry *e);
  67        void (*clear_ips)(struct intel_gvt_gtt_entry *e);
  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);
  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
  75struct 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
  84struct 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;
  91        struct mutex ppgtt_mm_lock;
  92        struct list_head ppgtt_mm_lru_list_head;
  93
  94        struct page *scratch_page;
  95        unsigned long scratch_mfn;
  96};
  97
  98enum intel_gvt_gtt_type {
  99        GTT_TYPE_INVALID = 0,
 100
 101        GTT_TYPE_GGTT_PTE,
 102
 103        GTT_TYPE_PPGTT_PTE_4K_ENTRY,
 104        GTT_TYPE_PPGTT_PTE_64K_ENTRY,
 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,
 127};
 128
 129enum intel_gvt_mm_type {
 130        INTEL_GVT_MM_GGTT,
 131        INTEL_GVT_MM_PPGTT,
 132};
 133
 134#define GVT_RING_CTX_NR_PDPS    GEN8_3LVL_PDPES
 135
 136struct intel_gvt_partial_pte {
 137        unsigned long offset;
 138        u64 data;
 139        struct list_head list;
 140};
 141
 142struct intel_vgpu_mm {
 143        enum intel_gvt_mm_type type;
 144        struct intel_vgpu *vgpu;
 145
 146        struct kref ref;
 147        atomic_t pincount;
 148
 149        union {
 150                struct {
 151                        enum intel_gvt_gtt_type root_entry_type;
 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;
 166                        struct list_head partial_pte_list;
 167                } ggtt_mm;
 168        };
 169};
 170
 171struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu,
 172                enum intel_gvt_gtt_type root_entry_type, u64 pdps[]);
 173
 174static inline void intel_vgpu_mm_get(struct intel_vgpu_mm *mm)
 175{
 176        kref_get(&mm->ref);
 177}
 178
 179void _intel_vgpu_mm_release(struct kref *mm_ref);
 180
 181static inline void intel_vgpu_mm_put(struct intel_vgpu_mm *mm)
 182{
 183        kref_put(&mm->ref, _intel_vgpu_mm_release);
 184}
 185
 186static inline void intel_vgpu_destroy_mm(struct intel_vgpu_mm *mm)
 187{
 188        intel_vgpu_mm_put(mm);
 189}
 190
 191struct intel_vgpu_guest_page;
 192
 193struct intel_vgpu_scratch_pt {
 194        struct page *page;
 195        unsigned long page_mfn;
 196};
 197
 198struct intel_vgpu_gtt {
 199        struct intel_vgpu_mm *ggtt_mm;
 200        unsigned long active_ppgtt_mm_bitmap;
 201        struct list_head ppgtt_mm_list_head;
 202        struct radix_tree_root spt_tree;
 203        struct list_head oos_page_list_head;
 204        struct list_head post_shadow_list_head;
 205        struct intel_vgpu_scratch_pt scratch_pt[GTT_TYPE_MAX];
 206};
 207
 208extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
 209extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
 210void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old);
 211void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);
 212
 213extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
 214void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu);
 215extern void intel_gvt_clean_gtt(struct intel_gvt *gvt);
 216
 217extern struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu,
 218                int page_table_level, void *root_entry);
 219
 220struct intel_vgpu_oos_page {
 221        struct intel_vgpu_ppgtt_spt *spt;
 222        struct list_head list;
 223        struct list_head vm_list;
 224        int id;
 225        void *mem;
 226};
 227
 228#define GTT_ENTRY_NUM_IN_ONE_PAGE 512
 229
 230/* Represent a vgpu shadow page table. */
 231struct intel_vgpu_ppgtt_spt {
 232        atomic_t refcount;
 233        struct intel_vgpu *vgpu;
 234
 235        struct {
 236                enum intel_gvt_gtt_type type;
 237                bool pde_ips; /* for 64KB PTEs */
 238                void *vaddr;
 239                struct page *page;
 240                unsigned long mfn;
 241        } shadow_page;
 242
 243        struct {
 244                enum intel_gvt_gtt_type type;
 245                bool pde_ips; /* for 64KB PTEs */
 246                unsigned long gfn;
 247                unsigned long write_cnt;
 248                struct intel_vgpu_oos_page *oos_page;
 249        } guest_page;
 250
 251        DECLARE_BITMAP(post_shadow_bitmap, GTT_ENTRY_NUM_IN_ONE_PAGE);
 252        struct list_head post_shadow_list;
 253};
 254
 255int intel_vgpu_sync_oos_pages(struct intel_vgpu *vgpu);
 256
 257int intel_vgpu_flush_post_shadow(struct intel_vgpu *vgpu);
 258
 259int intel_vgpu_pin_mm(struct intel_vgpu_mm *mm);
 260
 261void intel_vgpu_unpin_mm(struct intel_vgpu_mm *mm);
 262
 263unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm,
 264                unsigned long gma);
 265
 266struct intel_vgpu_mm *intel_vgpu_find_ppgtt_mm(struct intel_vgpu *vgpu,
 267                u64 pdps[]);
 268
 269struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu,
 270                enum intel_gvt_gtt_type root_entry_type, u64 pdps[]);
 271
 272int intel_vgpu_put_ppgtt_mm(struct intel_vgpu *vgpu, u64 pdps[]);
 273
 274int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu,
 275        unsigned int off, void *p_data, unsigned int bytes);
 276
 277int intel_vgpu_emulate_ggtt_mmio_write(struct intel_vgpu *vgpu,
 278        unsigned int off, void *p_data, unsigned int bytes);
 279
 280#endif /* _GVT_GTT_H_ */
 281