ARM SMMUv3控制器注冊過程分析(八)

1.概述

ARM SMMUv3控制器初始化及設備樹分析(七)中描述了IOMMU控制器初始化過程。SMMU驅動最后調用iommu_device_register將其注冊到內核中,下面分析一下SMMU控制器注冊過程中都做了那些工作。

如下圖所示,SMMU控制器注冊過程中主要做了4部分工作:

  1. 遍歷內核中所有總線,初始化使用SMMU的設備,主要是創建設備的Stream Table,給設備分配或者創建iommu_group
  2. 遍歷所有使用SMMU的設備,創建iommu_domian,并和設備關聯起來。主要是初始化設備使用的STE和CD表。
  3. 遍歷所有使用SMMU的設備,初始化DMA映射的iommu_domian。主要是初始化iova_domain、TLB刷新隊列,設置保留的IOVA。
  4. 釋放相關鎖,SMMU不需要,這里不多介紹。

iommu_device_register

如下代碼所示,iommu_device_register函數會遍歷iommu_buses定義的所有總線,初始化其中使用SMMU的設備。

[drivers/iommu/iommu.c]
static const struct bus_type * const iommu_buses[] = {&platform_bus_type,
#ifdef CONFIG_PCI&pci_bus_type,
#endif
#ifdef CONFIG_ARM_AMBA&amba_bustype,
#endif
#ifdef CONFIG_FSL_MC_BUS&fsl_mc_bus_type,
#endif
#ifdef CONFIG_TEGRA_HOST1X_CONTEXT_BUS&host1x_context_device_bus_type,
#endif
#ifdef CONFIG_CDX_BUS&cdx_bus_type,
#endif
};

2.初始化設備

初始化使用IOMMU的client設備,主要是為其創建Stream Table及分配或者創建iommu_group

  1. 調用arm_smmu_probe_device函數初始化設備。
    1. 由于client設備是smmu的master,因此smmu驅動會給每一個client設備分配一個arm_smmu_master,然后通過arm_smmu_master將client設備和smmu控制器關聯起來。dev_iommu中的私有數據指針priv指向了arm_smmu_masterarm_smmu_master中保存了設備的Stream ID信息。smmu驅動使用紅黑樹管理Stream ID。
    2. 如果采用2級Stream table,則需要分配client設備使用的第二級STE表內存,一次性分配256個STE表。然后將STE暫時設置成ABORT。
    3. 處理PCIe設備ATS相關功能。
  2. iommu_device保存到設備的dev_iommu中。這樣可以通過設備的device數據結構找到smmu控制器。
  3. 在sysfs中關聯設備和iommu,這樣在sys文件系統中device目錄下會有iommu控制器的文件。
  4. 調用arm_smmu_device_group函數為設備創建iommu_group。PCI設備可能會共享iommu_group,因此驅動會依據PCI總線拓撲結構、isolation特性或者DMA別名quirks查找或者創建iommu_group。其他設備每個設備分配一個iommu_group
  5. 分配group_device,然后掛到iommu_groupdevices鏈表中。一個iommu_group內可能有多個設備,每個設備使用group_device表示。
  6. iommu_group掛到group_list鏈表中,稍后統一處理。

probe_iommu_group

3.創建iommu_domian

遍歷group_list鏈表,為每個iommu_group設置默認的iommu_domain,主要的工作內容如下:

  1. 首先獲取iommu_domain的類型,傳入的參數為0,則iommu_domain類型由驅動和系統共同決定。對于PCI untrusted設備,類型為IOMMU_DOMAIN_DMA,其他設備返回0。
  2. 分配默認的iommu_domain。如果請求的iommu_domain類型非0,則使用請求的類型,否則使用iommu_def_domain_type表示的類型。iommu_def_domain_type是一個全局變量,由命令行參數和內核配置共同決定,通常情況下為IOMMU_DOMAIN_DMAIOMMU_DOMAIN_DMA_FQ。如果iommu_domain類型為DMA,則調用arm_smmu_domain_alloc_paging分配iommu_domain,smmu驅動底層會分配一個arm_smmu_domain,內部包含了iommu_domain,然后將arm_smmu_domainarm_smmu_devicearm_smmu_master)關聯在一起,最后初始化domain內頁表相關內容。
  3. 遍歷iommu_group內的每一個設備,如果其保留內存區域類型為IOMMU_RESV_DIRECTIOMMU_RESV_DIRECT_RELAXABLE,則創建direct mappings。避免這些內存區域被誤使用。
  4. 遍歷group中的每一個device,調用arm_smmu_attach_dev關聯對應的iommu_domain。最主要的是初始化arm_smmu_domain中的CD表。

分配iommu_domian
iommu_domain的類型不同,其分配策略也不同。iommu_domain__iommu_domain_alloc函數中分配,結合smmu驅動,可以總結iommu_domain的分配策略如下:

  1. 如果分配的iommu_domain類型是IOMMU_DOMAIN_IDENTITYIOMMU_DOMAIN_BLOCKED,則直接使用arm_smmu_ops驅動中靜態定義的arm_smmu_identity_domainarm_smmu_blocked_domain。這樣就存在多個iommu_group使用一個iommu_domain的情況。
  2. 如果分配的iommu_domain類型是IOMMU_DOMAIN_UNMANAGEDIOMMU_DOMAIN_DMAIOMMU_DOMAIN_DMA_FQ,則smmu驅動會動態分配arm_smmu_domain(內部包含了iommu_domain),這樣一個iommu_group對應一個iommu_domain,使用default_domain_ops,smmu驅動需要管理IOVA頁表。
  3. 如果分配的iommu_domain類型是IOMMU_DOMAIN_SVA,說明DMA共享進程進程地址空間,則smmu驅動會動態分配iommu_domain,并且使用arm_smmu_sva_domain_ops,由于和進程共享,smmu驅動只需要管理iommu_domain和PASID。

3.1.分配iommu_domian

arm_smmu_domain_alloc_paging函數主要分配支持iommu_map/unmap接口的iommu_domain,然后根據不同的地址轉換階段,做不同的初始化。主要的工作如下:

  1. 分配arm_smmu_domain,內部包含了iommu_domain
  2. 初始化arm_smmu_domainARM_SMMU_DOMAIN_S1ARM_SMMU_DOMAIN_S2初始化內容有所不同。
    1. 初始化IO頁表配置。包括SMMU支持的頁表大小掩碼、是否支持Cache一致性、刷新TLB回調函數arm_smmu_flush_ops
    2. 如果是第一階段地址轉換。設置輸入地址位寬為48位,如果支持虛擬地址擴展(VAX),則設置為52位,設置輸出地址位寬等于IPA地址的位寬。設置IO頁表格式為ARM_64_LPAE_S1
    3. 如果是第二階段地址轉換。設置輸入地址位寬等于IPA地址的位寬,設置輸出地址位寬等于PA地址的位寬。設置IO頁表格式為ARM_64_LPAE_S2
    4. 根據不同的IO頁表格式,創建管理IO頁表的接口集合io_pgtable_ops
      1. 對于ARM_64_LPAE_S1頁表格式,調用arm_64_lpae_alloc_pgtable_s1創建io_pgtable_ops。設置TCR(類似于MMU中的TCR_ELx)中的參數,如共享屬性、頁表大小、IPA地址寬度。設置MAIRs。分配保存第0級頁表的內存(CD表中TTB0/1指向這塊內存)。
      2. 對于ARM_64_LPAE_S2頁表格式,調用arm_64_lpae_alloc_pgtable_s2創建io_pgtable_ops。設置VTCR(類似于MMU中的VTCR_EL2)中的參數,如共享屬性、頁表大小、PA地址寬度。分配保存第0級頁表的內存(STE表中S2TTB指向這塊內存)。
    5. 如果是ARM_SMMU_DOMAIN_S1,則需要分配ASID。如果是ARM_SMMU_DOMAIN_S2,則需要分配VMID。

分配iommu_domian

arm_smmu_domain_alloc_paging函數分配iommu_domian的過程中涉及到重要的代碼定義如下所示:

[drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c]
// TLB刷新回調函數集合
static const struct iommu_flush_ops arm_smmu_flush_ops = {.tlb_flush_all      = arm_smmu_tlb_inv_context,.tlb_flush_walk     = arm_smmu_tlb_inv_walk,.tlb_add_page       = arm_smmu_tlb_inv_page_nosync,
};[drivers/iommu/io-pgtable.c]
// 根據不同的IO頁表格式,對應不同的創建io_pgtable_ops的函數
static const struct io_pgtable_init_fns *
io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE[ARM_32_LPAE_S1] = &io_pgtable_arm_32_lpae_s1_init_fns,[ARM_32_LPAE_S2] = &io_pgtable_arm_32_lpae_s2_init_fns,[ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,[ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,[ARM_MALI_LPAE]  = &io_pgtable_arm_mali_lpae_init_fns,
#endif......
};// io_pgtable_ops函數集合
[drivers/iommu/io-pgtable-arm.c]
data->iop.ops = (struct io_pgtable_ops) {.map_pages            = arm_lpae_map_pages,.unmap_pages          = arm_lpae_unmap_pages,.iova_to_phys         = arm_lpae_iova_to_phys,.read_and_clear_dirty = arm_lpae_read_and_clear_dirty,

3.2.關聯設備

arm_smmu_attach_dev函數的主要作用是將iommu_domain和設備關聯起來。如果是第一階段地址轉換的iommu_domain,則需要初始化CD表,如果是第二階段地址轉換的iommu_domain,則需要初始化STE表中S2相關的參數。具體的內容如下:

  1. 如果是ARM_SMMU_DOMAIN_S1,則分配CD表。如果是線性CD表(STRTAB_STE_0_S1FMT_LINEAR),則直接分配全部內存。如果是2級CD表(STRTAB_STE_0_S1FMT_64K_L2),先分配第一級L1CD內存,接著分配SSID ==0的第二級CD表數組(可以保存1024個CD),隨后將第二級CD表數組的DMA地址寫到L1CD內存中(l2.l1tab[0]),最后invalid L1CD。
  2. 處理和ATS相關的功能。
  3. 如果是第一階段地址轉換(ARM_SMMU_DOMAIN_S1)。
    1. 初始化第0個CD表。
    2. 初始化設備需要的STE表(根據SID初始化),默認SID==0的STE(STRTAB_STE_1_S1DSS_SSID0)無法使用,如果使用則會ABORT。
  4. 如果是第二階段地址轉換(ARM_SMMU_DOMAIN_S2)。初始化設備需要的STE表(根據SID初始化),如果該STE表有對應的CD表,則將第一個CD表清零。
  5. 按照EATS設置完成STE/CD的配置之后,需要完成對PCIe設備ATC的同步操作。

關聯設備

4.初始化DMA iommu_domian

iommu_setup_dma_ops函數初始化DMA映射的iommu_domian,主要的工作如下:

  1. 設置dev->dma_iommu=true。如果啟用DMA-API和IOMMU-API的中間層,則設備在分配DMA內存或者進行流式映射內存時,底層將調用DMA-IOMMU接口。
  2. 初始化iommu_domain。初始化管理IO虛擬地址的iova_domain及地址緩存、TLB刷新隊列和注冊保留的IO虛擬地址。

初始化IOVA

參考資料

  1. linux 6.12.35 source code.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92961.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92961.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92961.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Idefics3:構建和更好地理解視覺-語言模型:洞察與未來方向

溫馨提示: 本篇文章已同步至"AI專題精講" Idefics3:構建和更好地理解視覺-語言模型:洞察與未來方向 摘要 視覺-語言模型(VLMs)領域,接收圖像和文本作為輸入并輸出文本的模型,正在快…

利用DeepSeek解決kdb+x進行tpch測試的幾個問題及使用感受

上文其實沒有成功運行tpch的22個標準查詢中的任何一個,因為DeepSeek原始給出的導入語句有錯,有一些表沒有導入。 1.解決類型及長度問題導致的插入tbl文件到內存表失敗。 kdbx的Reference card()提到的基本數據類型如下: Basic datatypes n …

SGLang 核心技術詳解

SGLang 作為一個高性能的 LLM 服務框架,通過一系列先進的優化技術實現了卓越的推理性能。下面詳細解釋其核心功能組件: 1. RadixAttention 用于前綴緩存 核心概念 RadixAttention 是 SGLang 獨創的前綴緩存機制,基于 Radix Tree(基…

精密全波整流電路(四)

精密全波整流電路(四) 背景說明 [[精密半波整流電路|半波整流]]雖然能實現交直流信號的轉換,但是半波整流只能保留信號半個周期的能量,導致信號能量的利用率不高。 因此,在一些場合需要使用到全波整流電路。 同樣的&…

深入解讀Prometheus 2.33 Series Chunks壓縮特性:原理與實踐

深入解讀Prometheus 2.33 Series Chunks壓縮特性:原理與實踐 隨著監控指標規模不斷增長,Prometheus的本地TSDB存儲壓力日益增大。為提升存儲效率,Prometheus 2.33引入了Series Chunks壓縮特性,對時間序列數據在寫入和存儲時進行深…

SpringBoot整合Liquibase提升數據庫變更的可控性、安全性、自動化程度(最詳細)

為什么要使用liquibase?- 團隊協作與版本管理- 當多人(或多個小組)并行開發、對同一數據庫結構進行變更時,如果僅靠手寫 SQL 腳本,很 容易產生沖突或漏掉某些變更。- Liquibase 將所有 DDL/DML 操作以“changeset”形式納入源碼管…

數據寫入因為漢字引發的異常

spark 數據寫hive表,發生 查詢分區異常問題 異常: 25107124 19 26.49 ERROR Hive: MelaException(message.Exception thrown when execuling quey. S ELECT DISTINCT ‘org apache.hadop.hive melastore .modelMpartion As"NUCLEUS TYPE,AONCREATE TIME,AO.LAST ACCE…

Springboot項目實現將文件上傳到阿里云

Springboot項目實現將文件上傳到阿里云 一、概述二、具體步驟 2.1引入阿里云工具 首先先建utils包,然后引入AliOSSUtils類,如下: package com.hechixueyuan.forestfiredetectionsystem.utils;import com.aliyun.oss.OSS; import com.aliyun.o…

如何理解 TCP 是字節流協議?詳解

文章目錄一、面向字節流二、粘包問題應用層如何解決粘包問題?一、面向字節流 使用 TCP socket 進行網絡編程,Linux 內核會給每個 socket 都分配一個發送緩沖區和一個接收緩沖區 由于緩沖區的存在, TCP 讀寫不需要一一匹配,例如:…

面試問題總結——關于OpenCV(二)

最近小組在面試視覺算法工程師,順便整理了一波關于OpenCV的面試題目。 有些知識點也不深入,對于寫的不對的地方,歡迎指正。 目錄 20.像素梯度如何計算? 21.關于開運算和閉運算的理解 22.開運算和閉運算有什么優缺點? 23.圖像插值有哪些? 24.圖像金字塔的原理 25.邊緣檢測…

目標導向的強化學習:問題定義與 HER 算法詳解—強化學習(19)

目錄 1、目標導向的強化學習:問題定義 1.1、 核心要素與符號定義 1.2、 核心問題:稀疏獎勵困境 1.3、 學習目標 2、HER(Hindsight Experience Replay)算法 2.1、 HER 的核心邏輯 2.2、 算法步驟(結合 DDPG 舉例…

2025 XYD Summer Camp 7.21 智靈班分班考 · Day1

智靈班分班考 Day1 時間線 8:00 在濱蘭實驗的遠古機房中的一個鍵盤手感爆炸的電腦上開考。開 T1,推了推發現可以 segment tree 優化 dp,由于按空格需要很大的力氣導致馬蜂被迫改變。后來忍不住了頂著疼痛按空格。8:30 過了樣例,但是沒有大樣…

基于多種主題分析、關鍵詞提取算法的設計與實現【TF-IDF算法、LDA、NMF分解、BERT主題模型】

文章目錄有需要本項目的代碼或文檔以及全部資源,或者部署調試可以私信博主一、項目背景二、研究目標與意義三、數據獲取與處理四、文本分析與主題建模方法1. 傳統方法探索2. 主題模型比較與優化3. 深度語義建模與聚類五、研究成果與應用價值六、總結與展望總結每文一…

MDC(Mapped Diagnostic Context) 的核心介紹與使用教程

關于日志框架中 MDC(Mapped Diagnostic Context) 的核心介紹與使用教程,結合其在分布式系統中的實際應用場景,分模塊說明: 一、MDC 簡介 MDC(映射診斷上下文) 是 SLF4J/Logback 提供的一種線程…

Linux隨記(二十一)

一、highgo切換leader,follow - 隨記 【待寫】二、highgo的etcd未授權訪問 - 隨記 【待寫】三、highgo的etcd未授權訪問 - 隨記 【待寫】3.2、etcd的metric未授權訪問 - 隨記 【待寫】四、安裝Elasticsearch 7.17.29 和 Elasticsearch 未授權訪問【原理掃描】…

Java環境配置之各類組件下載安裝教程整理(jdk、idea、git、maven、mysql、redis)

Java環境配置之各類組件下載安裝教程整理(jdk、idea、git、maven、mysql、redis)1.[安裝配置jdk8]2.[安裝配置idea]3.[安裝配置git]4.[安裝配置maven]5.[安裝配置postman]6.[安裝配置redis和可視化工具]7.[安裝配置mysql和可視化工具]8.[安裝配置docker]…

配置https ssl證書生成

1.可用openssl生成私鑰和自簽名證書 安裝opensslsudo yum install openssl -y 2.生成ssl證書 365天期限sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \-keyout /etc/ssl/private/nginx-selfsigned.key \-out /etc/ssl/certs/nginx-selfsigned.crt3、按照提示編…

編程語言Java——核心技術篇(四)集合類詳解

言不信者行不果,行不敏者言多滯. 目錄 4. 集合類 4.1 集合類概述 4.1.1 集合框架遵循原則 4.1.2 集合框架體系 4.2 核心接口和實現類解析 4.2.1 Collection 接口體系 4.2.1.1 Collection 接口核心定義 4.2.1.2 List接口詳解 4.2.1.3 Set 接口詳解 4.2.1.4…

GaussDB 數據庫架構師(八) 等待事件(1)-概述

1、等待事件概述 等待事件:指當數據庫會話(session)因資源競爭或依賴無法繼續執行時,進入"等待"狀態,此時產生的性能事件即等待事件。 2、等待事件本質 性能瓶頸的信號燈,反映CPU,I/O、鎖、網絡等關鍵資源的阻塞情況。…

五分鐘系列-文本搜索工具grep

目錄 1??核心功能?? ??2??基本語法?? 3????常用選項 & 功能詳解?? ??4??經典應用場景 & 示例?? 5????重要的提示 & 技巧?? ??6??總結?? grep 是 Linux/Unix 系統中功能強大的??文本搜索工具??,其名稱源自 …