@@ -450,17 +450,17 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
450450 struct pasid_entry * pte ;
451451 u16 did , pgtt ;
452452
453+ spin_lock (& iommu -> lock );
453454 pte = intel_pasid_get_entry (dev , pasid );
454- if (WARN_ON (!pte ))
455- return ;
456-
457- if (!pasid_pte_is_present (pte ))
455+ if (WARN_ON (!pte ) || !pasid_pte_is_present (pte )) {
456+ spin_unlock (& iommu -> lock );
458457 return ;
458+ }
459459
460460 did = pasid_get_domain_id (pte );
461461 pgtt = pasid_pte_get_pgtt (pte );
462-
463462 intel_pasid_clear_entry (dev , pasid , fault_ignore );
463+ spin_unlock (& iommu -> lock );
464464
465465 if (!ecap_coherent (iommu -> ecap ))
466466 clflush_cache_range (pte , sizeof (* pte ));
@@ -496,22 +496,6 @@ static void pasid_flush_caches(struct intel_iommu *iommu,
496496 }
497497}
498498
499- static inline int pasid_enable_wpe (struct pasid_entry * pte )
500- {
501- #ifdef CONFIG_X86
502- unsigned long cr0 = read_cr0 ();
503-
504- /* CR0.WP is normally set but just to be sure */
505- if (unlikely (!(cr0 & X86_CR0_WP ))) {
506- pr_err_ratelimited ("No CPU write protect!\n" );
507- return - EINVAL ;
508- }
509- #endif
510- pasid_set_wpe (pte );
511-
512- return 0 ;
513- };
514-
515499/*
516500 * Set up the scalable mode pasid table entry for first only
517501 * translation type.
@@ -528,39 +512,52 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
528512 return - EINVAL ;
529513 }
530514
531- pte = intel_pasid_get_entry (dev , pasid );
532- if (WARN_ON (!pte ))
515+ if (flags & PASID_FLAG_SUPERVISOR_MODE ) {
516+ #ifdef CONFIG_X86
517+ unsigned long cr0 = read_cr0 ();
518+
519+ /* CR0.WP is normally set but just to be sure */
520+ if (unlikely (!(cr0 & X86_CR0_WP ))) {
521+ pr_err ("No CPU write protect!\n" );
522+ return - EINVAL ;
523+ }
524+ #endif
525+ if (!ecap_srs (iommu -> ecap )) {
526+ pr_err ("No supervisor request support on %s\n" ,
527+ iommu -> name );
528+ return - EINVAL ;
529+ }
530+ }
531+
532+ if ((flags & PASID_FLAG_FL5LP ) && !cap_5lp_support (iommu -> cap )) {
533+ pr_err ("No 5-level paging support for first-level on %s\n" ,
534+ iommu -> name );
533535 return - EINVAL ;
536+ }
534537
535- /* Caller must ensure PASID entry is not in use. */
536- if (pasid_pte_is_present (pte ))
538+ spin_lock (& iommu -> lock );
539+ pte = intel_pasid_get_entry (dev , pasid );
540+ if (!pte ) {
541+ spin_unlock (& iommu -> lock );
542+ return - ENODEV ;
543+ }
544+
545+ if (pasid_pte_is_present (pte )) {
546+ spin_unlock (& iommu -> lock );
537547 return - EBUSY ;
548+ }
538549
539550 pasid_clear_entry (pte );
540551
541552 /* Setup the first level page table pointer: */
542553 pasid_set_flptr (pte , (u64 )__pa (pgd ));
543554 if (flags & PASID_FLAG_SUPERVISOR_MODE ) {
544- if (!ecap_srs (iommu -> ecap )) {
545- pr_err ("No supervisor request support on %s\n" ,
546- iommu -> name );
547- return - EINVAL ;
548- }
549555 pasid_set_sre (pte );
550- if (pasid_enable_wpe (pte ))
551- return - EINVAL ;
552-
556+ pasid_set_wpe (pte );
553557 }
554558
555- if (flags & PASID_FLAG_FL5LP ) {
556- if (cap_5lp_support (iommu -> cap )) {
557- pasid_set_flpm (pte , 1 );
558- } else {
559- pr_err ("No 5-level paging support for first-level\n" );
560- pasid_clear_entry (pte );
561- return - EINVAL ;
562- }
563- }
559+ if (flags & PASID_FLAG_FL5LP )
560+ pasid_set_flpm (pte , 1 );
564561
565562 if (flags & PASID_FLAG_PAGE_SNOOP )
566563 pasid_set_pgsnp (pte );
@@ -572,6 +569,8 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
572569 /* Setup Present and PASID Granular Transfer Type: */
573570 pasid_set_translation_type (pte , PASID_ENTRY_PGTT_FL_ONLY );
574571 pasid_set_present (pte );
572+ spin_unlock (& iommu -> lock );
573+
575574 pasid_flush_caches (iommu , pte , pasid , did );
576575
577576 return 0 ;
@@ -629,15 +628,17 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
629628 pgd_val = virt_to_phys (pgd );
630629 did = domain -> iommu_did [iommu -> seq_id ];
631630
631+ spin_lock (& iommu -> lock );
632632 pte = intel_pasid_get_entry (dev , pasid );
633633 if (!pte ) {
634- dev_err ( dev , "Failed to get pasid entry of PASID %d\n" , pasid );
634+ spin_unlock ( & iommu -> lock );
635635 return - ENODEV ;
636636 }
637637
638- /* Caller must ensure PASID entry is not in use. */
639- if ( pasid_pte_is_present ( pte ))
638+ if ( pasid_pte_is_present ( pte )) {
639+ spin_unlock ( & iommu -> lock );
640640 return - EBUSY ;
641+ }
641642
642643 pasid_clear_entry (pte );
643644 pasid_set_domain_id (pte , did );
@@ -654,6 +655,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
654655 if (pasid != PASID_RID2PASID )
655656 pasid_set_sre (pte );
656657 pasid_set_present (pte );
658+ spin_unlock (& iommu -> lock );
659+
657660 pasid_flush_caches (iommu , pte , pasid , did );
658661
659662 return 0 ;
@@ -669,15 +672,17 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
669672 u16 did = FLPT_DEFAULT_DID ;
670673 struct pasid_entry * pte ;
671674
675+ spin_lock (& iommu -> lock );
672676 pte = intel_pasid_get_entry (dev , pasid );
673677 if (!pte ) {
674- dev_err ( dev , "Failed to get pasid entry of PASID %d\n" , pasid );
678+ spin_unlock ( & iommu -> lock );
675679 return - ENODEV ;
676680 }
677681
678- /* Caller must ensure PASID entry is not in use. */
679- if ( pasid_pte_is_present ( pte ))
682+ if ( pasid_pte_is_present ( pte )) {
683+ spin_unlock ( & iommu -> lock );
680684 return - EBUSY ;
685+ }
681686
682687 pasid_clear_entry (pte );
683688 pasid_set_domain_id (pte , did );
@@ -692,6 +697,8 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
692697 */
693698 pasid_set_sre (pte );
694699 pasid_set_present (pte );
700+ spin_unlock (& iommu -> lock );
701+
695702 pasid_flush_caches (iommu , pte , pasid , did );
696703
697704 return 0 ;
0 commit comments