@@ -85,6 +85,8 @@ static void set_dte_entry(struct amd_iommu *iommu,
85
85
86
86
static void iommu_flush_dte_sync (struct amd_iommu * iommu , u16 devid );
87
87
88
+ static struct iommu_dev_data * find_dev_data (struct amd_iommu * iommu , u16 devid );
89
+
88
90
/****************************************************************************
89
91
*
90
92
* Helper functions
@@ -202,6 +204,21 @@ static void update_dte256(struct amd_iommu *iommu, struct iommu_dev_data *dev_da
202
204
spin_unlock_irqrestore (& dev_data -> dte_lock , flags );
203
205
}
204
206
207
+ static void get_dte256 (struct amd_iommu * iommu , struct iommu_dev_data * dev_data ,
208
+ struct dev_table_entry * dte )
209
+ {
210
+ unsigned long flags ;
211
+ struct dev_table_entry * ptr ;
212
+ struct dev_table_entry * dev_table = get_dev_table (iommu );
213
+
214
+ ptr = & dev_table [dev_data -> devid ];
215
+
216
+ spin_lock_irqsave (& dev_data -> dte_lock , flags );
217
+ dte -> data128 [0 ] = ptr -> data128 [0 ];
218
+ dte -> data128 [1 ] = ptr -> data128 [1 ];
219
+ spin_unlock_irqrestore (& dev_data -> dte_lock , flags );
220
+ }
221
+
205
222
static inline bool pdom_is_v2_pgtbl_mode (struct protection_domain * pdom )
206
223
{
207
224
return (pdom && (pdom -> pd_mode == PD_MODE_V2 ));
@@ -350,9 +367,11 @@ static struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid
350
367
351
368
static int clone_alias (struct pci_dev * pdev , u16 alias , void * data )
352
369
{
370
+ struct dev_table_entry new ;
353
371
struct amd_iommu * iommu ;
354
- struct dev_table_entry * dev_table ;
372
+ struct iommu_dev_data * dev_data , * alias_data ;
355
373
u16 devid = pci_dev_id (pdev );
374
+ int ret = 0 ;
356
375
357
376
if (devid == alias )
358
377
return 0 ;
@@ -361,13 +380,27 @@ static int clone_alias(struct pci_dev *pdev, u16 alias, void *data)
361
380
if (!iommu )
362
381
return 0 ;
363
382
364
- amd_iommu_set_rlookup_table (iommu , alias );
365
- dev_table = get_dev_table (iommu );
366
- memcpy (dev_table [alias ].data ,
367
- dev_table [devid ].data ,
368
- sizeof (dev_table [alias ].data ));
383
+ /* Copy the data from pdev */
384
+ dev_data = dev_iommu_priv_get (& pdev -> dev );
385
+ if (!dev_data ) {
386
+ pr_err ("%s : Failed to get dev_data for 0x%x\n" , __func__ , devid );
387
+ ret = - EINVAL ;
388
+ goto out ;
389
+ }
390
+ get_dte256 (iommu , dev_data , & new );
369
391
370
- return 0 ;
392
+ /* Setup alias */
393
+ alias_data = find_dev_data (iommu , alias );
394
+ if (!alias_data ) {
395
+ pr_err ("%s : Failed to get alias dev_data for 0x%x\n" , __func__ , alias );
396
+ ret = - EINVAL ;
397
+ goto out ;
398
+ }
399
+ update_dte256 (iommu , alias_data , & new );
400
+
401
+ amd_iommu_set_rlookup_table (iommu , alias );
402
+ out :
403
+ return ret ;
371
404
}
372
405
373
406
static void clone_aliases (struct amd_iommu * iommu , struct device * dev )
@@ -640,6 +673,12 @@ static int iommu_init_device(struct amd_iommu *iommu, struct device *dev)
640
673
return - ENOMEM ;
641
674
642
675
dev_data -> dev = dev ;
676
+
677
+ /*
678
+ * The dev_iommu_priv_set() needes to be called before setup_aliases.
679
+ * Otherwise, subsequent call to dev_iommu_priv_get() will fail.
680
+ */
681
+ dev_iommu_priv_set (dev , dev_data );
643
682
setup_aliases (iommu , dev );
644
683
645
684
/*
@@ -653,8 +692,6 @@ static int iommu_init_device(struct amd_iommu *iommu, struct device *dev)
653
692
dev_data -> flags = pdev_get_caps (to_pci_dev (dev ));
654
693
}
655
694
656
- dev_iommu_priv_set (dev , dev_data );
657
-
658
695
return 0 ;
659
696
}
660
697
@@ -685,10 +722,13 @@ static void iommu_ignore_device(struct amd_iommu *iommu, struct device *dev)
685
722
static void dump_dte_entry (struct amd_iommu * iommu , u16 devid )
686
723
{
687
724
int i ;
688
- struct dev_table_entry * dev_table = get_dev_table (iommu );
725
+ struct dev_table_entry dte ;
726
+ struct iommu_dev_data * dev_data = find_dev_data (iommu , devid );
727
+
728
+ get_dte256 (iommu , dev_data , & dte );
689
729
690
730
for (i = 0 ; i < 4 ; ++ i )
691
- pr_err ("DTE[%d]: %016llx\n" , i , dev_table [ devid ] .data [i ]);
731
+ pr_err ("DTE[%d]: %016llx\n" , i , dte .data [i ]);
692
732
}
693
733
694
734
static void dump_command (unsigned long phys_addr )
0 commit comments