Skip to content

Commit 2cb5ff6

Browse files
yiliu1765joergroedel
authored andcommitted
iommu/vt-d: Refactor the pasid setup helpers
It is clearer to have a new set of pasid replacement helpers other than extending the existing ones to cover both initial setup and replacement. Then abstract out the common code for manipulating the pasid entry as preparation. No functional change is intended. Suggested-by: Lu Baolu <[email protected]> Reviewed-by: Lu Baolu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Signed-off-by: Yi Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 9bd008f commit 2cb5ff6

File tree

1 file changed

+105
-64
lines changed

1 file changed

+105
-64
lines changed

drivers/iommu/intel/pasid.c

Lines changed: 105 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
327353
int 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+
385415
int 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+
510545
int 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

Comments
 (0)