@@ -174,8 +174,8 @@ bool amd_iommu_snp_en;
174
174
EXPORT_SYMBOL (amd_iommu_snp_en );
175
175
176
176
LIST_HEAD (amd_iommu_pci_seg_list ); /* list of all PCI segments */
177
- LIST_HEAD (amd_iommu_list ); /* list of all AMD IOMMUs in the
178
- system */
177
+ LIST_HEAD (amd_iommu_list ); /* list of all AMD IOMMUs in the system */
178
+ LIST_HEAD ( amd_ivhd_dev_flags_list ); /* list of all IVHD device entry settings */
179
179
180
180
/* Number of IOMMUs present in the system */
181
181
static int amd_iommus_present ;
@@ -984,6 +984,14 @@ static void iommu_enable_gt(struct amd_iommu *iommu)
984
984
}
985
985
986
986
/* sets a specific bit in the device table entry. */
987
+ static void set_dte_bit (struct dev_table_entry * dte , u8 bit )
988
+ {
989
+ int i = (bit >> 6 ) & 0x03 ;
990
+ int _bit = bit & 0x3f ;
991
+
992
+ dte -> data [i ] |= (1UL << _bit );
993
+ }
994
+
987
995
static void __set_dev_entry_bit (struct dev_table_entry * dev_table ,
988
996
u16 devid , u8 bit )
989
997
{
@@ -1136,6 +1144,19 @@ static bool copy_device_table(void)
1136
1144
return true;
1137
1145
}
1138
1146
1147
+ static bool search_ivhd_dte_flags (u16 segid , u16 first , u16 last )
1148
+ {
1149
+ struct ivhd_dte_flags * e ;
1150
+
1151
+ for_each_ivhd_dte_flags (e ) {
1152
+ if ((e -> segid == segid ) &&
1153
+ (e -> devid_first == first ) &&
1154
+ (e -> devid_last == last ))
1155
+ return true;
1156
+ }
1157
+ return false;
1158
+ }
1159
+
1139
1160
void amd_iommu_apply_erratum_63 (struct amd_iommu * iommu , u16 devid )
1140
1161
{
1141
1162
int sysmgt ;
@@ -1151,27 +1172,66 @@ void amd_iommu_apply_erratum_63(struct amd_iommu *iommu, u16 devid)
1151
1172
* This function takes the device specific flags read from the ACPI
1152
1173
* table and sets up the device table entry with that information
1153
1174
*/
1154
- static void __init set_dev_entry_from_acpi (struct amd_iommu * iommu ,
1155
- u16 devid , u32 flags , u32 ext_flags )
1175
+ static void __init
1176
+ set_dev_entry_from_acpi_range (struct amd_iommu * iommu , u16 first , u16 last ,
1177
+ u32 flags , u32 ext_flags )
1156
1178
{
1157
- if (flags & ACPI_DEVFLAG_INITPASS )
1158
- set_dev_entry_bit (iommu , devid , DEV_ENTRY_INIT_PASS );
1159
- if (flags & ACPI_DEVFLAG_EXTINT )
1160
- set_dev_entry_bit (iommu , devid , DEV_ENTRY_EINT_PASS );
1161
- if (flags & ACPI_DEVFLAG_NMI )
1162
- set_dev_entry_bit (iommu , devid , DEV_ENTRY_NMI_PASS );
1163
- if (flags & ACPI_DEVFLAG_SYSMGT1 )
1164
- set_dev_entry_bit (iommu , devid , DEV_ENTRY_SYSMGT1 );
1165
- if (flags & ACPI_DEVFLAG_SYSMGT2 )
1166
- set_dev_entry_bit (iommu , devid , DEV_ENTRY_SYSMGT2 );
1167
- if (flags & ACPI_DEVFLAG_LINT0 )
1168
- set_dev_entry_bit (iommu , devid , DEV_ENTRY_LINT0_PASS );
1169
- if (flags & ACPI_DEVFLAG_LINT1 )
1170
- set_dev_entry_bit (iommu , devid , DEV_ENTRY_LINT1_PASS );
1179
+ int i ;
1180
+ struct dev_table_entry dte = {};
1181
+
1182
+ /* Parse IVHD DTE setting flags and store information */
1183
+ if (flags ) {
1184
+ struct ivhd_dte_flags * d ;
1171
1185
1172
- amd_iommu_apply_erratum_63 (iommu , devid );
1186
+ if (search_ivhd_dte_flags (iommu -> pci_seg -> id , first , last ))
1187
+ return ;
1173
1188
1174
- amd_iommu_set_rlookup_table (iommu , devid );
1189
+ d = kzalloc (sizeof (struct ivhd_dte_flags ), GFP_KERNEL );
1190
+ if (!d )
1191
+ return ;
1192
+
1193
+ pr_debug ("%s: devid range %#x:%#x\n" , __func__ , first , last );
1194
+
1195
+ if (flags & ACPI_DEVFLAG_INITPASS )
1196
+ set_dte_bit (& dte , DEV_ENTRY_INIT_PASS );
1197
+ if (flags & ACPI_DEVFLAG_EXTINT )
1198
+ set_dte_bit (& dte , DEV_ENTRY_EINT_PASS );
1199
+ if (flags & ACPI_DEVFLAG_NMI )
1200
+ set_dte_bit (& dte , DEV_ENTRY_NMI_PASS );
1201
+ if (flags & ACPI_DEVFLAG_SYSMGT1 )
1202
+ set_dte_bit (& dte , DEV_ENTRY_SYSMGT1 );
1203
+ if (flags & ACPI_DEVFLAG_SYSMGT2 )
1204
+ set_dte_bit (& dte , DEV_ENTRY_SYSMGT2 );
1205
+ if (flags & ACPI_DEVFLAG_LINT0 )
1206
+ set_dte_bit (& dte , DEV_ENTRY_LINT0_PASS );
1207
+ if (flags & ACPI_DEVFLAG_LINT1 )
1208
+ set_dte_bit (& dte , DEV_ENTRY_LINT1_PASS );
1209
+
1210
+ /* Apply erratum 63, which needs info in initial_dte */
1211
+ if (FIELD_GET (DTE_DATA1_SYSMGT_MASK , dte .data [1 ]) == 0x1 )
1212
+ dte .data [0 ] |= DTE_FLAG_IW ;
1213
+
1214
+ memcpy (& d -> dte , & dte , sizeof (dte ));
1215
+ d -> segid = iommu -> pci_seg -> id ;
1216
+ d -> devid_first = first ;
1217
+ d -> devid_last = last ;
1218
+ list_add_tail (& d -> list , & amd_ivhd_dev_flags_list );
1219
+ }
1220
+
1221
+ for (i = first ; i <= last ; i ++ ) {
1222
+ if (flags ) {
1223
+ struct dev_table_entry * dev_table = get_dev_table (iommu );
1224
+
1225
+ memcpy (& dev_table [i ], & dte , sizeof (dte ));
1226
+ }
1227
+ amd_iommu_set_rlookup_table (iommu , i );
1228
+ }
1229
+ }
1230
+
1231
+ static void __init set_dev_entry_from_acpi (struct amd_iommu * iommu ,
1232
+ u16 devid , u32 flags , u32 ext_flags )
1233
+ {
1234
+ set_dev_entry_from_acpi_range (iommu , devid , devid , flags , ext_flags );
1175
1235
}
1176
1236
1177
1237
int __init add_special_device (u8 type , u8 id , u32 * devid , bool cmd_line )
@@ -1332,9 +1392,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
1332
1392
case IVHD_DEV_ALL :
1333
1393
1334
1394
DUMP_printk (" DEV_ALL\t\t\tsetting: %#02x\n" , e -> flags );
1335
-
1336
- for (dev_i = 0 ; dev_i <= pci_seg -> last_bdf ; ++ dev_i )
1337
- set_dev_entry_from_acpi (iommu , dev_i , e -> flags , 0 );
1395
+ set_dev_entry_from_acpi_range (iommu , 0 , pci_seg -> last_bdf , e -> flags , 0 );
1338
1396
break ;
1339
1397
case IVHD_DEV_SELECT :
1340
1398
@@ -1428,14 +1486,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
1428
1486
1429
1487
devid = e -> devid ;
1430
1488
for (dev_i = devid_start ; dev_i <= devid ; ++ dev_i ) {
1431
- if (alias ) {
1489
+ if (alias )
1432
1490
pci_seg -> alias_table [dev_i ] = devid_to ;
1433
- set_dev_entry_from_acpi (iommu ,
1434
- devid_to , flags , ext_flags );
1435
- }
1436
- set_dev_entry_from_acpi (iommu , dev_i ,
1437
- flags , ext_flags );
1438
1491
}
1492
+ set_dev_entry_from_acpi_range (iommu , devid_start , devid , flags , ext_flags );
1493
+ set_dev_entry_from_acpi (iommu , devid_to , flags , ext_flags );
1439
1494
break ;
1440
1495
case IVHD_DEV_SPECIAL : {
1441
1496
u8 handle , type ;
0 commit comments