@@ -36,6 +36,16 @@ struct s390_domain {
36
36
37
37
static struct iommu_domain blocking_domain ;
38
38
39
+ static inline unsigned int calc_rfx (dma_addr_t ptr )
40
+ {
41
+ return ((unsigned long )ptr >> ZPCI_RF_SHIFT ) & ZPCI_INDEX_MASK ;
42
+ }
43
+
44
+ static inline unsigned int calc_rsx (dma_addr_t ptr )
45
+ {
46
+ return ((unsigned long )ptr >> ZPCI_RS_SHIFT ) & ZPCI_INDEX_MASK ;
47
+ }
48
+
39
49
static inline unsigned int calc_rtx (dma_addr_t ptr )
40
50
{
41
51
return ((unsigned long )ptr >> ZPCI_RT_SHIFT ) & ZPCI_INDEX_MASK ;
@@ -759,6 +769,51 @@ static int s390_iommu_map_pages(struct iommu_domain *domain,
759
769
return rc ;
760
770
}
761
771
772
+ static unsigned long * get_rso_from_iova (struct s390_domain * domain ,
773
+ dma_addr_t iova )
774
+ {
775
+ unsigned long * rfo ;
776
+ unsigned long rfe ;
777
+ unsigned int rfx ;
778
+
779
+ switch (domain -> origin_type ) {
780
+ case ZPCI_TABLE_TYPE_RFX :
781
+ rfo = domain -> dma_table ;
782
+ rfx = calc_rfx (iova );
783
+ rfe = READ_ONCE (rfo [rfx ]);
784
+ if (!reg_entry_isvalid (rfe ))
785
+ return NULL ;
786
+ return get_rf_rso (rfe );
787
+ case ZPCI_TABLE_TYPE_RSX :
788
+ return domain -> dma_table ;
789
+ default :
790
+ return NULL ;
791
+ }
792
+ }
793
+
794
+ static unsigned long * get_rto_from_iova (struct s390_domain * domain ,
795
+ dma_addr_t iova )
796
+ {
797
+ unsigned long * rso ;
798
+ unsigned long rse ;
799
+ unsigned int rsx ;
800
+
801
+ switch (domain -> origin_type ) {
802
+ case ZPCI_TABLE_TYPE_RFX :
803
+ case ZPCI_TABLE_TYPE_RSX :
804
+ rso = get_rso_from_iova (domain , iova );
805
+ rsx = calc_rsx (iova );
806
+ rse = READ_ONCE (rso [rsx ]);
807
+ if (!reg_entry_isvalid (rse ))
808
+ return NULL ;
809
+ return get_rs_rto (rse );
810
+ case ZPCI_TABLE_TYPE_RTX :
811
+ return domain -> dma_table ;
812
+ default :
813
+ return NULL ;
814
+ }
815
+ }
816
+
762
817
static phys_addr_t s390_iommu_iova_to_phys (struct iommu_domain * domain ,
763
818
dma_addr_t iova )
764
819
{
@@ -772,10 +827,13 @@ static phys_addr_t s390_iommu_iova_to_phys(struct iommu_domain *domain,
772
827
iova > domain -> geometry .aperture_end )
773
828
return 0 ;
774
829
830
+ rto = get_rto_from_iova (s390_domain , iova );
831
+ if (!rto )
832
+ return 0 ;
833
+
775
834
rtx = calc_rtx (iova );
776
835
sx = calc_sx (iova );
777
836
px = calc_px (iova );
778
- rto = s390_domain -> dma_table ;
779
837
780
838
rte = READ_ONCE (rto [rtx ]);
781
839
if (reg_entry_isvalid (rte )) {
0 commit comments