49
49
#define CTX_ENTRY_LOWER_SLPTPTR_MASK \
50
50
(0xFFFFFFFFFFFFFUL << CTX_ENTRY_LOWER_SLPTPTR_POS)
51
51
52
- #define DMAR_GET_BITSLICE (var , bitname ) \
53
- ((var & bitname ## _MASK) >> bitname ## _POS)
52
+ static inline uint64_t
53
+ dmar_get_bitslice (uint64_t var , uint64_t mask , uint32_t pos )
54
+ {
55
+ return ((var & mask ) >> pos );
56
+ }
54
57
55
- #define DMAR_SET_BITSLICE (var , bitname , val ) \
56
- ((var & \
57
- ~bitname ## _MASK) | ((val << bitname ## _POS) & bitname ## _MASK))
58
+ static inline uint64_t
59
+ dmar_set_bitslice (uint64_t var , uint64_t mask ,
60
+ uint32_t pos , uint64_t val )
61
+ {
62
+ return ((var & ~mask ) | ((val << pos ) & mask ));
63
+ }
58
64
59
65
/* translation type */
60
66
#define DMAR_CTX_TT_UNTRANSLATED 0x0UL
@@ -973,7 +979,9 @@ static int add_iommu_device(struct iommu_domain *domain, uint16_t segment,
973
979
974
980
root_entry = (struct dmar_root_entry * )& root_table [bus * 2 ];
975
981
976
- if (DMAR_GET_BITSLICE (root_entry -> lower , ROOT_ENTRY_LOWER_PRESENT ) == 0U ) {
982
+ if (dmar_get_bitslice (root_entry -> lower ,
983
+ ROOT_ENTRY_LOWER_PRESENT_MASK ,
984
+ ROOT_ENTRY_LOWER_PRESENT_POS ) == 0UL ) {
977
985
void * vaddr = alloc_paging_struct ();
978
986
979
987
if (vaddr != NULL ) {
@@ -982,10 +990,13 @@ static int add_iommu_device(struct iommu_domain *domain, uint16_t segment,
982
990
983
991
context_table_addr = context_table_addr >> 12 ;
984
992
985
- lower = DMAR_SET_BITSLICE (lower , ROOT_ENTRY_LOWER_CTP ,
986
- context_table_addr );
987
- lower = DMAR_SET_BITSLICE (lower ,
988
- ROOT_ENTRY_LOWER_PRESENT , 1 );
993
+ lower = dmar_set_bitslice (lower ,
994
+ ROOT_ENTRY_LOWER_CTP_MASK ,
995
+ ROOT_ENTRY_LOWER_CTP_POS ,
996
+ context_table_addr );
997
+ lower = dmar_set_bitslice (lower ,
998
+ ROOT_ENTRY_LOWER_PRESENT_MASK ,
999
+ ROOT_ENTRY_LOWER_PRESENT_POS , 1UL );
989
1000
990
1001
root_entry -> upper = 0UL ;
991
1002
root_entry -> lower = lower ;
@@ -996,8 +1007,9 @@ static int add_iommu_device(struct iommu_domain *domain, uint16_t segment,
996
1007
return 1 ;
997
1008
}
998
1009
} else {
999
- context_table_addr = DMAR_GET_BITSLICE (root_entry -> lower ,
1000
- ROOT_ENTRY_LOWER_CTP );
1010
+ context_table_addr = dmar_get_bitslice (root_entry -> lower ,
1011
+ ROOT_ENTRY_LOWER_CTP_MASK ,
1012
+ ROOT_ENTRY_LOWER_CTP_POS );
1001
1013
}
1002
1014
1003
1015
context_table_addr = context_table_addr << 12 ;
@@ -1006,7 +1018,9 @@ static int add_iommu_device(struct iommu_domain *domain, uint16_t segment,
1006
1018
context_entry = (struct dmar_context_entry * )& context_table [devfun * 2 ];
1007
1019
1008
1020
/* the context entry should not be present */
1009
- if (DMAR_GET_BITSLICE (context_entry -> lower , CTX_ENTRY_LOWER_P ) != 0U ) {
1021
+ if (dmar_get_bitslice (context_entry -> lower ,
1022
+ CTX_ENTRY_LOWER_P_MASK ,
1023
+ CTX_ENTRY_LOWER_P_POS ) != 0UL ) {
1010
1024
pr_err ("%s: context entry@0x%llx (Lower:%x) " ,
1011
1025
__func__ , context_entry , context_entry -> lower );
1012
1026
pr_err ("already present for %x:%x.%x" ,
@@ -1024,28 +1038,42 @@ static int add_iommu_device(struct iommu_domain *domain, uint16_t segment,
1024
1038
* programmed to indicate the largest AGAW value
1025
1039
* supported by hardware.
1026
1040
*/
1027
- upper = DMAR_SET_BITSLICE (upper , CTX_ENTRY_UPPER_AW ,
1028
- dmar_uint -> cap_msagaw );
1029
- lower = DMAR_SET_BITSLICE (lower , CTX_ENTRY_LOWER_TT ,
1030
- DMAR_CTX_TT_PASSTHROUGH );
1041
+ upper = dmar_set_bitslice (upper ,
1042
+ CTX_ENTRY_UPPER_AW_MASK ,
1043
+ CTX_ENTRY_UPPER_AW_POS ,
1044
+ dmar_uint -> cap_msagaw );
1045
+ lower = dmar_set_bitslice (lower ,
1046
+ CTX_ENTRY_LOWER_TT_MASK ,
1047
+ CTX_ENTRY_LOWER_TT_POS ,
1048
+ DMAR_CTX_TT_PASSTHROUGH );
1031
1049
} else {
1032
1050
ASSERT (false,
1033
1051
"dmaru doesn't support trans passthrough" );
1034
1052
}
1035
1053
} else {
1036
1054
/* TODO: add Device TLB support */
1037
- upper =
1038
- DMAR_SET_BITSLICE (upper , CTX_ENTRY_UPPER_AW ,
1039
- width_to_agaw (
1040
- domain -> addr_width ));
1041
- lower = DMAR_SET_BITSLICE (lower , CTX_ENTRY_LOWER_TT ,
1042
- DMAR_CTX_TT_UNTRANSLATED );
1055
+ upper = dmar_set_bitslice (upper ,
1056
+ CTX_ENTRY_UPPER_AW_MASK ,
1057
+ CTX_ENTRY_UPPER_AW_POS ,
1058
+ (uint64_t )width_to_agaw (domain -> addr_width ));
1059
+ lower = dmar_set_bitslice (lower ,
1060
+ CTX_ENTRY_LOWER_TT_MASK ,
1061
+ CTX_ENTRY_LOWER_TT_POS ,
1062
+ DMAR_CTX_TT_UNTRANSLATED );
1043
1063
}
1044
1064
1045
- upper = DMAR_SET_BITSLICE (upper , CTX_ENTRY_UPPER_DID , domain -> dom_id );
1046
- lower = DMAR_SET_BITSLICE (lower , CTX_ENTRY_LOWER_SLPTPTR ,
1047
- domain -> trans_table_ptr >> 12 );
1048
- lower = DMAR_SET_BITSLICE (lower , CTX_ENTRY_LOWER_P , 1 );
1065
+ upper = dmar_set_bitslice (upper ,
1066
+ CTX_ENTRY_UPPER_DID_MASK ,
1067
+ CTX_ENTRY_UPPER_DID_POS ,
1068
+ domain -> dom_id );
1069
+ lower = dmar_set_bitslice (lower ,
1070
+ CTX_ENTRY_LOWER_SLPTPTR_MASK ,
1071
+ CTX_ENTRY_LOWER_SLPTPTR_POS ,
1072
+ domain -> trans_table_ptr >> 12U );
1073
+ lower = dmar_set_bitslice (lower ,
1074
+ CTX_ENTRY_LOWER_P_MASK ,
1075
+ CTX_ENTRY_LOWER_P_POS ,
1076
+ 1UL );
1049
1077
1050
1078
context_entry -> upper = upper ;
1051
1079
context_entry -> lower = lower ;
@@ -1065,6 +1093,7 @@ remove_iommu_device(struct iommu_domain *domain, uint16_t segment,
1065
1093
uint64_t * context_table ;
1066
1094
struct dmar_root_entry * root_entry ;
1067
1095
struct dmar_context_entry * context_entry ;
1096
+ uint16_t dom_id ;
1068
1097
1069
1098
if (domain == NULL ) {
1070
1099
return 1 ;
@@ -1080,15 +1109,17 @@ remove_iommu_device(struct iommu_domain *domain, uint16_t segment,
1080
1109
root_table = (uint64_t * )HPA2HVA (dmar_uint -> root_table_addr );
1081
1110
root_entry = (struct dmar_root_entry * )& root_table [bus * 2 ];
1082
1111
1083
- context_table_addr = DMAR_GET_BITSLICE (root_entry -> lower ,
1084
- ROOT_ENTRY_LOWER_CTP );
1112
+ context_table_addr = dmar_get_bitslice (root_entry -> lower ,
1113
+ ROOT_ENTRY_LOWER_CTP_MASK ,
1114
+ ROOT_ENTRY_LOWER_CTP_POS );
1085
1115
context_table_addr = context_table_addr << 12 ;
1086
1116
context_table = (uint64_t * )HPA2HVA (context_table_addr );
1087
1117
1088
1118
context_entry = (struct dmar_context_entry * )& context_table [devfun * 2 ];
1089
1119
1090
- if (DMAR_GET_BITSLICE (context_entry -> upper ,
1091
- CTX_ENTRY_UPPER_DID ) != domain -> dom_id ) {
1120
+ dom_id = (uint16_t )dmar_get_bitslice (context_entry -> upper ,
1121
+ CTX_ENTRY_UPPER_DID_MASK , CTX_ENTRY_UPPER_DID_POS );
1122
+ if (dom_id != domain -> dom_id ) {
1092
1123
pr_err ("%s: domain id mismatch" , __func__ );
1093
1124
return 1 ;
1094
1125
}
0 commit comments