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#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
  44struct intel_gvt;
  45struct intel_vgpu;
  46struct intel_vgpu_mm;
  47
  48#define I915_GTT_PAGE_SHIFT         12
  49
  50#define INTEL_GVT_INVALID_ADDR (~0UL)
  51
  52struct intel_gvt_gtt_entry {
  53        u64 val64;
  54        int type;
  55};
  56
  57struct 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
  84struct 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
  93struct intel_gvt_gtt {
  94        struct intel_gvt_gtt_pte_ops *pte_ops;
  95        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
 107enum 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
 138enum 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
 145struct intel_gvt_partial_pte {
 146        unsigned long offset;
 147        u64 data;
 148        struct list_head list;
 149};
 150
 151struct 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
 184struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu,
 185                enum intel_gvt_gtt_type root_entry_type, u64 pdps[]);
 186
 187static inline void intel_vgpu_mm_get(struct intel_vgpu_mm *mm)
 188{
 189        kref_get(&mm->ref);
 190}
 191
 192void _intel_vgpu_mm_release(struct kref *mm_ref);
 193
 194static inline void intel_vgpu_mm_put(struct intel_vgpu_mm *mm)
 195{
 196        kref_put(&mm->ref, _intel_vgpu_mm_release);
 197}
 198
 199static inline void intel_vgpu_destroy_mm(struct intel_vgpu_mm *mm)
 200{
 201        intel_vgpu_mm_put(mm);
 202}
 203
 204struct intel_vgpu_guest_page;
 205
 206struct intel_vgpu_scratch_pt {
 207        struct page *page;
 208        unsigned long page_mfn;
 209};
 210
 211struct 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
 221int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
 222void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
 223void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old);
 224void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);
 225
 226int intel_gvt_init_gtt(struct intel_gvt *gvt);
 227void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu);
 228void intel_gvt_clean_gtt(struct intel_gvt *gvt);
 229
 230struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu,
 231                                              int page_table_level,
 232                                              void *root_entry);
 233
 234struct intel_vgpu_oos_page {
 235        struct intel_vgpu_ppgtt_spt *spt;
 236        struct list_head list;
 237        struct list_head vm_list;
 238        int id;
 239        void *mem;
 240};
 241
 242#define GTT_ENTRY_NUM_IN_ONE_PAGE 512
 243
 244/* Represent a vgpu shadow page table. */
 245struct intel_vgpu_ppgtt_spt {
 246        atomic_t refcount;
 247        struct intel_vgpu *vgpu;
 248
 249        struct {
 250                enum intel_gvt_gtt_type type;
 251                bool pde_ips; /* for 64KB PTEs */
 252                void *vaddr;
 253                struct page *page;
 254                unsigned long mfn;
 255        } shadow_page;
 256
 257        struct {
 258                enum intel_gvt_gtt_type type;
 259                bool pde_ips; /* for 64KB PTEs */
 260                unsigned long gfn;
 261                unsigned long write_cnt;
 262                struct intel_vgpu_oos_page *oos_page;
 263        } guest_page;
 264
 265        DECLARE_BITMAP(post_shadow_bitmap, GTT_ENTRY_NUM_IN_ONE_PAGE);
 266        struct list_head post_shadow_list;
 267};
 268
 269int intel_vgpu_sync_oos_pages(struct intel_vgpu *vgpu);
 270
 271int intel_vgpu_flush_post_shadow(struct intel_vgpu *vgpu);
 272
 273int intel_vgpu_pin_mm(struct intel_vgpu_mm *mm);
 274
 275void intel_vgpu_unpin_mm(struct intel_vgpu_mm *mm);
 276
 277unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm,
 278                unsigned long gma);
 279
 280struct intel_vgpu_mm *intel_vgpu_find_ppgtt_mm(struct intel_vgpu *vgpu,
 281                u64 pdps[]);
 282
 283struct intel_vgpu_mm *intel_vgpu_get_ppgtt_mm(struct intel_vgpu *vgpu,
 284                enum intel_gvt_gtt_type root_entry_type, u64 pdps[]);
 285
 286int intel_vgpu_put_ppgtt_mm(struct intel_vgpu *vgpu, u64 pdps[]);
 287
 288int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu,
 289        unsigned int off, void *p_data, unsigned int bytes);
 290
 291int intel_vgpu_emulate_ggtt_mmio_write(struct intel_vgpu *vgpu,
 292        unsigned int off, void *p_data, unsigned int bytes);
 293
 294void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu);
 295void intel_gvt_restore_ggtt(struct intel_gvt *gvt);
 296
 297#endif /* _GVT_GTT_H_ */
 298