2016-03-28 23:23:16 +08:00
/*
* Copyright ( c ) 2011 - 2016 Intel Corporation . All rights reserved .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
*
* Authors :
* Zhi Wang < zhi . a . wang @ intel . com >
* Zhenyu Wang < zhenyuw @ linux . intel . com >
* Xiao Zheng < xiao . zheng @ intel . com >
*
* Contributors :
* Min He < min . he @ intel . com >
* Bing Niu < bing . niu @ intel . com >
*
*/
# ifndef _GVT_GTT_H_
# define _GVT_GTT_H_
2017-10-10 13:51:32 +08:00
# define I915_GTT_PAGE_SHIFT 12
2016-03-28 23:23:16 +08:00
struct intel_vgpu_mm ;
# define INTEL_GVT_INVALID_ADDR (~0UL)
struct intel_gvt_gtt_entry {
u64 val64 ;
int type ;
} ;
struct intel_gvt_gtt_pte_ops {
2017-08-02 15:06:37 +08:00
int ( * get_entry ) ( void * pt ,
struct intel_gvt_gtt_entry * e ,
unsigned long index ,
bool hypervisor_access ,
unsigned long gpa ,
struct intel_vgpu * vgpu ) ;
int ( * set_entry ) ( void * pt ,
struct intel_gvt_gtt_entry * e ,
unsigned long index ,
bool hypervisor_access ,
unsigned long gpa ,
struct intel_vgpu * vgpu ) ;
2016-03-28 23:23:16 +08:00
bool ( * test_present ) ( struct intel_gvt_gtt_entry * e ) ;
void ( * clear_present ) ( struct intel_gvt_gtt_entry * e ) ;
2017-10-10 17:24:26 +08:00
void ( * set_present ) ( struct intel_gvt_gtt_entry * e ) ;
2016-03-28 23:23:16 +08:00
bool ( * test_pse ) ( struct intel_gvt_gtt_entry * e ) ;
2018-05-15 10:35:38 +08:00
void ( * clear_pse ) ( struct intel_gvt_gtt_entry * e ) ;
2018-05-15 10:35:34 +08:00
bool ( * test_ips ) ( struct intel_gvt_gtt_entry * e ) ;
void ( * clear_ips ) ( struct intel_gvt_gtt_entry * e ) ;
2018-05-15 10:35:37 +08:00
bool ( * test_64k_splited ) ( struct intel_gvt_gtt_entry * e ) ;
void ( * clear_64k_splited ) ( struct intel_gvt_gtt_entry * e ) ;
void ( * set_64k_splited ) ( struct intel_gvt_gtt_entry * e ) ;
2016-03-28 23:23:16 +08:00
void ( * set_pfn ) ( struct intel_gvt_gtt_entry * e , unsigned long pfn ) ;
unsigned long ( * get_pfn ) ( struct intel_gvt_gtt_entry * e ) ;
} ;
struct intel_gvt_gtt_gma_ops {
unsigned long ( * gma_to_ggtt_pte_index ) ( unsigned long gma ) ;
unsigned long ( * gma_to_pte_index ) ( unsigned long gma ) ;
unsigned long ( * gma_to_pde_index ) ( unsigned long gma ) ;
unsigned long ( * gma_to_l3_pdp_index ) ( unsigned long gma ) ;
unsigned long ( * gma_to_l4_pdp_index ) ( unsigned long gma ) ;
unsigned long ( * gma_to_pml4_index ) ( unsigned long gma ) ;
} ;
struct intel_gvt_gtt {
struct intel_gvt_gtt_pte_ops * pte_ops ;
struct intel_gvt_gtt_gma_ops * gma_ops ;
int ( * mm_alloc_page_table ) ( struct intel_vgpu_mm * mm ) ;
void ( * mm_free_page_table ) ( struct intel_vgpu_mm * mm ) ;
struct list_head oos_page_use_list_head ;
struct list_head oos_page_free_list_head ;
2019-03-01 15:04:13 +08:00
struct mutex ppgtt_mm_lock ;
2018-01-30 19:19:40 +08:00
struct list_head ppgtt_mm_lru_list_head ;
2016-12-08 10:14:48 +08:00
2017-10-10 14:34:11 +08:00
struct page * scratch_page ;
unsigned long scratch_mfn ;
2016-03-28 23:23:16 +08:00
} ;
2019-04-23 15:04:08 +03:00
enum intel_gvt_gtt_type {
GTT_TYPE_INVALID = 0 ,
2016-11-04 13:47:35 +08:00
GTT_TYPE_GGTT_PTE ,
GTT_TYPE_PPGTT_PTE_4K_ENTRY ,
2018-05-15 10:35:33 +08:00
GTT_TYPE_PPGTT_PTE_64K_ENTRY ,
2016-11-04 13:47:35 +08:00
GTT_TYPE_PPGTT_PTE_2M_ENTRY ,
GTT_TYPE_PPGTT_PTE_1G_ENTRY ,
GTT_TYPE_PPGTT_PTE_ENTRY ,
GTT_TYPE_PPGTT_PDE_ENTRY ,
GTT_TYPE_PPGTT_PDP_ENTRY ,
GTT_TYPE_PPGTT_PML4_ENTRY ,
GTT_TYPE_PPGTT_ROOT_ENTRY ,
GTT_TYPE_PPGTT_ROOT_L3_ENTRY ,
GTT_TYPE_PPGTT_ROOT_L4_ENTRY ,
GTT_TYPE_PPGTT_ENTRY ,
GTT_TYPE_PPGTT_PTE_PT ,
GTT_TYPE_PPGTT_PDE_PT ,
GTT_TYPE_PPGTT_PDP_PT ,
GTT_TYPE_PPGTT_PML4_PT ,
GTT_TYPE_MAX ,
2019-04-23 15:04:08 +03:00
} ;
2016-11-04 13:47:35 +08:00
2018-01-30 19:19:40 +08:00
enum intel_gvt_mm_type {
INTEL_GVT_MM_GGTT ,
INTEL_GVT_MM_PPGTT ,
} ;
2016-03-28 23:23:16 +08:00
2018-01-30 19:19:40 +08:00
# define GVT_RING_CTX_NR_PDPS GEN8_3LVL_PDPES
2016-03-28 23:23:16 +08:00
2018-09-19 14:42:10 +08:00
struct intel_gvt_partial_pte {
unsigned long offset ;
u64 data ;
struct list_head list ;
} ;
2018-01-30 19:19:40 +08:00
struct intel_vgpu_mm {
enum intel_gvt_mm_type type ;
struct intel_vgpu * vgpu ;
2016-03-28 23:23:16 +08:00
struct kref ref ;
atomic_t pincount ;
2018-01-30 19:19:40 +08:00
union {
struct {
2019-04-23 15:04:08 +03:00
enum intel_gvt_gtt_type root_entry_type ;
2018-01-30 19:19:40 +08:00
/*
* The 4 PDPs in ring context . For 48 bit addressing ,
* only PDP0 is valid and point to PML4 . For 32 it
* addressing , all 4 are used as true PDPs .
*/
u64 guest_pdps [ GVT_RING_CTX_NR_PDPS ] ;
u64 shadow_pdps [ GVT_RING_CTX_NR_PDPS ] ;
bool shadowed ;
struct list_head list ;
struct list_head lru_list ;
2020-05-08 11:14:09 +08:00
struct list_head link ; /* possible LRI shadow mm list */
2018-01-30 19:19:40 +08:00
} ppgtt_mm ;
struct {
void * virtual_ggtt ;
2018-09-19 14:42:10 +08:00
struct list_head partial_pte_list ;
2018-01-30 19:19:40 +08:00
} ggtt_mm ;
} ;
2016-03-28 23:23:16 +08:00
} ;
2018-01-30 19:19:40 +08:00
struct intel_vgpu_mm * intel_vgpu_create_ppgtt_mm ( struct intel_vgpu * vgpu ,
2019-04-23 15:04:08 +03:00
enum intel_gvt_gtt_type root_entry_type , u64 pdps [ ] ) ;
2018-01-30 19:19:41 +08:00
static inline void intel_vgpu_mm_get ( struct intel_vgpu_mm * mm )
{
kref_get ( & mm - > ref ) ;
}
void _intel_vgpu_mm_release ( struct kref * mm_ref ) ;
static inline void intel_vgpu_mm_put ( struct intel_vgpu_mm * mm )
{
kref_put ( & mm - > ref , _intel_vgpu_mm_release ) ;
}
static inline void intel_vgpu_destroy_mm ( struct intel_vgpu_mm * mm )
{
intel_vgpu_mm_put ( mm ) ;
}
2016-03-28 23:23:16 +08:00
struct intel_vgpu_guest_page ;
2017-11-02 17:44:52 +08:00
struct intel_vgpu_scratch_pt {
2016-11-04 13:47:35 +08:00
struct page * page ;
2017-11-02 17:44:52 +08:00
unsigned long page_mfn ;
2016-11-04 13:47:35 +08:00
} ;
2016-03-28 23:23:16 +08:00
struct intel_vgpu_gtt {
struct intel_vgpu_mm * ggtt_mm ;
unsigned long active_ppgtt_mm_bitmap ;
2018-01-30 19:19:40 +08:00
struct list_head ppgtt_mm_list_head ;
2018-01-30 19:19:54 +08:00
struct radix_tree_root spt_tree ;
2016-03-28 23:23:16 +08:00
struct list_head oos_page_list_head ;
struct list_head post_shadow_list_head ;
2017-11-02 17:44:52 +08:00
struct intel_vgpu_scratch_pt scratch_pt [ GTT_TYPE_MAX ] ;
2016-03-28 23:23:16 +08:00
} ;
2019-07-12 13:24:25 +02:00
int intel_vgpu_init_gtt ( struct intel_vgpu * vgpu ) ;
void intel_vgpu_clean_gtt ( struct intel_vgpu * vgpu ) ;
2018-03-27 15:35:15 +08:00
void intel_vgpu_reset_ggtt ( struct intel_vgpu * vgpu , bool invalidate_old ) ;
2018-02-07 18:12:14 +08:00
void intel_vgpu_invalidate_ppgtt ( struct intel_vgpu * vgpu ) ;
2016-03-28 23:23:16 +08:00
2019-07-12 13:24:25 +02:00
int intel_gvt_init_gtt ( struct intel_gvt * gvt ) ;
2017-08-04 13:08:59 +08:00
void intel_vgpu_reset_gtt ( struct intel_vgpu * vgpu ) ;
2019-07-12 13:24:25 +02:00
void intel_gvt_clean_gtt ( struct intel_gvt * gvt ) ;
2016-03-28 23:23:16 +08:00
2019-07-12 13:24:25 +02:00
struct intel_vgpu_mm * intel_gvt_find_ppgtt_mm ( struct intel_vgpu * vgpu ,
int page_table_level ,
void * root_entry ) ;
2016-03-28 23:23:16 +08:00
struct intel_vgpu_oos_page {
2018-01-30 19:19:49 +08:00
struct intel_vgpu_ppgtt_spt * spt ;
2016-03-28 23:23:16 +08:00
struct list_head list ;
struct list_head vm_list ;
int id ;
2019-02-20 12:07:45 +08:00
void * mem ;
2016-03-28 23:23:16 +08:00
} ;
# define GTT_ENTRY_NUM_IN_ONE_PAGE 512
2018-01-30 19:19:49 +08:00
/* Represent a vgpu shadow page table. */
2016-03-28 23:23:16 +08:00
struct intel_vgpu_ppgtt_spt {
atomic_t refcount ;
struct intel_vgpu * vgpu ;
2018-01-30 19:19:49 +08:00
struct {
2019-04-23 15:04:08 +03:00
enum intel_gvt_gtt_type type ;
2018-05-15 10:35:36 +08:00
bool pde_ips ; /* for 64KB PTEs */
2018-01-30 19:19:49 +08:00
void * vaddr ;
struct page * page ;
unsigned long mfn ;
} shadow_page ;
struct {
2019-04-23 15:04:08 +03:00
enum intel_gvt_gtt_type type ;
2018-05-15 10:35:36 +08:00
bool pde_ips ; /* for 64KB PTEs */
2018-01-30 19:19:49 +08:00
unsigned long gfn ;
unsigned long write_cnt ;
struct intel_vgpu_oos_page * oos_page ;
} guest_page ;
2016-03-28 23:23:16 +08:00
DECLARE_BITMAP ( post_shadow_bitmap , GTT_ENTRY_NUM_IN_ONE_PAGE ) ;
struct list_head post_shadow_list ;
} ;
int intel_vgpu_sync_oos_pages ( struct intel_vgpu * vgpu ) ;
int intel_vgpu_flush_post_shadow ( struct intel_vgpu * vgpu ) ;
int intel_vgpu_pin_mm ( struct intel_vgpu_mm * mm ) ;
void intel_vgpu_unpin_mm ( struct intel_vgpu_mm * mm ) ;
unsigned long intel_vgpu_gma_to_gpa ( struct intel_vgpu_mm * mm ,
unsigned long gma ) ;
struct intel_vgpu_mm * intel_vgpu_find_ppgtt_mm ( struct intel_vgpu * vgpu ,
2018-01-30 19:19:40 +08:00
u64 pdps [ ] ) ;
2016-03-28 23:23:16 +08:00
2018-01-30 19:19:46 +08:00
struct intel_vgpu_mm * intel_vgpu_get_ppgtt_mm ( struct intel_vgpu * vgpu ,
2019-04-23 15:04:08 +03:00
enum intel_gvt_gtt_type root_entry_type , u64 pdps [ ] ) ;
2016-03-28 23:23:16 +08:00
2018-01-30 19:19:46 +08:00
int intel_vgpu_put_ppgtt_mm ( struct intel_vgpu * vgpu , u64 pdps [ ] ) ;
2016-03-28 23:23:16 +08:00
2018-01-30 19:19:45 +08:00
int intel_vgpu_emulate_ggtt_mmio_read ( struct intel_vgpu * vgpu ,
2016-03-28 23:23:16 +08:00
unsigned int off , void * p_data , unsigned int bytes ) ;
2018-01-30 19:19:45 +08:00
int intel_vgpu_emulate_ggtt_mmio_write ( struct intel_vgpu * vgpu ,
2016-03-28 23:23:16 +08:00
unsigned int off , void * p_data , unsigned int bytes ) ;
# endif /* _GVT_GTT_H_ */