2018-07-14 10:46:54 +03:00
/* SPDX-License-Identifier: GPL-2.0 */
/*
2020-07-24 04:49:25 +03:00
* pasid . h - PASID idr , table and entry header
2018-07-14 10:46:54 +03: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 04:59:01 +03:00
# define PASID_RID2PASID 0x0
2018-07-14 10:46:54 +03:00
# define PASID_MIN 0x1
2018-12-10 04:58:56 +03:00
# define PASID_MAX 0x100000
# define PASID_PTE_MASK 0x3F
# define PASID_PTE_PRESENT 1
2020-05-16 09:20:57 +03:00
# define PASID_PTE_FPD 2
2018-12-10 04:58:56 +03:00
# define PDE_PFN_MASK PAGE_MASK
# define PASID_PDE_SHIFT 6
2018-12-10 04:59:03 +03:00
# define MAX_NR_PASID_BITS 20
2019-05-25 02:40:16 +03: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 10:46:54 +03:00
2020-05-16 09:20:50 +03:00
/* Virtual command interface for enlightened pasid management. */
# define VCMD_CMD_ALLOC 0x1
# define VCMD_CMD_FREE 0x2
# define VCMD_VRSP_IP 0x1
# define VCMD_VRSP_SC(e) (((e) >> 1) & 0x3)
# define VCMD_VRSP_SC_SUCCESS 0
2021-02-27 10:39:09 +03:00
# define VCMD_VRSP_SC_NO_PASID_AVAIL 2
# define VCMD_VRSP_SC_INVALID_PASID 2
2020-05-16 09:20:50 +03:00
# define VCMD_VRSP_RESULT_PASID(e) (((e) >> 8) & 0xfffff)
# define VCMD_CMD_OPERAND(e) ((e) << 8)
2018-12-10 04:58:59 +03:00
/*
* Domain ID reserved for pasid entries programmed for first - level
* only and pass - through transfer modes .
*/
# define FLPT_DEFAULT_DID 1
2018-12-10 04:59:04 +03:00
/*
* The SUPERVISOR_MODE flag indicates a first level translation which
* can be used for access to kernel addresses . It is valid only for
* access to the kernel ' s static 1 : 1 mapping of physical memory — not
* to vmalloc or even module mappings .
*/
# define PASID_FLAG_SUPERVISOR_MODE BIT(0)
2020-05-16 09:20:46 +03:00
# define PASID_FLAG_NESTED BIT(1)
2018-12-10 04:59:04 +03:00
2020-01-02 03:18:16 +03: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 04:58:56 +03:00
struct pasid_dir_entry {
2018-07-14 10:46:59 +03:00
u64 val ;
} ;
2018-12-10 04:58:56 +03:00
struct pasid_entry {
u64 val [ 8 ] ;
} ;
2020-05-16 09:20:46 +03: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 10:46:59 +03: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 19:30:05 +03:00
u32 max_pasid ; /* max pasid */
2018-07-14 10:46:59 +03:00
struct list_head dev ; /* device list */
} ;
2019-05-25 02:40:16 +03: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 ;
}
2020-09-15 19:30:05 +03:00
extern unsigned int intel_pasid_max_id ;
2018-07-14 10:46:59 +03: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 04:59:04 +03:00
int intel_pasid_setup_first_level ( struct intel_iommu * iommu ,
struct device * dev , pgd_t * pgd ,
2020-09-15 19:30:05 +03:00
u32 pasid , u16 did , int flags ) ;
2018-12-10 04:59:00 +03:00
int intel_pasid_setup_second_level ( struct intel_iommu * iommu ,
struct dmar_domain * domain ,
2020-09-15 19:30:05 +03:00
struct device * dev , u32 pasid ) ;
2018-12-10 04:59:00 +03:00
int intel_pasid_setup_pass_through ( struct intel_iommu * iommu ,
struct dmar_domain * domain ,
2020-09-15 19:30:05 +03:00
struct device * dev , u32 pasid ) ;
2020-05-16 09:20:46 +03:00
int intel_pasid_setup_nested ( struct intel_iommu * iommu ,
2020-09-15 19:30:05 +03:00
struct device * dev , pgd_t * pgd , u32 pasid ,
2020-05-16 09:20:46 +03:00
struct iommu_gpasid_bind_data_vtd * pasid_data ,
struct dmar_domain * domain , int addr_width ) ;
2018-12-10 04:59:00 +03:00
void intel_pasid_tear_down_entry ( struct intel_iommu * iommu ,
2020-09-15 19:30:05 +03:00
struct device * dev , u32 pasid ,
2020-05-16 09:20:57 +03:00
bool fault_ignore ) ;
2020-09-15 19:30:05 +03:00
int vcmd_alloc_pasid ( struct intel_iommu * iommu , u32 * pasid ) ;
void vcmd_free_pasid ( struct intel_iommu * iommu , u32 pasid ) ;
2018-07-14 10:46:54 +03:00
# endif /* __INTEL_PASID_H */