2018-07-14 15:46:54 +08:00
/* SPDX-License-Identifier: GPL-2.0 */
/*
2020-07-24 09:49:25 +08:00
* pasid . h - PASID idr , table and entry header
2018-07-14 15:46:54 +08:00
*
* Copyright ( C ) 2018 Intel Corporation
*
* Author : Lu Baolu < baolu . lu @ linux . intel . com >
*/
# ifndef __INTEL_PASID_H
# define __INTEL_PASID_H
2018-12-10 09:58:56 +08:00
# define PASID_MAX 0x100000
# define PASID_PTE_MASK 0x3F
# define PASID_PTE_PRESENT 1
2020-05-16 14:20:57 +08:00
# define PASID_PTE_FPD 2
2018-12-10 09:58:56 +08:00
# define PDE_PFN_MASK PAGE_MASK
# define PASID_PDE_SHIFT 6
2018-12-10 09:59:03 +08:00
# define MAX_NR_PASID_BITS 20
2019-05-24 16:40:16 -07:00
# define PASID_TBL_ENTRIES BIT(PASID_PDE_SHIFT)
# define is_pasid_enabled(entry) (((entry)->lo >> 3) & 0x1)
# define get_pasid_dir_size(entry) (1 << ((((entry)->lo >> 9) & 0x7) + 7))
2018-07-14 15:46:54 +08:00
2018-12-10 09:58:59 +08:00
/*
* Domain ID reserved for pasid entries programmed for first - level
* only and pass - through transfer modes .
*/
# define FLPT_DEFAULT_DID 1
2022-07-12 08:08:53 +08:00
# define NUM_RESERVED_DID 2
2018-12-10 09:58:59 +08:00
2020-05-16 14:20:46 +08:00
# define PASID_FLAG_NESTED BIT(1)
2021-03-30 10:11:45 +08:00
# define PASID_FLAG_PAGE_SNOOP BIT(2)
2018-12-10 09:59:04 +08:00
2020-01-02 08:18:16 +08:00
/*
* The PASID_FLAG_FL5LP flag Indicates using 5 - level paging for first -
* level translation , otherwise , 4 - level paging will be used .
*/
# define PASID_FLAG_FL5LP BIT(1)
2018-12-10 09:58:56 +08:00
struct pasid_dir_entry {
2018-07-14 15:46:59 +08:00
u64 val ;
} ;
2018-12-10 09:58:56 +08:00
struct pasid_entry {
u64 val [ 8 ] ;
} ;
2020-05-16 14:20:46 +08:00
# define PASID_ENTRY_PGTT_FL_ONLY (1)
# define PASID_ENTRY_PGTT_SL_ONLY (2)
# define PASID_ENTRY_PGTT_NESTED (3)
# define PASID_ENTRY_PGTT_PT (4)
2018-07-14 15:46:59 +08:00
/* The representative of a PASID table */
struct pasid_table {
void * table ; /* pasid table pointer */
int order ; /* page order of pasid table */
2020-09-15 09:30:05 -07:00
u32 max_pasid ; /* max pasid */
2018-07-14 15:46:59 +08:00
} ;
2019-05-24 16:40:16 -07:00
/* Get PRESENT bit of a PASID directory entry. */
static inline bool pasid_pde_is_present ( struct pasid_dir_entry * pde )
{
return READ_ONCE ( pde - > val ) & PASID_PTE_PRESENT ;
}
/* Get PASID table from a PASID directory entry. */
static inline struct pasid_entry *
get_pasid_table_from_pde ( struct pasid_dir_entry * pde )
{
if ( ! pasid_pde_is_present ( pde ) )
return NULL ;
return phys_to_virt ( READ_ONCE ( pde - > val ) & PDE_PFN_MASK ) ;
}
/* Get PRESENT bit of a PASID table entry. */
static inline bool pasid_pte_is_present ( struct pasid_entry * pte )
{
return READ_ONCE ( pte - > val [ 0 ] ) & PASID_PTE_PRESENT ;
}
2021-08-17 20:43:21 +08:00
/* Get PGTT field of a PASID table entry */
static inline u16 pasid_pte_get_pgtt ( struct pasid_entry * pte )
{
return ( u16 ) ( ( READ_ONCE ( pte - > val [ 0 ] ) > > 6 ) & 0x7 ) ;
}
2020-09-15 09:30:05 -07:00
extern unsigned int intel_pasid_max_id ;
2018-07-14 15:46:59 +08:00
int intel_pasid_alloc_table ( struct device * dev ) ;
void intel_pasid_free_table ( struct device * dev ) ;
struct pasid_table * intel_pasid_get_table ( struct device * dev ) ;
2018-12-10 09:59:04 +08:00
int intel_pasid_setup_first_level ( struct intel_iommu * iommu ,
struct device * dev , pgd_t * pgd ,
2020-09-15 09:30:05 -07:00
u32 pasid , u16 did , int flags ) ;
2018-12-10 09:59:00 +08:00
int intel_pasid_setup_second_level ( struct intel_iommu * iommu ,
struct dmar_domain * domain ,
2020-09-15 09:30:05 -07:00
struct device * dev , u32 pasid ) ;
2023-10-24 14:51:03 +01:00
int intel_pasid_setup_dirty_tracking ( struct intel_iommu * iommu ,
struct dmar_domain * domain ,
struct device * dev , u32 pasid ,
bool enabled ) ;
2018-12-10 09:59:00 +08:00
int intel_pasid_setup_pass_through ( struct intel_iommu * iommu ,
2020-09-15 09:30:05 -07:00
struct device * dev , u32 pasid ) ;
2023-10-25 21:42:12 -07:00
int intel_pasid_setup_nested ( struct intel_iommu * iommu , struct device * dev ,
u32 pasid , struct dmar_domain * domain ) ;
2018-12-10 09:59:00 +08:00
void intel_pasid_tear_down_entry ( struct intel_iommu * iommu ,
2020-09-15 09:30:05 -07:00
struct device * dev , u32 pasid ,
2020-05-16 14:20:57 +08:00
bool fault_ignore ) ;
2022-05-10 10:34:05 +08:00
void intel_pasid_setup_page_snoop_control ( struct intel_iommu * iommu ,
struct device * dev , u32 pasid ) ;
2018-07-14 15:46:54 +08:00
# endif /* __INTEL_PASID_H */