@@ -324,6 +324,32 @@ static void intel_pasid_flush_present(struct intel_iommu *iommu,
324324 * Set up the scalable mode pasid table entry for first only
325325 * translation type.
326326 */
327+ static void pasid_pte_config_first_level (struct intel_iommu * iommu ,
328+ struct pasid_entry * pte ,
329+ pgd_t * pgd , u16 did , int flags )
330+ {
331+ lockdep_assert_held (& iommu -> lock );
332+
333+ pasid_clear_entry (pte );
334+
335+ /* Setup the first level page table pointer: */
336+ pasid_set_flptr (pte , (u64 )__pa (pgd ));
337+
338+ if (flags & PASID_FLAG_FL5LP )
339+ pasid_set_flpm (pte , 1 );
340+
341+ if (flags & PASID_FLAG_PAGE_SNOOP )
342+ pasid_set_pgsnp (pte );
343+
344+ pasid_set_domain_id (pte , did );
345+ pasid_set_address_width (pte , iommu -> agaw );
346+ pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
347+
348+ /* Setup Present and PASID Granular Transfer Type: */
349+ pasid_set_translation_type (pte , PASID_ENTRY_PGTT_FL_ONLY );
350+ pasid_set_present (pte );
351+ }
352+
327353int intel_pasid_setup_first_level (struct intel_iommu * iommu ,
328354 struct device * dev , pgd_t * pgd ,
329355 u32 pasid , u16 did , int flags )
@@ -354,24 +380,8 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
354380 return - EBUSY ;
355381 }
356382
357- pasid_clear_entry (pte );
358-
359- /* Setup the first level page table pointer: */
360- pasid_set_flptr (pte , (u64 )__pa (pgd ));
361-
362- if (flags & PASID_FLAG_FL5LP )
363- pasid_set_flpm (pte , 1 );
364-
365- if (flags & PASID_FLAG_PAGE_SNOOP )
366- pasid_set_pgsnp (pte );
367-
368- pasid_set_domain_id (pte , did );
369- pasid_set_address_width (pte , iommu -> agaw );
370- pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
383+ pasid_pte_config_first_level (iommu , pte , pgd , did , flags );
371384
372- /* Setup Present and PASID Granular Transfer Type: */
373- pasid_set_translation_type (pte , PASID_ENTRY_PGTT_FL_ONLY );
374- pasid_set_present (pte );
375385 spin_unlock (& iommu -> lock );
376386
377387 pasid_flush_caches (iommu , pte , pasid , did );
@@ -382,6 +392,26 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
382392/*
383393 * Set up the scalable mode pasid entry for second only translation type.
384394 */
395+ static void pasid_pte_config_second_level (struct intel_iommu * iommu ,
396+ struct pasid_entry * pte ,
397+ u64 pgd_val , int agaw , u16 did ,
398+ bool dirty_tracking )
399+ {
400+ lockdep_assert_held (& iommu -> lock );
401+
402+ pasid_clear_entry (pte );
403+ pasid_set_domain_id (pte , did );
404+ pasid_set_slptr (pte , pgd_val );
405+ pasid_set_address_width (pte , agaw );
406+ pasid_set_translation_type (pte , PASID_ENTRY_PGTT_SL_ONLY );
407+ pasid_set_fault_enable (pte );
408+ pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
409+ if (dirty_tracking )
410+ pasid_set_ssade (pte );
411+
412+ pasid_set_present (pte );
413+ }
414+
385415int intel_pasid_setup_second_level (struct intel_iommu * iommu ,
386416 struct dmar_domain * domain ,
387417 struct device * dev , u32 pasid )
@@ -417,17 +447,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
417447 return - EBUSY ;
418448 }
419449
420- pasid_clear_entry (pte );
421- pasid_set_domain_id (pte , did );
422- pasid_set_slptr (pte , pgd_val );
423- pasid_set_address_width (pte , domain -> agaw );
424- pasid_set_translation_type (pte , PASID_ENTRY_PGTT_SL_ONLY );
425- pasid_set_fault_enable (pte );
426- pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
427- if (domain -> dirty_tracking )
428- pasid_set_ssade (pte );
429-
430- pasid_set_present (pte );
450+ pasid_pte_config_second_level (iommu , pte , pgd_val , domain -> agaw ,
451+ did , domain -> dirty_tracking );
431452 spin_unlock (& iommu -> lock );
432453
433454 pasid_flush_caches (iommu , pte , pasid , did );
@@ -507,6 +528,20 @@ int intel_pasid_setup_dirty_tracking(struct intel_iommu *iommu,
507528/*
508529 * Set up the scalable mode pasid entry for passthrough translation type.
509530 */
531+ static void pasid_pte_config_pass_through (struct intel_iommu * iommu ,
532+ struct pasid_entry * pte , u16 did )
533+ {
534+ lockdep_assert_held (& iommu -> lock );
535+
536+ pasid_clear_entry (pte );
537+ pasid_set_domain_id (pte , did );
538+ pasid_set_address_width (pte , iommu -> agaw );
539+ pasid_set_translation_type (pte , PASID_ENTRY_PGTT_PT );
540+ pasid_set_fault_enable (pte );
541+ pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
542+ pasid_set_present (pte );
543+ }
544+
510545int intel_pasid_setup_pass_through (struct intel_iommu * iommu ,
511546 struct device * dev , u32 pasid )
512547{
@@ -525,13 +560,7 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
525560 return - EBUSY ;
526561 }
527562
528- pasid_clear_entry (pte );
529- pasid_set_domain_id (pte , did );
530- pasid_set_address_width (pte , iommu -> agaw );
531- pasid_set_translation_type (pte , PASID_ENTRY_PGTT_PT );
532- pasid_set_fault_enable (pte );
533- pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
534- pasid_set_present (pte );
563+ pasid_pte_config_pass_through (iommu , pte , did );
535564 spin_unlock (& iommu -> lock );
536565
537566 pasid_flush_caches (iommu , pte , pasid , did );
@@ -562,6 +591,46 @@ void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,
562591 intel_pasid_flush_present (iommu , dev , pasid , did , pte );
563592}
564593
594+ static void pasid_pte_config_nestd (struct intel_iommu * iommu ,
595+ struct pasid_entry * pte ,
596+ struct iommu_hwpt_vtd_s1 * s1_cfg ,
597+ struct dmar_domain * s2_domain ,
598+ u16 did )
599+ {
600+ struct dma_pte * pgd = s2_domain -> pgd ;
601+
602+ lockdep_assert_held (& iommu -> lock );
603+
604+ pasid_clear_entry (pte );
605+
606+ if (s1_cfg -> addr_width == ADDR_WIDTH_5LEVEL )
607+ pasid_set_flpm (pte , 1 );
608+
609+ pasid_set_flptr (pte , s1_cfg -> pgtbl_addr );
610+
611+ if (s1_cfg -> flags & IOMMU_VTD_S1_SRE ) {
612+ pasid_set_sre (pte );
613+ if (s1_cfg -> flags & IOMMU_VTD_S1_WPE )
614+ pasid_set_wpe (pte );
615+ }
616+
617+ if (s1_cfg -> flags & IOMMU_VTD_S1_EAFE )
618+ pasid_set_eafe (pte );
619+
620+ if (s2_domain -> force_snooping )
621+ pasid_set_pgsnp (pte );
622+
623+ pasid_set_slptr (pte , virt_to_phys (pgd ));
624+ pasid_set_fault_enable (pte );
625+ pasid_set_domain_id (pte , did );
626+ pasid_set_address_width (pte , s2_domain -> agaw );
627+ pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
628+ if (s2_domain -> dirty_tracking )
629+ pasid_set_ssade (pte );
630+ pasid_set_translation_type (pte , PASID_ENTRY_PGTT_NESTED );
631+ pasid_set_present (pte );
632+ }
633+
565634/**
566635 * intel_pasid_setup_nested() - Set up PASID entry for nested translation.
567636 * @iommu: IOMMU which the device belong to
@@ -579,7 +648,6 @@ int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev,
579648 struct iommu_hwpt_vtd_s1 * s1_cfg = & domain -> s1_cfg ;
580649 struct dmar_domain * s2_domain = domain -> s2_domain ;
581650 u16 did = domain_id_iommu (domain , iommu );
582- struct dma_pte * pgd = s2_domain -> pgd ;
583651 struct pasid_entry * pte ;
584652
585653 /* Address width should match the address width supported by hardware */
@@ -622,34 +690,7 @@ int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev,
622690 return - EBUSY ;
623691 }
624692
625- pasid_clear_entry (pte );
626-
627- if (s1_cfg -> addr_width == ADDR_WIDTH_5LEVEL )
628- pasid_set_flpm (pte , 1 );
629-
630- pasid_set_flptr (pte , s1_cfg -> pgtbl_addr );
631-
632- if (s1_cfg -> flags & IOMMU_VTD_S1_SRE ) {
633- pasid_set_sre (pte );
634- if (s1_cfg -> flags & IOMMU_VTD_S1_WPE )
635- pasid_set_wpe (pte );
636- }
637-
638- if (s1_cfg -> flags & IOMMU_VTD_S1_EAFE )
639- pasid_set_eafe (pte );
640-
641- if (s2_domain -> force_snooping )
642- pasid_set_pgsnp (pte );
643-
644- pasid_set_slptr (pte , virt_to_phys (pgd ));
645- pasid_set_fault_enable (pte );
646- pasid_set_domain_id (pte , did );
647- pasid_set_address_width (pte , s2_domain -> agaw );
648- pasid_set_page_snoop (pte , !!ecap_smpwc (iommu -> ecap ));
649- if (s2_domain -> dirty_tracking )
650- pasid_set_ssade (pte );
651- pasid_set_translation_type (pte , PASID_ENTRY_PGTT_NESTED );
652- pasid_set_present (pte );
693+ pasid_pte_config_nestd (iommu , pte , s1_cfg , s2_domain , did );
653694 spin_unlock (& iommu -> lock );
654695
655696 pasid_flush_caches (iommu , pte , pasid , did );
0 commit comments