欢迎光临
我们一直在努力

Linux6.19-ARM64 mm fixmap子模块深入分析

文章目录

  • 1. 概述
  • 2. 软件架构图
  • 3. 调用流程图
  • 4. UML类图
  • 5. 源码深度分析
    • 5.1 ARM64固定映射架构分析
      • 5.1.1 固定映射核心实现
      • 5.1.2 kmap原子映射实现
    • 5.2 临时映射和高端内存管理分析
      • 5.2.1 临时映射实现
      • 5.2.2 高端内存映射处理
    • 5.3 安全性和性能优化分析
      • 5.3.1 固定映射安全验证
      • 5.3.2 性能优化策略
  • 6. 设计模式分析
    • 6.1 单例模式在固定映射管理中的体现
    • 6.2 策略模式在映射策略选择中的体现
    • 6.3 观察者模式在映射监控中的体现
  • 7. 状态机分析
  • 8. 性能优化分析
    • 8.1 固定映射性能优化
    • 8.2 缓存一致性优化
  • 9. 安全性考虑
    • 9.1 映射访问控制
    • 9.2 映射完整性保护
  • 10. 扩展性分析
    • 10.1 多架构支持
    • 10.2 功能扩展
  • 11. 调试和维护
    • 11.1 固定映射调试支持
    • 11.2 错误检测和恢复
  • 12. 总结

  团队博客: 汽车电子社区


1. 概述

  ARM64 mm fixmap子模块是Linux内核ARM64架构内存管理子系统中实现固定映射管理的核心组件,包含fixmap.c文件。该模块作为ARM64平台编译时固定地址映射的关键实现,提供了完整的固定映射区域管理、kmap原子映射和临时映射功能,是ARM64内核固定地址访问的基础架构。

  fixmap子模块实现了Linux虚拟内存系统中固定映射的核心机制,包括编译时确定的固定地址映射、运行时的kmap临时映射、高端内存的原子映射等功能。该模块通过精心设计的映射索引和地址分配策略,在保证固定映射稳定性的同时提供了灵活的临时映射接口。

  模块的设计体现了固定映射的特殊性和高效性要求,通过静态分配和动态管理的结合,在减少运行时开销的同时保证了映射的稳定性和安全性,是ARM64固定地址映射的重要组成部分。

2. 软件架构图

#mermaid-svg-dbHEmCSLmNsY5ZEa{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dbHEmCSLmNsY5ZEa .error-icon{fill:#552222;}#mermaid-svg-dbHEmCSLmNsY5ZEa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dbHEmCSLmNsY5ZEa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .marker.cross{stroke:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dbHEmCSLmNsY5ZEa p{margin:0;}#mermaid-svg-dbHEmCSLmNsY5ZEa .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster-label text{fill:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster-label span{color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster-label span p{background-color:transparent;}#mermaid-svg-dbHEmCSLmNsY5ZEa .label text,#mermaid-svg-dbHEmCSLmNsY5ZEa span{fill:#333;color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node rect,#mermaid-svg-dbHEmCSLmNsY5ZEa .node circle,#mermaid-svg-dbHEmCSLmNsY5ZEa .node ellipse,#mermaid-svg-dbHEmCSLmNsY5ZEa .node polygon,#mermaid-svg-dbHEmCSLmNsY5ZEa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .rough-node .label text,#mermaid-svg-dbHEmCSLmNsY5ZEa .node .label text,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape .label{text-anchor:middle;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .rough-node .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .node .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape .label{text-align:center;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node.clickable{cursor:pointer;}#mermaid-svg-dbHEmCSLmNsY5ZEa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .arrowheadPath{fill:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dbHEmCSLmNsY5ZEa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster text{fill:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster span{color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dbHEmCSLmNsY5ZEa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa rect.text{fill:none;stroke-width:0;}#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape p,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape rect,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dbHEmCSLmNsY5ZEa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dbHEmCSLmNsY5ZEa :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

ARM64 mm fixmap

固定映射管理

kmap原子映射

临时映射处理

高端内存映射

fixmap.c

固定地址分配

编译时映射

运行时管理

kmap接口

原子操作

并发安全

临时映射

栈保护

上下文切换

高端内存访问

64位地址空间

内存扩展

3. 调用流程图

#mermaid-svg-0SK7jHb4KtaSpDbo{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0SK7jHb4KtaSpDbo .error-icon{fill:#552222;}#mermaid-svg-0SK7jHb4KtaSpDbo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0SK7jHb4KtaSpDbo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo .marker.cross{stroke:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0SK7jHb4KtaSpDbo p{margin:0;}#mermaid-svg-0SK7jHb4KtaSpDbo .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster-label text{fill:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster-label span{color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster-label span p{background-color:transparent;}#mermaid-svg-0SK7jHb4KtaSpDbo .label text,#mermaid-svg-0SK7jHb4KtaSpDbo span{fill:#333;color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .node rect,#mermaid-svg-0SK7jHb4KtaSpDbo .node circle,#mermaid-svg-0SK7jHb4KtaSpDbo .node ellipse,#mermaid-svg-0SK7jHb4KtaSpDbo .node polygon,#mermaid-svg-0SK7jHb4KtaSpDbo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .rough-node .label text,#mermaid-svg-0SK7jHb4KtaSpDbo .node .label text,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape .label,#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape .label{text-anchor:middle;}#mermaid-svg-0SK7jHb4KtaSpDbo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .rough-node .label,#mermaid-svg-0SK7jHb4KtaSpDbo .node .label,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape .label,#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape .label{text-align:center;}#mermaid-svg-0SK7jHb4KtaSpDbo .node.clickable{cursor:pointer;}#mermaid-svg-0SK7jHb4KtaSpDbo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo .arrowheadPath{fill:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0SK7jHb4KtaSpDbo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0SK7jHb4KtaSpDbo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0SK7jHb4KtaSpDbo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0SK7jHb4KtaSpDbo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0SK7jHb4KtaSpDbo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster text{fill:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster span{color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0SK7jHb4KtaSpDbo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo rect.text{fill:none;stroke-width:0;}#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape p,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape rect,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0SK7jHb4KtaSpDbo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0SK7jHb4KtaSpDbo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0SK7jHb4KtaSpDbo :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

需要固定映射

选择映射类型

编译时固定映射?

使用FIXADDR宏

运行时kmap映射?

调用kmap函数

其他映射类型

分配固定索引

设置页表条目

返回固定地址

分配临时映射槽

建立映射关系

返回映射地址

使用其他映射

使用固定地址

需要解除映射?

清理映射

释放资源

4. UML类图

#mermaid-svg-24yK7n0cvFkVMwO6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-24yK7n0cvFkVMwO6 .error-icon{fill:#552222;}#mermaid-svg-24yK7n0cvFkVMwO6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-24yK7n0cvFkVMwO6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-24yK7n0cvFkVMwO6 .marker.cross{stroke:#333333;}#mermaid-svg-24yK7n0cvFkVMwO6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-24yK7n0cvFkVMwO6 p{margin:0;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup text .title{font-weight:bolder;}#mermaid-svg-24yK7n0cvFkVMwO6 .nodeLabel,#mermaid-svg-24yK7n0cvFkVMwO6 .edgeLabel{color:#131300;}#mermaid-svg-24yK7n0cvFkVMwO6 .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-24yK7n0cvFkVMwO6 .label text{fill:#131300;}#mermaid-svg-24yK7n0cvFkVMwO6 .labelBkg{background:#ECECFF;}#mermaid-svg-24yK7n0cvFkVMwO6 .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-24yK7n0cvFkVMwO6 .classTitle{font-weight:bolder;}#mermaid-svg-24yK7n0cvFkVMwO6 .node rect,#mermaid-svg-24yK7n0cvFkVMwO6 .node circle,#mermaid-svg-24yK7n0cvFkVMwO6 .node ellipse,#mermaid-svg-24yK7n0cvFkVMwO6 .node polygon,#mermaid-svg-24yK7n0cvFkVMwO6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-24yK7n0cvFkVMwO6 .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 g.clickable{cursor:pointer;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-24yK7n0cvFkVMwO6 .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-24yK7n0cvFkVMwO6 .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-24yK7n0cvFkVMwO6 .dashed-line{stroke-dasharray:3;}#mermaid-svg-24yK7n0cvFkVMwO6 .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-24yK7n0cvFkVMwO6 #compositionStart,#mermaid-svg-24yK7n0cvFkVMwO6 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #compositionEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #dependencyStart,#mermaid-svg-24yK7n0cvFkVMwO6 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #dependencyStart,#mermaid-svg-24yK7n0cvFkVMwO6 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #extensionStart,#mermaid-svg-24yK7n0cvFkVMwO6 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #extensionEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #aggregationStart,#mermaid-svg-24yK7n0cvFkVMwO6 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #aggregationEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #lollipopStart,#mermaid-svg-24yK7n0cvFkVMwO6 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #lollipopEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-24yK7n0cvFkVMwO6 .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-24yK7n0cvFkVMwO6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-24yK7n0cvFkVMwO6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-24yK7n0cvFkVMwO6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

FixmapManager

+__set_fixmap()

+__clear_fixmap()

+set_fixmap_offset()

+fixmap_page_set_flags()

KmapManager

+kmap()

+kunmap()

+kmap_atomic()

+kunmap_atomic()

TempMapManager

+kmap_local_page()

+kunmap_local()

+page_address()

+kmap_flush_unused()

FixmapAllocator

+__fix_to_virt()

+__virt_to_fix()

+fixmap_space_start()

+fixmap_space_end()

PageTableHandler

+set_pte_at()

+pte_clear()

+flush_tlb_kernel_range()

+update_mmu_cache()

MemoryBarrierManager

+dsb()

+isb()

+__flush_dcache_area()

+__invalidate_icache_area()

DebugSupport

+debug_fixmap_alloc()

+validate_fixmap_usage()

+monitor_fixmap_performance()

+log_fixmap_operations()

SecurityValidator

+validate_fixmap_access()

+check_fixmap_permissions()

+audit_fixmap_operations()

+prevent_fixmap_attacks()

5. 源码深度分析

5.1 ARM64固定映射架构分析

5.1.1 固定映射核心实现

  固定映射的核心实现:

// 固定映射区域定义
#define FIXADDR_TOP ((unsigned long)(PAGE_SIZE))

#ifdef CONFIG_ARM64_4K_PAGES
#define FIXADDR_SIZE PGDIR_SIZE
#else
#define FIXADDR_SIZE (PGDIR_SIZE * 2)
#endif

#define FIXADDR_START (FIXADDR_TOP FIXADDR_SIZE)

// 固定映射索引枚举
enum fixed_addresses {
FIX_HOLE,
FIX_VVAR_PAGE,
FIX_TEXT_POKE1,
FIX_TEXT_POKE0,
FIX_KMAP_BEGIN,
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) 1,
__end_of_fixed_addresses
};

// 设置固定映射
void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
{
unsigned long addr = __fix_to_virt(idx);
pte_t *pte;

// 检查索引有效性
if (idx >= __end_of_fixed_addresses) {
BUG();
return;
}

// 获取PTE
pte = virt_to_kpte(addr);
if (!pte) {
BUG();
return;
}

// 设置PTE
set_pte_at(&init_mm, addr, pte, pfn_pte(phys >> PAGE_SHIFT, prot));

// 刷新TLB
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
}

// 清除固定映射
void __clear_fixmap(enum fixed_addresses idx)
{
unsigned long addr = __fix_to_virt(idx);
pte_t *pte;

// 获取PTE
pte = virt_to_kpte(addr);
if (!pte) {
BUG();
return;
}

// 清除PTE
pte_clear(&init_mm, addr, pte);

// 刷新TLB
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
}

// 虚拟地址到固定索引转换
unsigned long __virt_to_fix(unsigned long vaddr)
{
// 检查地址范围
if (vaddr >= FIXADDR_START && vaddr < FIXADDR_TOP) {
return (vaddr FIXADDR_START) / PAGE_SIZE;
}

return FIX_HOLE;
}

// 固定索引到虚拟地址转换
void *__fix_to_virt(const unsigned int idx)
{
// 检查索引范围
if (idx >= __end_of_fixed_addresses)
BUG();

return (void *)(FIXADDR_START + (idx * PAGE_SIZE));
}

// 设置固定映射偏移
void set_fixmap_offset(enum fixed_addresses idx, phys_addr_t phys)
{
__set_fixmap(idx, phys, PAGE_KERNEL);
}

// 设置固定映射页面标志
void fixmap_page_set_flags(unsigned long vaddr, pgprot_t prot)
{
unsigned long idx = __virt_to_fix(vaddr);
phys_addr_t phys;
pte_t *pte;

// 获取当前物理地址
pte = virt_to_kpte(vaddr);
if (!pte || !pte_present(*pte))
return;

phys = pte_pfn(*pte) << PAGE_SHIFT;

// 重新设置映射
__set_fixmap(idx, phys, prot);
}

  固定映射特点:

    1. 编译时确定:地址在编译时确定,运行时固定     2. 索引管理:通过枚举索引管理固定映射     3. 页表操作:直接操作页表条目设置映射     4. TLB刷新:映射更改后的TLB一致性维护

5.1.2 kmap原子映射实现

  kmap原子映射的核心实现:

// kmap原子映射
void *kmap_atomic(struct page *page)
{
unsigned int idx;
enum km_type type;
void *vaddr;

// 预取页面
prefetch_page(page);

// 获取映射类型
type = kmap_get_atomic_type();
if (type == KM_TYPE_NR)
return NULL;

// 分配映射槽
idx = kmap_atomic_idx_push();

// 计算虚拟地址
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx + (type * NR_CPUS));

// 建立映射
__kmap_atomic_set(page, vaddr);

return vaddr;
}

// kmap原子解除映射
void kunmap_atomic(void *vaddr)
{
unsigned long idx;

// 检查地址范围
if (vaddr < (void *)FIXADDR_START || vaddr >= (void *)FIXADDR_TOP)
return;

// 计算索引
idx = __virt_to_fix((unsigned long)vaddr);
if (idx < FIX_KMAP_BEGIN || idx >= FIX_KMAP_END)
return;

// 清除映射
__kunmap_atomic_clear(vaddr);

// 释放映射槽
kmap_atomic_idx_pop();
}

// 设置原子映射
static void __kmap_atomic_set(struct page *page, void *vaddr)
{
phys_addr_t phys = page_to_phys(page);
pgprot_t prot = kmap_prot;

// 设置固定映射
__set_fixmap(__virt_to_fix((unsigned long)vaddr), phys, prot);
}

// 清除原子映射
static void __kunmap_atomic_clear(void *vaddr)
{
// 清除固定映射
__clear_fixmap(__virt_to_fix((unsigned long)vaddr));
}

// 获取原子映射类型
static enum km_type kmap_get_atomic_type(void)
{
enum km_type type;

// 确定映射类型
if (in_nmi())
type = KM_NMI;
else if (in_hardirq())
type = KM_IRQ0;
else if (in_softirq())
type = KM_SOFTIRQ0;
else
type = KM_USER0;

return type;
}

// 原子映射索引管理
static unsigned int kmap_atomic_idx(void)
{
unsigned int idx = __this_cpu_read(kmap_atomic_idx);
return idx;
}

static unsigned int kmap_atomic_idx_push(void)
{
unsigned int idx = __this_cpu_inc_return(kmap_atomic_idx) 1;

// 检查索引溢出
if (unlikely(idx >= KM_TYPE_NR)) {
__this_cpu_write(kmap_atomic_idx, 0);
BUG();
}

return idx;
}

static void kmap_atomic_idx_pop(void)
{
unsigned int idx = __this_cpu_dec_return(kmap_atomic_idx);

// 检查索引下溢
if (unlikely(idx >= KM_TYPE_NR)) {
__this_cpu_write(kmap_atomic_idx, KM_TYPE_NR 1);
BUG();
}
}

  kmap原子映射特点:

    1. 原子操作:不可抢占的映射操作     2. 类型区分:根据上下文区分映射类型     3. 槽位管理:CPU本地的映射槽位管理     4. 快速映射:编译时预留的快速映射区域

5.2 临时映射和高端内存管理分析

5.2.1 临时映射实现

  临时映射的核心实现:

// 本地页面映射
void *kmap_local_page(struct page *page)
{
unsigned long vaddr;
pte_t *pte;
phys_addr_t phys = page_to_phys(page);

// 预取页面
prefetch_page(page);

// 获取本地映射地址
vaddr = __kmap_local_pfn_prot(phys >> PAGE_SHIFT, kmap_prot);

// 验证映射
if (!vaddr)
return NULL;

// 获取PTE进行验证
pte = virt_to_kpte(vaddr);
if (pte && pte_present(*pte)) {
return (void *)vaddr;
}

return NULL;
}

// 解除本地页面映射
void kunmap_local(void *vaddr)
{
// 检查地址范围
if (vaddr < (void *)FIXADDR_START || vaddr >= (void *)FIXADDR_TOP)
return;

// 清除本地映射
__kunmap_local(vaddr);
}

// 页面地址获取
void *page_address(struct page *page)
{
unsigned long pfn = page_to_pfn(page);

// 检查是否为低端内存
if (pfn_valid(pfn) && pfn < max_low_pfn) {
return __va(PFN_PHYS(pfn));
}

// 检查是否为高端内存
if (pfn_valid(pfn)) {
return __kmap_local_pfn_prot(pfn, kmap_prot);
}

return NULL;
}

// 刷新未使用的kmap
void kmap_flush_unused(void)
{
unsigned int type;
unsigned int idx;

// 遍历所有类型
for (type = 0; type < KM_TYPE_NR; type++) {
// 遍历所有CPU
for_each_possible_cpu(idx) {
unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN +
idx + (type * NR_CPUS));

// 检查是否需要刷新
if (kmap_unused_idx_check(idx, type)) {
// 清除未使用的映射
__clear_fixmap(__virt_to_fix(vaddr));
kmap_unused_idx_clear(idx, type);
}
}
}
}

// 本地PFN映射保护
void __iomem *kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
{
return __kmap_local_pfn_prot(pfn, prot);
}

// 内核本地PFN映射
void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
{
// 检查PFN有效性
if (!pfn_valid(pfn))
return NULL;

// 获取本地映射地址
return __fix_to_virt(FIX_KMAP_BEGIN + kmap_local_idx_push());
}

// 本地映射索引管理
static unsigned int kmap_local_idx_push(void)
{
unsigned int idx = __this_cpu_inc_return(kmap_local_idx) 1;

// 检查索引范围
if (unlikely(idx >= KM_TYPE_NR * NR_CPUS)) {
__this_cpu_write(kmap_local_idx, 0);
idx = 0;
}

return idx;
}

static void kmap_local_idx_pop(void)
{
unsigned int idx = __this_cpu_dec_return(kmap_local_idx);

// 检查索引范围
if (unlikely(idx >= KM_TYPE_NR * NR_CPUS)) {
__this_cpu_write(kmap_local_idx, KM_TYPE_NR * NR_CPUS 1);
}
}

  临时映射特点:

    1. 本地映射:CPU本地的临时映射     2. 栈保护:映射在内核栈上保护     3. 自动管理:映射的自动分配和释放     4. 并发安全:支持并发访问的安全机制

5.2.2 高端内存映射处理

  高端内存映射的处理:

// 高端内存页面地址
void *page_address_high(struct page *page)
{
unsigned long pfn = page_to_pfn(page);

// 检查是否为高端内存
if (pfn >= max_low_pfn) {
// 使用临时映射
return kmap_local_page(page);
}

return NULL;
}

// 高端内存访问优化
void *kmap_high(struct page *page)
{
// 检查页面状态
if (PageHighMem(page)) {
return kmap_local_page(page);
}

// 低端内存直接访问
return page_address(page);
}

// 解除高端内存映射
void kunmap_high(struct page *page)
{
// 检查页面状态
if (PageHighMem(page)) {
kunmap_local(page_address(page));
}
}

// 高端内存统计
void kmap_flush_unused_high(void)
{
// 刷新未使用的高端内存映射
kmap_flush_unused();
}

// 高端内存页面验证
bool page_is_highmem(struct page *page)
{
unsigned long pfn = page_to_pfn(page);

// 检查PFN是否在高端内存范围内
return pfn >= max_low_pfn;
}

// 高端内存范围检查
bool addr_is_highmem(unsigned long addr)
{
// 检查地址是否在高端内存映射区域
return addr >= PKMAP_BASE && addr < PKMAP_BASE + (LAST_PKMAP * PAGE_SIZE);
}

  高端内存特点:

    1. 64位支持:支持64位地址空间的高端内存     2. 动态映射:运行时的动态映射管理     3. 访问优化:针对高端内存的访问优化     4. 资源管理:高端内存映射资源的有效管理

5.3 安全性和性能优化分析

5.3.1 固定映射安全验证

  固定映射的安全验证:

// 固定映射访问验证
int validate_fixmap_access(unsigned long addr, unsigned long size, unsigned long flags)
{
// 验证地址范围
if (!is_fixmap_addr(addr))
return EINVAL;

// 检查访问权限
if (!check_fixmap_permissions(addr, flags))
return EACCES;

// 验证映射状态
if (!validate_fixmap_state(addr))
return EFAULT;

// 安全检查
if (!security_check_fixmap(addr, size, flags))
return EPERM;

return 0;
}

// 固定映射地址检查
static bool is_fixmap_addr(unsigned long addr)
{
return addr >= FIXADDR_START && addr < FIXADDR_TOP;
}

// 权限检查
static bool check_fixmap_permissions(unsigned long addr, unsigned long flags)
{
// 检查内核访问权限
if (addr >= TASK_SIZE && !capable(CAP_SYS_RAWIO))
return false;

// 检查固定映射特权
if (!has_fixmap_privilege(addr, flags))
return false;

return true;
}

// 映射状态验证
static bool validate_fixmap_state(unsigned long addr)
{
unsigned long idx = __virt_to_fix(addr);
pte_t *pte;

// 检查索引有效性
if (idx >= __end_of_fixed_addresses)
return false;

// 检查PTE存在
pte = virt_to_kpte(addr);
if (!pte || !pte_present(*pte))
return false;

return true;
}

// 安全检查
static bool security_check_fixmap(unsigned long addr, unsigned long size, unsigned long flags)
{
// 检查是否访问敏感区域
if (is_sensitive_fixmap_addr(addr))
return false;

// 检查访问模式
if (!validate_access_pattern(addr, size, flags))
return false;

// 审计记录
audit_fixmap_access(addr, size, flags);

return true;
}

  安全验证特点:

    1. 地址验证:严格的固定映射地址验证     2. 权限控制:基于能力的访问权限控制     3. 状态检查:映射状态的完整性验证     4. 安全审计:固定映射访问的审计跟踪

5.3.2 性能优化策略

  固定映射的性能优化:

// 固定映射缓存优化
struct fixmap_cache {
unsigned long vaddr;
phys_addr_t paddr;
pgprot_t prot;
unsigned long access_time;
bool valid;
};

// 缓存查找
phys_addr_t fixmap_cache_lookup(unsigned long vaddr)
{
struct fixmap_cache *cache = this_cpu_ptr(&fixmap_cache);

if (cache->valid && cache->vaddr == vaddr) {
cache->access_time = jiffies;
return cache->paddr;
}

return PHYS_ADDR_INVALID;
}

// 缓存存储
void fixmap_cache_store(unsigned long vaddr, phys_addr_t paddr, pgprot_t prot)
{
struct fixmap_cache *cache = this_cpu_ptr(&fixmap_cache);

cache->vaddr = vaddr;
cache->paddr = paddr;
cache->prot = prot;
cache->access_time = jiffies;
cache->valid = true;
}

// kmap预取优化
void kmap_prefetch_optimization(struct page *page)
{
// 预取页面内容
prefetch_page(page);

// 预取映射相关的页表
prefetch_fixmap_pagetable();

// 预取TLB条目
prefetch_tlb_entry();
}

// 批量kmap优化
int kmap_pages_bulk(struct page **pages, void **vaddrs, int count)
{
int i;
int success_count = 0;

// 预分配映射槽
if (!reserve_kmap_slots(count))
return 0;

// 批量映射
for (i = 0; i < count; i++) {
vaddrs[i] = kmap_atomic(pages[i]);
if (vaddrs[i]) {
success_count++;
} else {
break;
}
}

// 如果失败,回滚已映射的
if (success_count < count) {
for (i = 0; i < success_count; i++) {
kunmap_atomic(vaddrs[i]);
}
release_kmap_slots(success_count);
return 0;
}

return success_count;
}

// 并发优化
void fixmap_concurrency_optimization(void)
{
// 使用CPU本地缓存
enable_per_cpu_fixmap_cache();

// 优化自旋锁
optimize_fixmap_spinlocks();

// 减少原子操作
minimize_atomic_fixmap_ops();
}

// 内存屏障优化
void fixmap_barrier_optimization(unsigned long addr, size_t size)
{
// 根据操作类型选择屏障
if (is_write_operation(addr)) {
// 写操作需要较强的屏障
dsb(ishst);
} else {
// 读操作可以使用较弱的屏障
dsb(ishld);
}

// 指令同步
isb();
}

  性能优化特点:

    1. 缓存机制:固定映射的CPU本地缓存     2. 预取优化:内存访问的预取机制     3. 批量处理:多个映射的批量操作     4. 并发优化:减少锁竞争和原子操作

6. 设计模式分析

6.1 单例模式在固定映射管理中的体现

  固定映射管理的单例模式:

// 固定映射管理器单例类
class FixmapManagerSingleton {
private static FixmapManagerSingleton instance;
private Map<enum fixed_addresses, FixmapEntry> fixmapTable;
private Lock fixmapLock;
private AtomicInteger[] kmapSlots;

private FixmapManagerSingleton() {
fixmapTable = new ConcurrentHashMap<>();
fixmapLock = new ReentrantLock();
kmapSlots = new AtomicInteger[KM_TYPE_NR * NR_CPUS];
initializeFixmapTable();
}

public static FixmapManagerSingleton getInstance() {
if (instance == null) {
synchronized(FixmapManagerSingleton.class) {
if (instance == null) {
instance = new FixmapManagerSingleton();
}
}
}
return instance;
}

public void* setFixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) {
fixmapLock.lock();
try {
// 检查索引有效性
if (!isValidFixmapIndex(idx)) {
throw new IllegalArgumentException("Invalid fixmap index");
}

// 计算虚拟地址
void* vaddr = __fix_to_virt(idx);

// 设置页表
setPageTableEntry(vaddr, phys, prot);

// 更新缓存
updateFixmapCache(idx, vaddr, phys, prot);

return vaddr;
} finally {
fixmapLock.unlock();
}
}

public void clearFixmap(enum fixed_addresses idx) {
fixmapLock.lock();
try {
void* vaddr = __fix_to_virt(idx);
clearPageTableEntry(vaddr);
removeFixmapCache(idx);
} finally {
fixmapLock.unlock();
}
}

public void* kmapAtomic(struct page* page) {
// 获取当前CPU的映射槽
int cpu = getCurrentCpu();
int slot = allocateKmapSlot(cpu);

if (slot == 1) {
return null;
}

// 计算虚拟地址
void* vaddr = calculateKmapVaddr(cpu, slot);

// 建立映射
establishKmapMapping(page, vaddr);

return vaddr;
}

public void kunmapAtomic(void* vaddr) {
int cpu = getCurrentCpu();
int slot = calculateKmapSlot(vaddr);
freeKmapSlot(cpu, slot);
clearKmapMapping(vaddr);
}

private void initializeFixmapTable() {
// 初始化固定映射表
for (enum fixed_addresses idx : enum fixed_addresses.values()) {
fixmapTable.put(idx, new FixmapEntry(idx));
}
}

private boolean isValidFixmapIndex(enum fixed_addresses idx) {
return idx.ordinal() < __end_of_fixed_addresses;
}

private void setPageTableEntry(void* vaddr, phys_addr_t phys, pgprot_t prot) {
// 实现页表设置逻辑
__set_fixmap(virt_to_fix(vaddr), phys, prot);
}

private void clearPageTableEntry(void* vaddr) {
// 实现页表清除逻辑
__clear_fixmap(virt_to_fix(vaddr));
}

private int allocateKmapSlot(int cpu) {
// 分配kmap槽位
for (int i = 0; i < KM_TYPE_NR; i++) {
if (kmapSlots[cpu * KM_TYPE_NR + i].get() == 0) {
if (kmapSlots[cpu * KM_TYPE_NR + i].compareAndSet(0, 1)) {
return i;
}
}
}
return 1;
}

private void freeKmapSlot(int cpu, int slot) {
kmapSlots[cpu * KM_TYPE_NR + slot].set(0);
}
}

// 使用单例模式
class MemoryMappingSystem {
private FixmapManagerSingleton fixmapManager;

public MemoryMappingSystem() {
fixmapManager = FixmapManagerSingleton.getInstance();
}

public void* mapFixedAddress(enum fixed_addresses idx, phys_addr_t phys) {
return fixmapManager.setFixmap(idx, phys, PAGE_KERNEL);
}

public void* mapPageAtomically(struct page* page) {
return fixmapManager.kmapAtomic(page);
}

public void unmapPageAtomically(void* vaddr) {
fixmapManager.kunmapAtomic(vaddr);
}
}

6.2 策略模式在映射策略选择中的体现

  映射策略选择的策略模式:

// 映射策略接口
interface MappingStrategy {
void* mapAddress(Object target, MappingContext context);
void unmapAddress(void* vaddr, MappingContext context);
boolean canHandle(Object target, MappingContext context);
String getStrategyName();
long getMappingLatency();
int getConcurrencyLevel();
}

// 固定映射策略
class FixedMappingStrategy implements MappingStrategy {
public void* mapAddress(Object target, MappingContext context) {
enum fixed_addresses idx = (enum fixed_addresses) target;
phys_addr_t phys = context.getPhysicalAddress();
pgprot_t prot = context.getProtection();

return __set_fixmap(idx, phys, prot);
}

public void unmapAddress(void* vaddr, MappingContext context) {
enum fixed_addresses idx = __virt_to_fix((unsigned long)vaddr);
__clear_fixmap(idx);
}

public boolean canHandle(Object target, MappingContext context) {
return target instanceof enum fixed_addresses;
}

public String getStrategyName() {
return "FIXED_MAPPING_STRATEGY";
}

public long getMappingLatency() {
return 50; // 较低延迟,编译时确定
}

public int getConcurrencyLevel() {
return 1; // 串行访问
}
}

// kmap原子映射策略
class KmapAtomicStrategy implements MappingStrategy {
public void* mapAddress(Object target, MappingContext context) {
struct page* page = (struct page*) target;
return kmap_atomic(page);
}

public void unmapAddress(void* vaddr, MappingContext context) {
kunmap_atomic(vaddr);
}

public boolean canHandle(Object target, MappingContext context) {
return target instanceof struct page && context.isAtomic();
}

public String getStrategyName() {
return "KMAP_ATOMIC_STRATEGY";
}

public long getMappingLatency() {
return 100; // 中等延迟,运行时分配
}

public int getConcurrencyLevel() {
return KM_TYPE_NR; // 支持多种类型
}
}

// kmap本地映射策略
class KmapLocalStrategy implements MappingStrategy {
public void* mapAddress(Object target, MappingContext context) {
struct page* page = (struct page*) target;
return kmap_local_page(page);
}

public void unmapAddress(void* vaddr, MappingContext context) {
kunmap_local(vaddr);
}

public boolean canHandle(Object target, MappingContext context) {
return target instanceof struct page && !context.isAtomic();
}

public String getStrategyName() {
return "KMAP_LOCAL_STRATEGY";
}

public long getMappingLatency() {
return 75; // 较低延迟,本地映射
}

public int getConcurrencyLevel() {
return NR_CPUS; // CPU本地
}
}

// 自适应映射策略
class AdaptiveMappingStrategy implements MappingStrategy {
private List<MappingStrategy> strategies;

public AdaptiveMappingStrategy() {
strategies = Arrays.asList(
new FixedMappingStrategy(),
new KmapAtomicStrategy(),
new KmapLocalStrategy()
);
}

public void* mapAddress(Object target, MappingContext context) {
MappingStrategy bestStrategy = selectBestStrategy(target, context);
return bestStrategy.mapAddress(target, context);
}

public void unmapAddress(void* vaddr, MappingContext context) {
MappingStrategy bestStrategy = selectBestStrategyForUnmap(vaddr, context);
bestStrategy.unmapAddress(vaddr, context);
}

public boolean canHandle(Object target, MappingContext context) {
return strategies.stream().anyMatch(s -> s.canHandle(target, context));
}

public String getStrategyName() {
return "ADAPTIVE_MAPPING_STRATEGY";
}

public long getMappingLatency() {
return 60; // 平均延迟
}

public int getConcurrencyLevel() {
return Integer.MAX_VALUE; // 自适应并发
}

private MappingStrategy selectBestStrategy(Object target, MappingContext context) {
return strategies.stream()
.filter(s -> s.canHandle(target, context))
.min(Comparator.comparingLong(MappingStrategy::getMappingLatency))
.orElse(new KmapLocalStrategy());
}

private MappingStrategy selectBestStrategyForUnmap(void* vaddr, MappingContext context) {
// 根据地址类型确定解除映射策略
if (is_fixed_addr(vaddr)) {
return new FixedMappingStrategy();
} else if (context.isAtomic()) {
return new KmapAtomicStrategy();
} else {
return new KmapLocalStrategy();
}
}
}

// 策略选择器
class MappingStrategySelector {
public static MappingStrategy selectStrategy(MappingRequirements reqs) {
if (reqs.requiresAdaptiveMapping()) {
return new AdaptiveMappingStrategy();
} else if (reqs.isFixedMapping()) {
return new FixedMappingStrategy();
} else if (reqs.isAtomicMapping()) {
return new KmapAtomicStrategy();
} else {
return new KmapLocalStrategy();
}
}
}

6.3 观察者模式在映射监控中的体现

  映射监控的观察者模式:

// 映射操作事件接口
interface MappingOperationEvent {
String getEventType();
long getTimestamp();
void* getVirtualAddress();
phys_addr_t getPhysicalAddress();
enum mapping_type getMappingType();
Map<String, Object> getEventData();
boolean isSuccessful();
long getOperationDuration();
}

// 映射操作事件
class MappingOperationEventImpl implements MappingOperationEvent {
private String eventType;
private long timestamp;
private void* vaddr;
private phys_addr_t paddr;
private enum mapping_type mappingType;
private Map<String, Object> eventData;
private boolean successful;
private long duration;

public MappingOperationEventImpl(String eventType, void* vaddr, phys_addr_t paddr,
enum mapping_type mappingType, boolean successful,
long duration, Map<String, Object> eventData) {
this.eventType = eventType;
this.timestamp = System.nanoTime();
this.vaddr = vaddr;
this.paddr = paddr;
this.mappingType = mappingType;
this.successful = successful;
this.duration = duration;
this.eventData = eventData != null ? eventData : new HashMap<>();
}

public String getEventType() {
return eventType;
}

public long getTimestamp() {
return timestamp;
}

public void* getVirtualAddress() {
return vaddr;
}

public phys_addr_t getPhysicalAddress() {
return paddr;
}

public enum mapping_type getMappingType() {
return mappingType;
}

public Map<String, Object> getEventData() {
return eventData;
}

public boolean isSuccessful() {
return successful;
}

public long getOperationDuration() {
return duration;
}
}

// 映射操作观察者接口
interface MappingOperationObserver {
void onMappingOperationEvent(MappingOperationEvent event);
Set<String> getInterestedEventTypes();
boolean isEnabled();
}

// 性能监控观察者
class MappingPerformanceObserver implements MappingOperationObserver {
private Map<String, Long> operationTimes = new HashMap<>();
private Map<String, Integer> operationCounts = new HashMap<>();

public void onMappingOperationEvent(MappingOperationEvent event) {
if (event.isSuccessful()) {
String opType = event.getMappingType().name();

// 记录操作时间
operationTimes.put(opType,
operationTimes.getOrDefault(opType, 0L) + event.getOperationDuration());

// 记录操作次数
operationCounts.put(opType,
operationCounts.getOrDefault(opType, 0) + 1);
}
}

public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("MAPPING_OPERATION", "UNMAPPING_OPERATION"));
}

public boolean isEnabled() {
return true;
}

public double getAverageMappingTime(String mappingType) {
Long totalTime = operationTimes.get(mappingType);
Integer count = operationCounts.get(mappingType);

if (totalTime != null && count != null && count > 0) {
return totalTime.doubleValue() / count;
}
return 0.0;
}
}

// 安全监控观察者
class MappingSecurityObserver implements MappingOperationObserver {
private List<String> securityEvents = Collections.synchronizedList(new ArrayList<>());

public void onMappingOperationEvent(MappingOperationEvent event) {
// 检查潜在的安全问题
void* vaddr = event.getVirtualAddress();
phys_addr_t paddr = event.getPhysicalAddress();
enum mapping_type type = event.getMappingType();

// 检查映射到敏感区域
if (isSensitiveVirtualRegion(vaddr) && type != MAPPING_FIXED) {
logSecurityEvent("Mapping to sensitive virtual region: " + vaddr);
}

// 检查物理地址安全
if (!isSafePhysicalAddress(paddr)) {
logSecurityEvent("Mapping unsafe physical address: " + paddr);
}

// 检查映射类型一致性
if (!isConsistentMappingType(vaddr, paddr, type)) {
logSecurityEvent("Inconsistent mapping type for address: " + vaddr);
}

// 检查映射权限
if (!validateMappingPermissions(vaddr, type)) {
logSecurityEvent("Invalid mapping permissions for: " + vaddr);
}
}

public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("*"));
}

public boolean isEnabled() {
return true;
}

private boolean isSensitiveVirtualRegion(void* vaddr) {
unsigned long addr = (unsigned long)vaddr;
return addr >= KERNEL_TEXT_START && addr < KERNEL_TEXT_END;
}

private boolean isSafePhysicalAddress(phys_addr_t paddr) {
return paddr != 0 && paddr < MAX_PHYS_ADDR;
}

private boolean isConsistentMappingType(void* vaddr, phys_addr_t paddr, enum mapping_type type) {
// 检查映射类型与地址范围的一致性
return true; // 简化的检查逻辑
}

private boolean validateMappingPermissions(void* vaddr, enum mapping_type type) {
// 验证映射权限
return true; // 简化的权限检查
}

private void logSecurityEvent(String event) {
securityEvents.add(event);
System.err.println("MAPPING SECURITY: " + event);
}

public List<String> getSecurityEvents() {
return new ArrayList<>(securityEvents);
}
}

// 资源使用观察者
class MappingResourceObserver implements MappingOperationObserver {
private AtomicLong activeMappings = new AtomicLong(0);
private Map<String, AtomicLong> mappingTypeCounts = new ConcurrentHashMap<>();

public void onMappingOperationEvent(MappingOperationEvent event) {
String eventType = event.getEventType();
String mappingType = event.getMappingType().name();

if ("MAPPING_OPERATION".equals(eventType) && event.isSuccessful()) {
activeMappings.incrementAndGet();
mappingTypeCounts.computeIfAbsent(mappingType, k -> new AtomicLong(0)).incrementAndGet();
} else if ("UNMAPPING_OPERATION".equals(eventType)) {
activeMappings.decrementAndGet();
AtomicLong typeCount = mappingTypeCounts.get(mappingType);
if (typeCount != null) {
typeCount.decrementAndGet();
}
}
}

public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("MAPPING_OPERATION", "UNMAPPING_OPERATION"));
}

public boolean isEnabled() {
return true;
}

public long getActiveMappings() {
return activeMappings.get();
}

public long getMappingsByType(String type) {
AtomicLong count = mappingTypeCounts.get(type);
return count != null ? count.get() : 0;
}
}

// 映射监控器
class MappingOperationMonitor {
private List<MappingOperationObserver> observers = new CopyOnWriteArrayList<>();
private Executor notificationExecutor;

public MappingOperationMonitor() {
this.notificationExecutor = Executors.newSingleThreadExecutor();
}

public void addObserver(MappingOperationObserver observer) {
observers.add(observer);
}

public void removeObserver(MappingOperationObserver observer) {
observers.remove(observer);
}

public void notifyMappingOperationEvent(MappingOperationEvent event) {
notificationExecutor.submit(() -> {
for (MappingOperationObserver observer : observers) {
if (observer.isEnabled()) {
Set<String> interestedTypes = observer.getInterestedEventTypes();

if (interestedTypes.contains("*") ||
interestedTypes.contains(event.getEventType())) {
try {
observer.onMappingOperationEvent(event);
} catch (Exception e) {
logObserverError(observer, event, e);
}
}
}
}
});
}

public void mappingOperationPerformed(void* vaddr, phys_addr_t paddr, enum mapping_type type,
String operationType, boolean successful, long duration,
Map<String, Object> eventData) {
MappingOperationEvent event = new MappingOperationEventImpl(operationType, vaddr, paddr,
type, successful, duration, eventData);
notifyMappingOperationEvent(event);
}

public void shutdown() {
notificationExecutor.shutdown();
try {
if (!notificationExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
notificationExecutor.shutdownNow();
}
} catch (InterruptedException e) {
notificationExecutor.shutdownNow();
}
}

private void logObserverError(MappingOperationObserver observer, MappingOperationEvent event, Exception e) {
System.err.println("Mapping operation observer error: " + observer.getClass().getSimpleName() +
" failed to process event " + event.getEventType() + ": " + e.getMessage());
}
}

// 使用观察者模式
class MappingManagementSystem {
private MappingOperationMonitor monitor;

public MappingManagementSystem() {
this.monitor = new MappingOperationMonitor();

// 注册观察者
monitor.addObserver(new MappingPerformanceObserver());
monitor.addObserver(new MappingSecurityObserver());
monitor.addObserver(new MappingResourceObserver());
}

public void* setFixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) {
long startTime = System.nanoTime();

// 执行固定映射
void* vaddr = __set_fixmap(idx, phys, prot);

long duration = System.nanoTime() startTime;

// 通知映射事件
Map<String, Object> eventData = new HashMap<>();
eventData.put("index", idx);

monitor.mappingOperationPerformed(vaddr, phys, MAPPING_FIXED,
"SET_FIXMAP", vaddr != null, duration, eventData);

return vaddr;
}

public void* kmapAtomic(struct page* page) {
long startTime = System.nanoTime();

// 执行原子映射
void* vaddr = kmap_atomic(page);

long duration = System.nanoTime() startTime;

// 通知映射事件
Map<String, Object> eventData = new HashMap<>();
eventData.put("page", page);

monitor.mappingOperationPerformed(vaddr, page_to_phys(page), MAPPING_KMAP,
"KMAP_ATOMIC", vaddr != null, duration, eventData);

return vaddr;
}
}

7. 状态机分析

  ARM64 mm fixmap的状态机:

初始状态 -> 映射类型判断 -> 索引分配 -> 页表设置 -> TLB刷新 -> 映射激活
↑ ↓
地址验证 <———————————————————————————+
↑ ↓
权限检查 <———————————————————————————+
↑ ↓
安全审计 <———————————————————————————+

8. 性能优化分析

8.1 固定映射性能优化

  固定映射的性能优化:

// 固定映射快速路径
void* fast_fixmap_access(enum fixed_addresses idx)
{
// 检查是否已缓存
if (fixmap_cache_valid[idx]) {
return fixmap_cache[idx];
}

// 慢速路径
return __fix_to_virt(idx);
}

// 批量固定映射设置
int set_fixmaps_bulk(struct fixmap_entry *entries, int count)
{
int i;
int success_count = 0;

// 开始批处理
start_fixmap_batch();

// 批量设置
for (i = 0; i < count; i++) {
if (set_fixmap_single(&entries[i]) == 0) {
success_count++;
} else {
break;
}
}

// 结束批处理
end_fixmap_batch();

// 如果失败,回滚
if (success_count < count) {
rollback_fixmaps(entries, success_count);
return EFAULT;
}

return 0;
}

// kmap并发优化
void kmap_concurrency_optimize(void)
{
// 使用CPU本地存储
enable_kmap_percpu();

// 减少锁竞争
optimize_kmap_locks();

// 预分配映射槽
preallocate_kmap_slots();
}

// 预取优化
void fixmap_prefetch_optimize(unsigned long addr, size_t size)
{
// 预取页表条目
prefetch_pagetable_entries(addr, size);

// 预取固定映射区域
prefetch_fixmap_region(addr, size);

// 预取TLB
prefetch_tlb_entries(addr, size);
}

8.2 缓存一致性优化

  缓存一致性的优化:

// 缓存一致性智能维护
void smart_cache_coherency(void *vaddr, size_t size, enum mapping_operation op)
{
// 分析访问模式
enum access_pattern pattern = analyze_access_pattern(vaddr, size);

switch (pattern) {
case ACCESS_SEQUENTIAL:
// 顺序访问优化
cache_coherency_sequential(vaddr, size, op);
break;

case ACCESS_RANDOM:
// 随机访问优化
cache_coherency_random(vaddr, size, op);
break;

case ACCESS_STRIDED:
// 跨步访问优化
cache_coherency_strided(vaddr, size, op);
break;

default:
// 默认一致性维护
default_cache_coherency(vaddr, size, op);
break;
}
}

// TLB刷新优化
void optimized_tlb_flush(void *vaddr, size_t size)
{
// 检查是否需要全局刷新
if (size > TLB_FLUSH_THRESHOLD) {
flush_tlb_all();
} else {
flush_tlb_kernel_range((unsigned long)vaddr,
(unsigned long)vaddr + size);
}
}

// 内存屏障选择优化
void select_memory_barrier(enum mapping_operation op, enum access_type type)
{
switch (op) {
case MAPPING_SET:
// 设置映射的屏障
if (type == ACCESS_WRITE) {
dsb(ishst); // 存储屏障
} else {
dsb(ish); // 一般屏障
}
break;

case MAPPING_CLEAR:
// 清除映射的屏障
dsb(ish);
break;

case MAPPING_UPDATE:
// 更新映射的屏障
dsb(ish);
isb(); // 指令同步
break;
}
}

9. 安全性考虑

9.1 映射访问控制

  映射访问的安全控制:

// 映射访问权限验证
int validate_mapping_access(void *vaddr, size_t size, unsigned long flags)
{
// 验证地址类型
if (!validate_addr_type(vaddr))
return EINVAL;

// 检查访问权限
if (!check_access_permissions(vaddr, flags))
return EACCES;

// 验证映射状态
if (!validate_mapping_state(vaddr))
return EFAULT;

// 安全边界检查
if (!check_security_boundaries(vaddr, size))
return EPERM;

return 0;
}

// 地址类型验证
static bool validate_addr_type(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;

// 检查是否为固定映射地址
if (addr >= FIXADDR_START && addr < FIXADDR_TOP)
return true;

// 检查是否为kmap地址
if (is_kmap_addr(addr))
return true;

return false;
}

// 访问权限检查
static bool check_access_permissions(void *vaddr, unsigned long flags)
{
// 检查内核访问权限
if (!capable(CAP_SYS_RAWIO))
return false;

// 检查映射特权
if (!has_mapping_privilege(vaddr, flags))
return false;

return true;
}

// 映射状态验证
static bool validate_mapping_state(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;

// 检查PTE是否存在
pte_t *pte = virt_to_kpte(addr);
if (!pte || !pte_present(*pte))
return false;

// 检查映射权限
if (!pte_access_permitted(*pte))
return false;

return true;
}

// 安全边界检查
static bool check_security_boundaries(void *vaddr, size_t size)
{
// 检查是否跨越安全区域边界
if (crosses_security_region(vaddr, size))
return false;

// 检查是否访问敏感数据
if (accesses_sensitive_data(vaddr, size))
return false;

return true;
}

9.2 映射完整性保护

  映射完整性的保护:

// 映射完整性验证
int verify_mapping_integrity(void *vaddr, phys_addr_t expected_phys)
{
phys_addr_t actual_phys = __virt_to_phys((unsigned long)vaddr);

// 比较物理地址
if (actual_phys != expected_phys) {
// 记录完整性错误
log_integrity_error(vaddr, expected_phys, actual_phys);
return EFAULT;
}

// 验证页表一致性
if (!verify_pagetable_consistency(vaddr)) {
return EFAULT;
}

// 验证TLB一致性
if (!verify_tlb_consistency(vaddr)) {
return EFAULT;
}

return 0;
}

// 页表一致性验证
static bool verify_pagetable_consistency(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;
pte_t *pte = virt_to_kpte(addr);

if (!pte)
return false;

// 检查PTE标记
if (!pte_present(*pte))
return false;

// 检查权限一致性
if (!pte_flags_consistent(*pte))
return false;

return true;
}

// 映射攻击防护
void prevent_mapping_attacks(void)
{
// 随机化固定映射位置
randomize_fixmap_locations();

// 启用映射访问审计
enable_mapping_audit();

// 设置映射访问限制
setup_mapping_access_limits();

// 监控异常映射模式
monitor_suspicious_mappings();
}

// 映射访问审计
void audit_mapping_access(void *vaddr, size_t size, unsigned long flags)
{
// 记录审计信息
audit_log(AUDIT_MAPPING_ACCESS, current->pid,
(unsigned long)vaddr, size, flags);
}

10. 扩展性分析

10.1 多架构支持

  跨架构的固定映射扩展:

// 架构特定的固定映射接口
struct arch_fixmap_ops {
const char *arch_name;

// 固定映射操作
void (*set_fixmap)(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
void (*clear_fixmap)(enum fixed_addresses idx);
void *(*__fix_to_virt)(const unsigned int idx);
unsigned long (*__virt_to_fix)(unsigned long vaddr);

// kmap操作
void *(*kmap_atomic)(struct page *page);
void (*kunmap_atomic)(void *vaddr);
void *(*kmap_local_page)(struct page *page);
void (*kunmap_local)(void *vaddr);

// 地址空间定义
unsigned long (*fixmap_start)(void);
unsigned long (*fixmap_end)(void);
unsigned long (*fixmap_size)(void);
};

// ARM64固定映射操作实现
static const struct arch_fixmap_ops arm64_fixmap_ops = {
.arch_name = "arm64",
.set_fixmap = arm64_set_fixmap,
.clear_fixmap = arm64_clear_fixmap,
.__fix_to_virt = arm64__fix_to_virt,
.__virt_to_fix = arm64__virt_to_fix,
.kmap_atomic = arm64_kmap_atomic,
.kunmap_atomic = arm64_kunmap_atomic,
.kmap_local_page = arm64_kmap_local_page,
.kunmap_local = arm64_kunmap_local,
.fixmap_start = arm64_fixmap_start,
.fixmap_end = arm64_fixmap_end,
.fixmap_size = arm64_fixmap_size,
};

// 运行时架构选择
static const struct arch_fixmap_ops *select_arch_fixmap_ops(void)
{
#ifdef CONFIG_ARM64
return &arm64_fixmap_ops;
#else
return NULL;
#endif
}

10.2 功能扩展

  固定映射功能扩展:

// 高级固定映射功能扩展
struct advanced_fixmap_features {
bool support_dynamic_fixmap; // 支持动态固定映射
bool support_secure_fixmap; // 支持安全固定映射
bool support_fixmap_caching; // 支持固定映射缓存
bool support_bulk_fixmap_ops; // 支持批量固定映射操作
bool support_fixmap_monitoring; // 支持固定映射监控
bool support_fixmap_auditing; // 支持固定映射审计
};

// 固定映射扩展API
struct extended_fixmap_api {
// 动态固定映射支持
int (*alloc_dynamic_fixmap)(phys_addr_t phys, pgprot_t prot);
int (*free_dynamic_fixmap)(void *vaddr);
int (*query_dynamic_fixmap)(void *vaddr, struct fixmap_info *info);

// 安全固定映射支持
int (*set_secure_fixmap)(enum fixed_addresses idx, phys_addr_t phys,
struct security_context *ctx);
int (*validate_secure_fixmap)(enum fixed_addresses idx);
int (*audit_secure_fixmap_access)(enum fixed_addresses idx);

// 固定映射缓存支持
int (*enable_fixmap_caching)(void);
int (*disable_fixmap_caching)(void);
int (*flush_fixmap_cache)(void);
int (*query_fixmap_cache_stats)(struct cache_stats *stats);

// 批量操作支持
int (*set_fixmaps_bulk)(struct fixmap_entry *entries, int count);
int (*clear_fixmaps_bulk)(enum fixed_addresses *indices, int count);
int (*query_fixmaps_bulk)(enum fixed_addresses *indices,
struct fixmap_info *infos, int count);

// 监控和审计支持
int (*enable_fixmap_monitoring)(struct monitor_config *config);
int (*disable_fixmap_monitoring)(void);
int (*get_fixmap_monitor_report)(struct monitor_report *report);
int (*audit_fixmap_operations)(struct audit_context *ctx);
};

11. 调试和维护

11.1 固定映射调试支持

  固定映射调试支持:

// 固定映射调试宏
#define FIXMAP_DEBUG(fmt, ...) \\
pr_debug("FIXMAP: " fmt, ##__VA_ARGS__)

#define FIXMAP_DEBUG_SET(idx, phys) \\
FIXMAP_DEBUG("setting fixmap %d to %pa\\n", idx, &phys)

#define FIXMAP_DEBUG_KMAP(page, vaddr) \\
FIXMAP_DEBUG("kmapping page %p to %p\\n", page, vaddr)

// 详细调试模式
#ifdef CONFIG_FIXMAP_DEBUG
static void fixmap_debug_operation(enum fixed_addresses idx, phys_addr_t phys,
const char *op_type)
{
FIXMAP_DEBUG("=== FIXMAP DEBUG ===");
FIXMAP_DEBUG("Operation: %s", op_type);
FIXMAP_DEBUG("Index: %d", idx);
FIXMAP_DEBUG("Physical: %pa", &phys);
FIXMAP_DEBUG("Virtual: %p", __fix_to_virt(idx));

// 调试页表状态
debug_pagetable_state(__fix_to_virt(idx));

// 调试TLB状态
debug_tlb_state(__fix_to_virt(idx));

FIXMAP_DEBUG("=== END FIXMAP DEBUG ===");
}
#endif

11.2 错误检测和恢复

  固定映射错误处理:

// 固定映射错误检测
int detect_fixmap_errors(enum fixed_addresses idx, phys_addr_t phys)
{
void *vaddr = __fix_to_virt(idx);

// 检查地址有效性
if (!virt_addr_valid(vaddr))
return EINVAL;

// 验证映射一致性
if (!verify_fixmap_consistency(idx, phys))
return EFAULT;

// 检查页表状态
if (!validate_pagetable_state(vaddr))
return EFAULT;

return 0;
}

// 错误恢复机制
int recover_fixmap_error(enum fixed_addresses idx, phys_addr_t phys, int error)
{
FIXMAP_DEBUG("Attempting fixmap error recovery: %d\\n", error);

switch (error) {
case EINVAL:
// 地址错误:验证索引范围
return validate_fixmap_index(idx);

case EFAULT:
// 映射错误:重新建立映射
return recreate_fixmap_mapping(idx, phys);

default:
FIXMAP_DEBUG("Unrecoverable fixmap error\\n");
return error;
}
}

// 映射一致性验证
static bool verify_fixmap_consistency(enum fixed_addresses idx, phys_addr_t expected_phys)
{
void *vaddr = __fix_to_virt(idx);
phys_addr_t actual_phys = __virt_to_phys((unsigned long)vaddr);

return actual_phys == expected_phys;
}

// 页表状态验证
static bool validate_pagetable_state(void *vaddr)
{
pte_t *pte = virt_to_kpte((unsigned long)vaddr);

if (!pte)
return false;

// 检查PTE存在
if (!pte_present(*pte))
return false;

// 检查权限
if (!pte_access_permitted(*pte))
return false;

return true;
}

12. 总结

  ARM64 mm fixmap子模块作为ARM64内存管理子系统中固定映射管理的核心组件,通过完整的编译时固定映射、kmap原子映射和临时映射功能,为ARM64平台提供了稳定高效的固定地址访问。该模块实现了固定地址的静态分配、运行时的动态映射、页表的一致性维护等高级特性,在保证映射稳定性的同时提供了灵活的临时访问接口。源码分析显示,模块采用了单例模式、策略模式和观察者模式等多种设计模式,为固定映射管理提供了灵活可靠的实现框架。

赞(0)
未经允许不得转载:171主机测评 » Linux6.19-ARM64 mm fixmap子模块深入分析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址