@@ -324,6 +324,32 @@ static void intel_pasid_flush_present(struct intel_iommu *iommu,
324
324
* Set up the scalable mode pasid table entry for first only
325
325
* translation type.
326
326
*/
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
+
327
353
int intel_pasid_setup_first_level (struct intel_iommu * iommu ,
328
354
struct device * dev , pgd_t * pgd ,
329
355
u32 pasid , u16 did , int flags )
@@ -354,24 +380,8 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
354
380
return - EBUSY ;
355
381
}
356
382
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 );
371
384
372
- /* Setup Present and PASID Granular Transfer Type: */
373
- pasid_set_translation_type (pte , PASID_ENTRY_PGTT_FL_ONLY );
374
- pasid_set_present (pte );
375
385
spin_unlock (& iommu -> lock );
376
386
377
387
pasid_flush_caches (iommu , pte , pasid , did );
@@ -382,6 +392,26 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
382
392
/*
383
393
* Set up the scalable mode pasid entry for second only translation type.
384
394
*/
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
+
385
415
int intel_pasid_setup_second_level (struct intel_iommu * iommu ,
386
416
struct dmar_domain * domain ,
387
417
struct device * dev , u32 pasid )
@@ -417,17 +447,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
417
447
return - EBUSY ;
418
448
}
419
449
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 );
431
452
spin_unlock (& iommu -> lock );
432
453
433
454
pasid_flush_caches (iommu , pte , pasid , did );
@@ -507,6 +528,20 @@ int intel_pasid_setup_dirty_tracking(struct intel_iommu *iommu,
507
528
/*
508
529
* Set up the scalable mode pasid entry for passthrough translation type.
509
530
*/
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
+
510
545
int intel_pasid_setup_pass_through (struct intel_iommu * iommu ,
511
546
struct device * dev , u32 pasid )
512
547
{
@@ -525,13 +560,7 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
525
560
return - EBUSY ;
526
561
}
527
562
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 );
535
564
spin_unlock (& iommu -> lock );
536
565
537
566
pasid_flush_caches (iommu , pte , pasid , did );
@@ -562,6 +591,46 @@ void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,
562
591
intel_pasid_flush_present (iommu , dev , pasid , did , pte );
563
592
}
564
593
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
+
565
634
/**
566
635
* intel_pasid_setup_nested() - Set up PASID entry for nested translation.
567
636
* @iommu: IOMMU which the device belong to
@@ -579,7 +648,6 @@ int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev,
579
648
struct iommu_hwpt_vtd_s1 * s1_cfg = & domain -> s1_cfg ;
580
649
struct dmar_domain * s2_domain = domain -> s2_domain ;
581
650
u16 did = domain_id_iommu (domain , iommu );
582
- struct dma_pte * pgd = s2_domain -> pgd ;
583
651
struct pasid_entry * pte ;
584
652
585
653
/* 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,
622
690
return - EBUSY ;
623
691
}
624
692
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 );
653
694
spin_unlock (& iommu -> lock );
654
695
655
696
pasid_flush_caches (iommu , pte , pasid , did );
0 commit comments