@@ -370,6 +370,15 @@ static inline bool pasid_get_ssade(struct pasid_entry *pe)
370
370
return pasid_get_bits (& pe -> val [0 ]) & (1 << 9 );
371
371
}
372
372
373
+ /*
374
+ * Setup the SRE(Supervisor Request Enable) field (Bit 128) of a
375
+ * scalable mode PASID entry.
376
+ */
377
+ static inline void pasid_set_sre (struct pasid_entry * pe )
378
+ {
379
+ pasid_set_bits (& pe -> val [2 ], 1 << 0 , 1 );
380
+ }
381
+
373
382
/*
374
383
* Setup the WPE(Write Protect Enable) field (Bit 132) of a
375
384
* scalable mode PASID entry.
@@ -437,6 +446,15 @@ pasid_set_flpm(struct pasid_entry *pe, u64 value)
437
446
pasid_set_bits (& pe -> val [2 ], GENMASK_ULL (3 , 2 ), value << 2 );
438
447
}
439
448
449
+ /*
450
+ * Setup the Extended Access Flag Enable (EAFE) field (Bit 135)
451
+ * of a scalable mode PASID entry.
452
+ */
453
+ static inline void pasid_set_eafe (struct pasid_entry * pe )
454
+ {
455
+ pasid_set_bits (& pe -> val [2 ], 1 << 7 , 1 << 7 );
456
+ }
457
+
440
458
static void
441
459
pasid_cache_invalidation_with_pasid (struct intel_iommu * iommu ,
442
460
u16 did , u32 pasid )
@@ -822,3 +840,97 @@ void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,
822
840
if (!cap_caching_mode (iommu -> cap ))
823
841
devtlb_invalidation_with_pasid (iommu , dev , pasid );
824
842
}
843
+
844
+ /**
845
+ * intel_pasid_setup_nested() - Set up PASID entry for nested translation.
846
+ * @iommu: IOMMU which the device belong to
847
+ * @dev: Device to be set up for translation
848
+ * @pasid: PASID to be programmed in the device PASID table
849
+ * @domain: User stage-1 domain nested on a stage-2 domain
850
+ *
851
+ * This is used for nested translation. The input domain should be
852
+ * nested type and nested on a parent with 'is_nested_parent' flag
853
+ * set.
854
+ */
855
+ int intel_pasid_setup_nested (struct intel_iommu * iommu , struct device * dev ,
856
+ u32 pasid , struct dmar_domain * domain )
857
+ {
858
+ struct iommu_hwpt_vtd_s1 * s1_cfg = & domain -> s1_cfg ;
859
+ pgd_t * s1_gpgd = (pgd_t * )(uintptr_t )domain -> s1_pgtbl ;
860
+ struct dmar_domain * s2_domain = domain -> s2_domain ;
861
+ u16 did = domain_id_iommu (domain , iommu );
862
+ struct dma_pte * pgd = s2_domain -> pgd ;
863
+ struct pasid_entry * pte ;
864
+
865
+ /* Address width should match the address width supported by hardware */
866
+ switch (s1_cfg -> addr_width ) {
867
+ case ADDR_WIDTH_4LEVEL :
868
+ break ;
869
+ case ADDR_WIDTH_5LEVEL :
870
+ if (!cap_fl5lp_support (iommu -> cap )) {
871
+ dev_err_ratelimited (dev ,
872
+ "5-level paging not supported\n" );
873
+ return - EINVAL ;
874
+ }
875
+ break ;
876
+ default :
877
+ dev_err_ratelimited (dev , "Invalid stage-1 address width %d\n" ,
878
+ s1_cfg -> addr_width );
879
+ return - EINVAL ;
880
+ }
881
+
882
+ if ((s1_cfg -> flags & IOMMU_VTD_S1_SRE ) && !ecap_srs (iommu -> ecap )) {
883
+ pr_err_ratelimited ("No supervisor request support on %s\n" ,
884
+ iommu -> name );
885
+ return - EINVAL ;
886
+ }
887
+
888
+ if ((s1_cfg -> flags & IOMMU_VTD_S1_EAFE ) && !ecap_eafs (iommu -> ecap )) {
889
+ pr_err_ratelimited ("No extended access flag support on %s\n" ,
890
+ iommu -> name );
891
+ return - EINVAL ;
892
+ }
893
+
894
+ spin_lock (& iommu -> lock );
895
+ pte = intel_pasid_get_entry (dev , pasid );
896
+ if (!pte ) {
897
+ spin_unlock (& iommu -> lock );
898
+ return - ENODEV ;
899
+ }
900
+ if (pasid_pte_is_present (pte )) {
901
+ spin_unlock (& iommu -> lock );
902
+ return - EBUSY ;
903
+ }
904
+
905
+ pasid_clear_entry (pte );
906
+
907
+ if (s1_cfg -> addr_width == ADDR_WIDTH_5LEVEL )
908
+ pasid_set_flpm (pte , 1 );
909
+
910
+ pasid_set_flptr (pte , (uintptr_t )s1_gpgd );
911
+
912
+ if (s1_cfg -> flags & IOMMU_VTD_S1_SRE ) {
913
+ pasid_set_sre (pte );
914
+ if (s1_cfg -> flags & IOMMU_VTD_S1_WPE )
915
+ pasid_set_wpe (pte );
916
+ }
917
+
918
+ if (s1_cfg -> flags & IOMMU_VTD_S1_EAFE )
919
+ pasid_set_eafe (pte );
920
+
921
+ if (s2_domain -> force_snooping )
922
+ pasid_set_pgsnp (pte );
923
+
924
+ pasid_set_slptr (pte , virt_to_phys (pgd ));
925
+ pasid_set_fault_enable (pte );
926
+ pasid_set_domain_id (pte , did );
927
+ pasid_set_address_width (pte , s2_domain -> agaw );
928
+ pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
929
+ pasid_set_translation_type (pte , PASID_ENTRY_PGTT_NESTED );
930
+ pasid_set_present (pte );
931
+ spin_unlock (& iommu -> lock );
932
+
933
+ pasid_flush_caches (iommu , pte , pasid , did );
934
+
935
+ return 0 ;
936
+ }
0 commit comments