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

文章目录

  • [1. 概述](#1. 概述)
  • [2. 软件架构图](#2. 软件架构图)
  • [3. 调用流程图](#3. 调用流程图)
  • [4. UML类图](#4. UML类图)
  • [5. 源码深度分析](#5. 源码深度分析)
    • [5.1 ARM64 MMU架构分析](#5.1 ARM64 MMU架构分析)
      • [5.1.1 ARM64页表结构](#5.1.1 ARM64页表结构)
      • [5.1.2 页表分配和管理](#5.1.2 页表分配和管理)
    • [5.2 地址映射实现分析](#5.2 地址映射实现分析)
      • [5.2.1 页表条目设置](#5.2.1 页表条目设置)
      • [5.2.2 页表遍历和查找](#5.2.2 页表遍历和查找)
    • [5.3 性能优化技术分析](#5.3 性能优化技术分析)
      • [5.3.1 页表预分配优化](#5.3.1 页表预分配优化)
      • [5.3.2 TLB和缓存优化](#5.3.2 TLB和缓存优化)
  • [6. 设计模式分析](#6. 设计模式分析)
    • [6.1 工厂模式在页表分配中的体现](#6.1 工厂模式在页表分配中的体现)
    • [6.2 策略模式在地址映射中的体现](#6.2 策略模式在地址映射中的体现)
    • [6.3 组合模式在页表层次中的体现](#6.3 组合模式在页表层次中的体现)
  • [7. 状态机分析](#7. 状态机分析)
  • [8. 性能优化分析](#8. 性能优化分析)
    • [8.1 页表缓存优化](#8.1 页表缓存优化)
    • [8.2 地址转换优化](#8.2 地址转换优化)
  • [9. 安全性考虑](#9. 安全性考虑)
    • [9.1 页表完整性保护](#9.1 页表完整性保护)
    • [9.2 地址空间隔离](#9.2 地址空间隔离)
  • [10. 扩展性分析](#10. 扩展性分析)
    • [10.1 多架构支持](#10.1 多架构支持)
    • [10.2 功能扩展](#10.2 功能扩展)
  • [11. 调试和维护](#11. 调试和维护)
    • [11.1 MMU调试支持](#11.1 MMU调试支持)
    • [11.2 错误检测和恢复](#11.2 错误检测和恢复)
  • [12. 总结](#12. 总结)

团队博客: 汽车电子社区


1. 概述

ARM64 mm mmu子模块是Linux内核ARM64架构内存管理子系统中实现内存管理单元的核心组件,包含mmu.c文件。该模块作为ARM64平台MMU管理的核心实现,提供了完整的页表创建、地址映射、页表遍历和MMU上下文管理的功能,是ARM64内存管理系统的"心脏"和基础架构。

mmu子模块实现了ARM64架构下最关键的内存管理逻辑,包括多级页表的创建和维护、虚拟地址到物理地址的映射关系、页表项的权限控制和属性设置。该模块作为内存管理系统的核心,为ARM64平台提供了高效可靠的地址转换和内存访问控制,是现代操作系统内存虚拟化的基石。

模块的设计体现了内存管理单元的复杂性和高性能要求,通过精心设计的页表结构和地址转换算法,在保证内存访问安全性的同时实现了接近硬件极限的地址转换性能,是ARM64内存子系统架构设计的典范。

2. 软件架构图

ARM64 mm mmu
页表管理
地址映射
页表遍历
MMU上下文
mmu.c
多级页表
页表分配
页表释放
地址转换
映射建立
映射解除
页表查找
页表修改
页表同步
ASID管理
TLB管理
缓存一致性

3. 调用流程图











内存管理请求
检查页表层次
PGD存在?
分配PGD
检查P4D
P4D存在?
分配P4D
检查PUD
PUD存在?
分配PUD
检查PMD
PMD存在?
分配PMD
检查PTE
PTE存在?
分配PTE页面
设置PTE值
更新TLB
同步操作
完成映射

4. UML类图

MMUManager
+alloc_init_pgd()
+pgd_alloc()
+pgd_free()
+set_pgd()
+pmd_alloc_one()
+pte_alloc_one()
PageTableManager
+pgd_offset()
+p4d_offset()
+pud_offset()
+pmd_offset()
+pte_offset()
+pte_offset_map()
AddressMapping
+set_pte_at()
+set_pmd_at()
+set_pud_at()
+set_p4d_at()
+pte_clear()
+pmd_clear()
MemoryBarrier
+dsb_ish()
+dsb_sy()
+isb()
+tlb_flush()
PageTableEntry
+pte_val()
+pmd_val()
+pud_val()
+p4d_val()
+pte_set()
+pmd_set()
TLBManager
+flush_tlb_all()
+flush_tlb_mm()
+flush_tlb_page()
+flush_tlb_range()
PermissionManager
+pte_mkwrite()
+pte_mkread()
+pte_mkexec()
+pte_mkdirty()
+pte_mkclean()

5. 源码深度分析

5.1 ARM64 MMU架构分析

5.1.1 ARM64页表结构

ARM64页表的层次结构和组织方式:

c 复制代码
// ARM64页表层次定义

// 页全局目录 (Page Global Directory)
typedef struct { pgdval_t pgd; } pgd_t;

// 页上级目录 (Page Upper Directory) - ARM64特有
typedef struct { p4dval_t p4d; } p4d_t;

// 页上级目录 (Page Upper Directory)
typedef struct { pudval_t pud; } pud_t;

// 页中间目录 (Page Middle Directory)
typedef struct { pmdval_t pmd; } pmd_t;

// 页表条目 (Page Table Entry)
typedef struct { pteval_t pte; } pte_t;

// 页表大小定义
#define PTRS_PER_PGD     512   // 每个PGD包含512个条目
#define PTRS_PER_P4D     512   // 每个P4D包含512个条目(ARM64中通常与PGD相同)
#define PTRS_PER_PUD     512   // 每个PUD包含512个条目
#define PTRS_PER_PMD     512   // 每个PMD包含512个条目
#define PTRS_PER_PTE     512   // 每个PTE页面包含512个条目

// 页面大小
#define PAGE_SIZE        4096  // 标准页面大小
#define PMD_SIZE         (PTRS_PER_PMD * PAGE_SIZE)     // PMD覆盖的大小
#define PUD_SIZE         (PTRS_PER_PUD * PMD_SIZE)      // PUD覆盖的大小
#define PGDIR_SIZE       (PTRS_PER_PGD * PUD_SIZE)      // PGD覆盖的大小

// ARM64特有的页表配置
#define ARM64_HW_PGTABLE_LEVELS  4  // ARM64硬件支持4级页表
#define ARM64_SW_PGTABLE_LEVELS  4  // 软件使用的页表级别

页表层次特点

1. 4级页表 :ARM64使用完整的4级页表结构

2. 512个条目 :每级页表包含512个指针

3. 灵活配置 :支持不同页面大小的配置

4. ARM64扩展:包含P4D层级以支持未来扩展

5.1.2 页表分配和管理

页表的分配和管理核心函数:

c 复制代码
// PGD分配函数
pgd_t *pgd_alloc(struct mm_struct *mm)
{
    pgd_t *pgd;
    p4d_t *p4d;
    pud_t *pud;
    pmd_t *pmd;
    pte_t *pte;
    
    // 分配PGD页面
    pgd = (pgd_t *)__get_free_page(GFP_PGTABLE_KERNEL);
    if (!pgd)
        return NULL;
    
    // 初始化PGD
    memset(pgd, 0, PAGE_SIZE);
    
    // 对于ARM64,PGD和P4D通常是相同的
    // 预分配必要的页表层次以提高性能
    
    // 为内核空间预分配页表(如果需要)
    if (likely(mm == &init_mm)) {
        // 初始化内存的页表已经预分配
        memcpy(pgd, swapper_pg_dir, PAGE_SIZE);
    } else {
        // 为用户空间初始化
        pgd_val(*pgd) = ARM64_INVALID_PGD;
    }
    
    return pgd;
}

// PGD释放函数
void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
    // 清理页表条目
    pgd_clear_bad(pgd);
    
    // 释放PGD页面
    free_page((unsigned long)pgd);
}

// PMD分配函数
pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
    struct page *page;
    pmd_t *pmd;
    
    // 分配页面
    page = alloc_page(GFP_PGTABLE_USER);
    if (!page)
        return NULL;
    
    // 初始化PMD
    pmd = (pmd_t *)page_address(page);
    memset(pmd, 0, PAGE_SIZE);
    
    // 设置页面标记
    if (paravirt_enabled()) {
        // 虚拟化环境下的特殊处理
        paravirt_alloc_pmd(mm, addr);
    }
    
    return pmd;
}

// PTE分配函数
pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long addr)
{
    struct page *page;
    pte_t *pte;
    
    // 分配页面
    page = alloc_page(GFP_PGTABLE_USER);
    if (!page)
        return NULL;
    
    // 初始化PTE
    pte = (pte_t *)page_address(page);
    memset(pte, 0, PAGE_SIZE);
    
    // 设置页面标记
    __SetPageTable(page);
    
    return pte;
}

页表管理特点

1. 层次化分配 :按需分配各级页表

2. 内存池优化 :使用专门的页表内存池

3. 初始化优化 :预初始化常用页表

4. 虚拟化支持:Xen/KVM虚拟化的特殊处理

5.2 地址映射实现分析

5.2.1 页表条目设置

页表条目的设置和权限管理:

c 复制代码
// PTE设置函数
void set_pte_at(struct mm_struct *mm, unsigned long addr,
               pte_t *ptep, pte_t pte)
{
    // 验证地址对齐
    WARN_ON(!pte_present(pte) && !pte_none(pte));
    
    // 设置PTE值
    if (sizeof(pteval_t) > sizeof(long)) {
        // 64位PTE的原子设置
        set_pte_atomic(ptep, pte);
    } else {
        // 32位PTE的设置
        *ptep = pte;
    }
    
    // TLB维护
    if (pte_present(pte)) {
        // 页面存在,更新TLB
        update_mmu_cache(mm, addr, ptep);
    } else {
        // 页面不存在,无需TLB更新
    }
}

// PMD设置函数
void set_pmd_at(struct mm_struct *mm, unsigned long addr,
               pmd_t *pmdp, pmd_t pmd)
{
    // PMD设置逻辑
    if (pmd_large(pmd)) {
        // 大页面的特殊处理
        set_pmd_safe(pmdp, pmd);
    } else {
        // 普通PMD设置
        *pmdp = pmd;
    }
    
    // TLB同步
    flush_tlb_range(mm, addr, addr + PMD_SIZE);
}

// 页面权限设置函数
pte_t pte_mkwrite(pte_t pte)
{
    // 设置写权限
    pte_val(pte) |= L_PTE_WRITE;
    return pte;
}

pte_t pte_mkread(pte_t pte)
{
    // 设置读权限
    pte_val(pte) |= L_PTE_READ;
    return pte;
}

pte_t pte_mkexec(pte_t pte)
{
    // 设置执行权限
    pte_val(pte) |= L_PTE_EXEC;
    return pte;
}

pte_t pte_mkdirty(pte_t pte)
{
    // 标记页面为脏
    pte_val(pte) |= L_PTE_DIRTY;
    return pte;
}

pte_t pte_mkclean(pte_t pte)
{
    // 清除脏标记
    pte_val(pte) &= ~L_PTE_DIRTY;
    return pte;
}

权限管理特点

1. 原子操作 :大PTE的原子设置保证一致性

2. 权限控制 :精确的读写执行权限管理

3. 状态跟踪 :页面脏状态的维护

4. TLB同步:映射变化后的TLB更新

5.2.2 页表遍历和查找

页表的遍历和查找算法:

c 复制代码
// 页表偏移计算函数
pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
{
    // 计算PGD索引
    unsigned long index = pgd_index(address);
    
    // 返回PGD条目指针
    return mm->pgd + index;
}

p4d_t *p4d_offset(pgd_t *pgd, unsigned long address)
{
    // ARM64中P4D通常与PGD相同
    if (pgd_none(*pgd)) {
        return (p4d_t *)pgd;
    }
    
    // 计算P4D索引
    unsigned long index = p4d_index(address);
    
    // 返回P4D条目指针
    p4d_t *p4d = p4d_offset(pgd, address);
    return p4d;
}

pud_t *pud_offset(p4d_t *p4d, unsigned long address)
{
    // 检查是否为大页
    if (p4d_large(*p4d)) {
        return (pud_t *)p4d;
    }
    
    // 计算PUD索引
    unsigned long index = pud_index(address);
    
    // 获取PUD页表
    pud_t *pud = pud_offset(p4d, address);
    return pud;
}

pmd_t *pmd_offset(pud_t *pud, unsigned long address)
{
    // 检查是否为大页
    if (pud_large(*pud)) {
        return (pmd_t *)pud;
    }
    
    // 计算PMD索引
    unsigned long index = pmd_index(address);
    
    // 获取PMD页表
    pmd_t *pmd = pmd_offset(pud, address);
    return pmd;
}

pte_t *pte_offset(pmd_t *pmd, unsigned long address)
{
    // 检查是否为大页
    if (pmd_large(*pmd)) {
        return (pte_t *)pmd;
    }
    
    // 计算PTE索引
    unsigned long index = pte_index(address);
    
    // 获取PTE页表
    pte_t *pte = pte_offset(pmd, address);
    return pte;
}

// 页表查找和映射
pte_t *pte_offset_map(pmd_t *pmd, unsigned long address)
{
    pte_t *pte;
    
    // 获取PTE指针
    pte = pte_offset(pmd, address);
    
    // 映射PTE页面(处理锁)
    pte = pte_offset_map_lock(mm, pmd, address, &ptl);
    
    return pte;
}

页表遍历特点

1. 层次索引 :每级页表的索引计算

2. 大页支持 :大页面的特殊处理路径

3. 锁管理 :页表锁的获取和释放

4. 内存映射:PTE页面的临时映射

5.3 性能优化技术分析

5.3.1 页表预分配优化

页表的预分配和缓存优化:

c 复制代码
// 页表预分配策略
#define PGD_PREALLOC_SIZE    16    // 预分配的PGD数量
#define PMD_PREALLOC_SIZE    64    // 预分配的PMD数量
#define PTE_PREALLOC_SIZE   128    // 预分配的PTE数量

// 页表缓存
struct pgtable_cache {
    struct page *pgd_cache[PGD_PREALLOC_SIZE];
    struct page *pmd_cache[PMD_PREALLOC_SIZE];
    struct page *pte_cache[PTE_PREALLOC_SIZE];
    
    spinlock_t lock;
    int pgd_count;
    int pmd_count;
    int pte_count;
};

// 从缓存分配PGD
pgd_t *pgd_alloc_cached(struct mm_struct *mm)
{
    struct page *page;
    
    // 尝试从缓存获取
    spin_lock(&pgtable_cache.lock);
    if (pgtable_cache.pgd_count > 0) {
        page = pgtable_cache.pgd_cache[--pgtable_cache.pgd_count];
        spin_unlock(&pgtable_cache.lock);
        
        // 初始化页面
        pgd_t *pgd = (pgd_t *)page_address(page);
        memset(pgd, 0, PAGE_SIZE);
        
        return pgd;
    }
    spin_unlock(&pgtable_cache.lock);
    
    // 缓存未命中,正常分配
    return pgd_alloc(mm);
}

// 预填充页表缓存
void prepopulate_pgtable_cache(void)
{
    int i;
    
    // 预分配PGD
    for (i = 0; i < PGD_PREALLOC_SIZE; i++) {
        struct page *page = alloc_page(GFP_PGTABLE_KERNEL);
        if (page) {
            spin_lock(&pgtable_cache.lock);
            pgtable_cache.pgd_cache[pgtable_cache.pgd_count++] = page;
            spin_unlock(&pgtable_cache.lock);
        }
    }
    
    // 预分配PMD和PTE
    // ... 类似逻辑
}

// 页表预热优化
void pgtable_warmup(struct mm_struct *mm, unsigned long start, size_t size)
{
    unsigned long addr = start;
    unsigned long end = start + size;
    
    // 预先建立页表层次
    for (; addr < end; addr += PMD_SIZE) {
        pgd_t *pgd = pgd_offset(mm, addr);
        if (pgd_none(*pgd)) {
            // 预分配必要的页表
            handle_mm_fault(NULL, addr, FAULT_FLAG_ALLOW_RETRY, NULL);
        }
    }
}

预分配特点

1. 缓存池 :各级页表的预分配缓存

2. 批量分配 :减少频繁的页面分配开销

3. 预热机制 :关键地址空间的页表预热

4. 锁优化:细粒度的锁减少竞争

5.3.2 TLB和缓存优化

TLB和缓存的协同优化:

c 复制代码
// MMU缓存更新
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
{
    // 检查是否需要TLB更新
    if (pte_present(*ptep)) {
        // 页面存在,更新TLB
        update_tlb_single(addr);
        
        // 检查是否为大页
        if (pte_huge(*ptep)) {
            // 大页面的特殊处理
            update_tlb_huge(addr);
        }
    }
    
    // 缓存预取优化
    prefetch_page_tables(addr);
}

// TLB单个页面更新
static void update_tlb_single(unsigned long addr)
{
    // ARM64 TLB更新指令
    asm volatile("tlbi vae1, %0" : : "r" (addr >> 12));
    
    // 同步屏障
    asm volatile("dsb ish" : : : "memory");
    asm volatile("isb" : : : "memory");
}

// TLB大页更新
static void update_tlb_huge(unsigned long addr)
{
    // 大页面的TLB更新
    asm volatile("tlbi vae1is, %0" : : "r" (addr >> 12));
    
    // 同步操作
    asm volatile("dsb ish" : : : "memory");
}

// 页表预取
static void prefetch_page_tables(unsigned long addr)
{
    unsigned long pgd_idx = pgd_index(addr);
    unsigned long p4d_idx = p4d_index(addr);
    unsigned long pud_idx = pud_index(addr);
    unsigned long pmd_idx = pmd_index(addr);
    
    // 预取各级页表
    prefetch(&current->mm->pgd[pgd_idx]);
    
    // 根据页表层次预取更多级别
    if (ARM64_SW_PGTABLE_LEVELS > 3) {
        // 预取P4D
        prefetch_p4d_tables(addr);
    }
    
    prefetch_pud_tables(addr);
    prefetch_pmd_tables(addr);
}

// 页面表预取优化
static void prefetch_pmd_tables(unsigned long addr)
{
    pmd_t *pmd;
    unsigned long pmd_end;
    
    // 计算PMD范围
    unsigned long pmd_start = addr & PMD_MASK;
    pmd_end = pmd_start + PMD_SIZE;
    
    // 预取PMD条目
    for (unsigned long a = pmd_start; a < pmd_end; a += PAGE_SIZE) {
        pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset(current->mm, a), a), a), a);
        prefetch(pmd);
    }
}

缓存优化特点

1. TLB精细控制 :不同类型页面的TLB更新

2. 预取策略 :页表的智能预取

3. 大页优化 :大页面的特殊处理路径

4. 同步保证:正确的内存屏障使用

6. 设计模式分析

6.1 工厂模式在页表分配中的体现

页表分配的工厂模式:

c 复制代码
// 页表分配器接口
interface PageTableAllocator {
    PageTable allocate(struct mm_struct *mm, unsigned long addr);
    void free(PageTable table);
    boolean canAllocate(unsigned long addr);
    String getAllocatorName();
}

// PGD分配器实现
class PGDAllocator implements PageTableAllocator {
    public PageTable allocate(struct mm_struct *mm, unsigned long addr) {
        pgd_t *pgd = pgd_alloc(mm);
        if (pgd) {
            return new PageTable(pgd, PageTableLevel.PGD);
        }
        return null;
    }
    
    public void free(PageTable table) {
        pgd_free(table.getMM(), (pgd_t *)table.getTable());
    }
    
    public boolean canAllocate(unsigned long addr) {
        return true; // PGD总是可以分配
    }
    
    public String getAllocatorName() {
        return "PGD_ALLOCATOR";
    }
}

// PMD分配器实现
class PMDAllocator implements PageTableAllocator {
    public PageTable allocate(struct mm_struct *mm, unsigned long addr) {
        pmd_t *pmd = pmd_alloc_one(mm, addr);
        if (pmd) {
            return new PageTable(pmd, PageTableLevel.PMD);
        }
        return null;
    }
    
    public void free(PageTable table) {
        pmd_free((pmd_t *)table.getTable());
    }
    
    public boolean canAllocate(unsigned long addr) {
        return !pmd_large(*(pmd_t *)find_pmd_table(addr)); // 只有非大页才需要分配
    }
    
    public String getAllocatorName() {
        return "PMD_ALLOCATOR";
    }
}

// PTE分配器实现
class PTEAllocator implements PageTableAllocator {
    public PageTable allocate(struct mm_struct *mm, unsigned long addr) {
        pte_t *pte = pte_alloc_one(mm, addr);
        if (pte) {
            return new PageTable(pte, PageTableLevel.PTE);
        }
        return null;
    }
    
    public void free(PageTable table) {
        pte_free((pte_t *)table.getTable());
    }
    
    public boolean canAllocate(unsigned long addr) {
        return !pmd_large(*(pmd_t *)find_pmd_table(addr)); // 只有非大页才需要分配
    }
    
    public String getAllocatorName() {
        return "PTE_ALLOCATOR";
    }
}

// 页表分配器工厂
class PageTableAllocatorFactory {
    private static Map<PageTableLevel, PageTableAllocator> allocators;
    
    static {
        allocators = new HashMap<>();
        allocators.put(PageTableLevel.PGD, new PGDAllocator());
        allocators.put(PageTableLevel.PMD, new PMDAllocator());
        allocators.put(PageTableLevel.PTE, new PTEAllocator());
    }
    
    public static PageTableAllocator getAllocator(PageTableLevel level) {
        return allocators.get(level);
    }
    
    public static PageTable allocatePageTable(PageTableLevel level, 
                                            struct mm_struct *mm, unsigned long addr) {
        PageTableAllocator allocator = getAllocator(level);
        if (allocator != null && allocator.canAllocate(addr)) {
            return allocator.allocate(mm, addr);
        }
        return null;
    }
    
    public static void freePageTable(PageTable table) {
        PageTableAllocator allocator = getAllocator(table.getLevel());
        if (allocator != null) {
            allocator.free(table);
        }
    }
}

// 使用工厂模式
class MMUManager {
    public PageTable allocatePageTable(PageTableLevel level, 
                                     struct mm_struct *mm, unsigned long addr) {
        return PageTableAllocatorFactory.allocatePageTable(level, mm, addr);
    }
    
    public void freePageTable(PageTable table) {
        PageTableAllocatorFactory.freePageTable(table);
    }
}

6.2 策略模式在地址映射中的体现

地址映射的策略模式:

c 复制代码
// 地址映射策略接口
interface AddressMappingStrategy {
    vm_fault_t mapAddress(struct vm_fault *vmf);
    boolean canHandle(struct vm_fault *vmf);
    String getStrategyName();
    double getMappingEfficiency();
    long getAverageMappingTime();
}

// 标准页面映射策略
class StandardPageMappingStrategy implements AddressMappingStrategy {
    public vm_fault_t mapAddress(struct vm_fault *vmf) {
        // 标准页面映射逻辑
        struct page *page = alloc_page(GFP_HIGHUSER_MOVABLE);
        if (!page) {
            return VM_FAULT_OOM;
        }
        
        // 建立映射
        pte_t entry = mk_pte(page, vmf->vma->vm_page_prot);
        set_pte_at(vmf->vma->vm_mm, vmf->address, vmf->pte, entry);
        
        return VM_FAULT_SUCCESS;
    }
    
    public boolean canHandle(struct vm_fault *vmf) {
        // 检查是否为标准页面映射
        return is_standard_page_fault(vmf);
    }
    
    public String getStrategyName() {
        return "STANDARD_PAGE_MAPPING";
    }
    
    public double getMappingEfficiency() {
        return 0.95;
    }
    
    public long getAverageMappingTime() {
        return 2000; // 2微秒
    }
}

// 写时复制映射策略
class CopyOnWriteMappingStrategy implements AddressMappingStrategy {
    public vm_fault_t mapAddress(struct vm_fault *vmf) {
        // 写时复制映射逻辑
        struct page *old_page = vmf->page;
        struct page *new_page = alloc_page(GFP_HIGHUSER_MOVABLE);
        
        if (!new_page) {
            return VM_FAULT_OOM;
        }
        
        // 复制页面内容
        copy_user_highpage(new_page, old_page, vmf->address, vmf->vma);
        
        // 建立私有映射
        pte_t entry = mk_pte(new_page, vmf->vma->vm_page_prot);
        entry = pte_mkwrite(pte_mkdirty(entry));
        set_pte_at(vmf->vma->vm_mm, vmf->address, vmf->pte, entry);
        
        // 释放旧页面引用
        put_page(old_page);
        
        return VM_FAULT_SUCCESS;
    }
    
    public boolean canHandle(struct vm_fault *vmf) {
        // 检查是否为写时复制场景
        return is_copy_on_write_fault(vmf);
    }
    
    public String getStrategyName() {
        return "COPY_ON_WRITE_MAPPING";
    }
    
    public double getMappingEfficiency() {
        return 0.85;
    }
    
    public long getAverageMappingTime() {
        return 10000; // 10微秒(包括复制时间)
    }
}

// 交换页面映射策略
class SwapPageMappingStrategy implements AddressMappingStrategy {
    public vm_fault_t mapAddress(struct vm_fault *vmf) {
        // 交换页面映射逻辑
        swp_entry_t entry = pte_to_swp_entry(*vmf->pte);
        struct page *page = alloc_page(GFP_HIGHUSER_MOVABLE);
        
        if (!page) {
            return VM_FAULT_OOM;
        }
        
        // 从交换空间读取页面
        if (swap_readpage(page, entry) != 0) {
            __free_page(page);
            return VM_FAULT_SIGBUS;
        }
        
        // 建立映射
        pte_t entry = mk_pte(page, vmf->vma->vm_page_prot);
        set_pte_at(vmf->vma->vm_mm, vmf->address, vmf->pte, entry);
        
        return VM_FAULT_SUCCESS;
    }
    
    public boolean canHandle(struct vm_fault *vmf) {
        // 检查页面是否在交换空间
        return is_swap_page_fault(vmf);
    }
    
    public String getStrategyName() {
        return "SWAP_PAGE_MAPPING";
    }
    
    public double getMappingEfficiency() {
        return 0.75;
    }
    
    public long getAverageMappingTime() {
        return 50000; // 50微秒(包括I/O时间)
    }
}

// 自适应地址映射策略
class AdaptiveMappingStrategy implements AddressMappingStrategy {
    private List<AddressMappingStrategy> strategies;
    private MappingStatistics stats;
    
    public AdaptiveMappingStrategy() {
        strategies = Arrays.asList(
            new StandardPageMappingStrategy(),
            new CopyOnWriteMappingStrategy(),
            new SwapPageMappingStrategy()
        );
        stats = new MappingStatistics();
    }
    
    public vm_fault_t mapAddress(struct vm_fault *vmf) {
        // 选择最适合的策略
        AddressMappingStrategy bestStrategy = selectBestStrategy(vmf);
        
        long startTime = System.nanoTime();
        vm_fault_t result = bestStrategy.mapAddress(vmf);
        long mappingTime = System.nanoTime() - startTime;
        
        // 更新统计信息
        stats.recordMapping(bestStrategy.getStrategyName(), result == VM_FAULT_SUCCESS, mappingTime);
        
        // 重新评估策略优先级
        reevaluateStrategyPriorities();
        
        return result;
    }
    
    public boolean canHandle(struct vm_fault *vmf) {
        return strategies.stream().anyMatch(s -> s.canHandle(vmf));
    }
    
    public String getStrategyName() {
        return "ADAPTIVE_MAPPING";
    }
    
    public double getMappingEfficiency() {
        return stats.getOverallEfficiency();
    }
    
    public long getAverageMappingTime() {
        return stats.getAverageMappingTime();
    }
    
    private AddressMappingStrategy selectBestStrategy(struct vm_fault *vmf) {
        return strategies.stream()
                .filter(s -> s.canHandle(vmf))
                .max(Comparator.comparingDouble(s -> calculateStrategyScore(s, vmf)))
                .orElse(new StandardPageMappingStrategy());
    }
    
    private double calculateStrategyScore(AddressMappingStrategy strategy, struct vm_fault *vmf) {
        double efficiency = stats.getStrategyEfficiency(strategy.getStrategyName());
        long avgTime = stats.getStrategyAverageTime(strategy.getStrategyName());
        
        // 综合评分:效率权重70%,时间权重30%
        return efficiency * 0.7 - (avgTime / 1000000.0) * 0.3;
    }
    
    private void reevaluateStrategyPriorities() {
        strategies.sort((a, b) -> Double.compare(
            stats.getStrategyEfficiency(b.getStrategyName()),
            stats.getStrategyEfficiency(a.getStrategyName())
        ));
    }
}

// 策略选择器
class AddressMappingStrategySelector {
    public static AddressMappingStrategy selectStrategy(PageFaultType type, SystemContext context) {
        switch (type) {
            case MISSING_PAGE:
                return new StandardPageMappingStrategy();
            case COPY_ON_WRITE:
                return new CopyOnWriteMappingStrategy();
            case SWAPPED_OUT:
                return new SwapPageMappingStrategy();
            case COMPLEX_FAULT:
                return new AdaptiveMappingStrategy();
            default:
                return new StandardPageMappingStrategy();
        }
    }
}

6.3 组合模式在页表层次中的体现

页表层次的组合模式:

c 复制代码
// 页表组件接口
interface PageTableComponent {
    void setEntry(unsigned long index, PageTableEntry entry);
    PageTableEntry getEntry(unsigned long index);
    boolean isPresent(unsigned long index);
    void clearEntry(unsigned long index);
    PageTableLevel getLevel();
    void traverse(PageTableVisitor visitor);
}

// 页表条目类
class PageTableEntry {
    private long value;
    
    public PageTableEntry(long value) {
        this.value = value;
    }
    
    public long getValue() {
        return value;
    }
    
    public void setValue(long value) {
        this.value = value;
    }
    
    public boolean isPresent() {
        return (value & PTE_PRESENT) != 0;
    }
    
    public boolean isLarge() {
        return (value & PTE_LARGE) != 0;
    }
    
    public long getPhysicalAddress() {
        return value & PTE_ADDR_MASK;
    }
}

// 页表节点(组合模式中的叶子节点)
class PageTableLeaf implements PageTableComponent {
    private PageTableEntry entry;
    private unsigned long index;
    
    public PageTableLeaf(unsigned long index, PageTableEntry entry) {
        this.index = index;
        this.entry = entry;
    }
    
    public void setEntry(unsigned long index, PageTableEntry entry) {
        if (this.index == index) {
            this.entry = entry;
        }
    }
    
    public PageTableEntry getEntry(unsigned long index) {
        return (this.index == index) ? entry : null;
    }
    
    public boolean isPresent(unsigned long index) {
        return this.index == index && entry.isPresent();
    }
    
    public void clearEntry(unsigned long index) {
        if (this.index == index) {
            entry = new PageTableEntry(0);
        }
    }
    
    public PageTableLevel getLevel() {
        return PageTableLevel.PTE;
    }
    
    public void traverse(PageTableVisitor visitor) {
        visitor.visitLeaf(this);
    }
}

// 页表节点(组合模式中的组合节点)
class PageTableComposite implements PageTableComponent {
    private PageTableComponent[] children;
    private PageTableLevel level;
    private unsigned long baseIndex;
    
    public PageTableComposite(PageTableLevel level, unsigned long baseIndex) {
        this.level = level;
        this.baseIndex = baseIndex;
        this.children = new PageTableComponent[getEntriesPerLevel(level)];
        
        // 初始化子节点
        for (int i = 0; i < children.length; i++) {
            children[i] = createChild(level, baseIndex + i);
        }
    }
    
    private PageTableComponent createChild(PageTableLevel parentLevel, unsigned long index) {
        PageTableLevel childLevel = getChildLevel(parentLevel);
        if (childLevel == PageTableLevel.PTE) {
            return new PageTableLeaf(index, new PageTableEntry(0));
        } else {
            return new PageTableComposite(childLevel, index * getEntriesPerLevel(childLevel));
        }
    }
    
    private PageTableLevel getChildLevel(PageTableLevel level) {
        switch (level) {
            case PGD: return PageTableLevel.P4D;
            case P4D: return PageTableLevel.PUD;
            case PUD: return PageTableLevel.PMD;
            case PMD: return PageTableLevel.PTE;
            default: throw new IllegalArgumentException("Invalid level");
        }
    }
    
    private int getEntriesPerLevel(PageTableLevel level) {
        switch (level) {
            case PGD:
            case P4D:
            case PUD:
            case PMD:
                return PTRS_PER_PGD; // 512
            case PTE:
                return 1; // PTE是叶子节点
            default:
                return 0;
        }
    }
    
    public void setEntry(unsigned long index, PageTableEntry entry) {
        unsigned long localIndex = index - baseIndex;
        unsigned long entriesPerChild = getEntriesPerLevel(getChildLevel(level));
        unsigned long childIndex = localIndex / entriesPerChild;
        unsigned long childLocalIndex = localIndex % entriesPerChild;
        
        if (childIndex < children.length) {
            children[(int)childIndex].setEntry(childLocalIndex, entry);
        }
    }
    
    public PageTableEntry getEntry(unsigned long index) {
        unsigned long localIndex = index - baseIndex;
        unsigned long entriesPerChild = getEntriesPerLevel(getChildLevel(level));
        unsigned long childIndex = localIndex / entriesPerChild;
        unsigned long childLocalIndex = localIndex % entriesPerChild;
        
        if (childIndex < children.length) {
            return children[(int)childIndex].getEntry(childLocalIndex);
        }
        return null;
    }
    
    public boolean isPresent(unsigned long index) {
        unsigned long localIndex = index - baseIndex;
        unsigned long entriesPerChild = getEntriesPerLevel(getChildLevel(level));
        unsigned long childIndex = localIndex / entriesPerChild;
        unsigned long childLocalIndex = localIndex % entriesPerChild;
        
        if (childIndex < children.length) {
            return children[(int)childIndex].isPresent(childLocalIndex);
        }
        return false;
    }
    
    public void clearEntry(unsigned long index) {
        unsigned long localIndex = index - baseIndex;
        unsigned long entriesPerChild = getEntriesPerLevel(getChildLevel(level));
        unsigned long childIndex = localIndex / entriesPerChild;
        unsigned long childLocalIndex = localIndex % entriesPerChild;
        
        if (childIndex < children.length) {
            children[(int)childIndex].clearEntry(childLocalIndex);
        }
    }
    
    public PageTableLevel getLevel() {
        return level;
    }
    
    public void traverse(PageTableVisitor visitor) {
        visitor.visitComposite(this);
        for (PageTableComponent child : children) {
            child.traverse(visitor);
        }
    }
}

// 页表访问者接口
interface PageTableVisitor {
    void visitLeaf(PageTableLeaf leaf);
    void visitComposite(PageTableComposite composite);
}

// 页表转储访问者
class PageTableDumpVisitor implements PageTableVisitor {
    private PrintWriter writer;
    private int indentLevel = 0;
    
    public PageTableDumpVisitor(PrintWriter writer) {
        this.writer = writer;
    }
    
    public void visitLeaf(PageTableLeaf leaf) {
        printIndent();
        writer.printf("PTE[%d]: %016lx\n", leaf.getIndex(), leaf.getEntry().getValue());
    }
    
    public void visitComposite(PageTableComposite composite) {
        printIndent();
        writer.printf("%s[%d]:\n", composite.getLevel().name(), composite.getBaseIndex());
        indentLevel++;
    }
    
    private void printIndent() {
        for (int i = 0; i < indentLevel; i++) {
            writer.print("  ");
        }
    }
}

// 页表验证访问者
class PageTableValidationVisitor implements PageTableVisitor {
    private List<String> errors = new ArrayList<>();
    
    public void visitLeaf(PageTableLeaf leaf) {
        PageTableEntry entry = leaf.getEntry();
        
        // 验证PTE的正确性
        if (entry.isPresent() && entry.getPhysicalAddress() == 0) {
            errors.add(String.format("Invalid PTE at index %d: present but no physical address", 
                                   leaf.getIndex()));
        }
        
        if (!isAligned(entry.getPhysicalAddress(), PAGE_SIZE)) {
            errors.add(String.format("Unaligned physical address in PTE at index %d: %lx", 
                                   leaf.getIndex(), entry.getPhysicalAddress()));
        }
    }
    
    public void visitComposite(PageTableComposite composite) {
        // 验证组合节点的正确性
        if (composite.getChildren().length != getExpectedChildrenCount(composite.getLevel())) {
            errors.add(String.format("Invalid children count for %s: expected %d, got %d",
                                   composite.getLevel().name(),
                                   getExpectedChildrenCount(composite.getLevel()),
                                   composite.getChildren().length));
        }
    }
    
    public List<String> getErrors() {
        return errors;
    }
    
    private int getExpectedChildrenCount(PageTableLevel level) {
        return (level != PageTableLevel.PTE) ? PTRS_PER_PGD : 1;
    }
    
    private boolean isAligned(long address, long alignment) {
        return (address & (alignment - 1)) == 0;
    }
}

// 使用组合模式
class PageTableManager {
    private PageTableComposite root;
    
    public PageTableManager() {
        // 创建4级页表层次结构
        root = new PageTableComposite(PageTableLevel.PGD, 0);
    }
    
    public void setEntry(unsigned long address, PageTableEntry entry) {
        unsigned long index = address >> PAGE_SHIFT;
        root.setEntry(index, entry);
    }
    
    public PageTableEntry getEntry(unsigned long address) {
        unsigned long index = address >> PAGE_SHIFT;
        return root.getEntry(index);
    }
    
    public void clearEntry(unsigned long address) {
        unsigned long index = address >> PAGE_SHIFT;
        root.clearEntry(index);
    }
    
    public void dumpPageTable(PrintWriter writer) {
        PageTableDumpVisitor dumper = new PageTableDumpVisitor(writer);
        root.traverse(dumper);
    }
    
    public boolean validatePageTable() {
        PageTableValidationVisitor validator = new PageTableValidationVisitor();
        root.traverse(validator);
        return validator.getErrors().isEmpty();
    }
    
    public List<String> getValidationErrors() {
        PageTableValidationVisitor validator = new PageTableValidationVisitor();
        root.traverse(validator);
        return validator.getErrors();
    }
}

7. 状态机分析

ARM64 mm mmu的状态机:

复制代码
初始状态 -> 页表查找 -> 条目检查 -> 分配页表 -> 设置条目 -> TLB更新 -> 映射完成
     ↑                                                                                     ↓
错误处理 <---------------------------------------------------------------------------------+
     ↑                                                                                     ↓
权限验证 <---------------------------------------------------------------------------------+
     ↑                                                                                     ↓
同步操作 <---------------------------------------------------------------------------------+

8. 性能优化分析

8.1 页表缓存优化

页表缓存的性能优化:

c 复制代码
// 页表缓存命中率分析
static void analyze_ptable_cache_performance(void) {
    // 分析页表缓存的性能
    u64 cache_hits = 0;
    u64 cache_misses = 0;
    u64 total_lookups = 1000000;
    
    for (u64 i = 0; i < total_lookups; i++) {
        unsigned long addr = get_random_address();
        
        if (is_ptable_cached(addr)) {
            cache_hits++;
        } else {
            cache_misses++;
            // 模拟缓存填充
            fill_ptable_cache(addr);
        }
    }
    
    double hit_rate = (double)cache_hits / total_lookups * 100;
    
    pr_info("Page table cache performance:\n");
    pr_info("  Cache hits: %llu\n", cache_hits);
    pr_info("  Cache misses: %llu\n", cache_misses);
    pr_info("  Hit rate: %.2f%%\n", hit_rate);
}

8.2 地址转换优化

地址转换的性能优化:

c 复制代码
// 地址转换性能分析
static void analyze_address_translation_performance(void) {
    // 分析地址转换的性能
    u64 translations = 100000;
    u64 start_time, end_time;
    u64 total_time;
    
    start_time = ktime_get_ns();
    
    for (u64 i = 0; i < translations; i++) {
        unsigned long va = get_test_virtual_address(i);
        phys_addr_t pa = virt_to_phys(va);
        // 验证转换结果
        if (pa == 0) {
            pr_err("Translation failed for VA: %lx\n", va);
        }
    }
    
    end_time = ktime_get_ns();
    total_time = end_time - start_time;
    
    pr_info("Address translation performance:\n");
    pr_info("  Total translations: %llu\n", translations);
    pr_info("  Total time: %llu ns\n", total_time);
    pr_info("  Average time per translation: %llu ns\n", total_time / translations);
    pr_info("  Translations per second: %llu\n", translations * 1000000000ULL / total_time);
}

9. 安全性考虑

9.1 页表完整性保护

页表完整性的安全保障:

c 复制代码
// 页表完整性验证
static int validate_page_table_integrity(pgd_t *pgd) {
    // 验证PGD的完整性
    if (!pgd || !virt_addr_valid(pgd)) {
        return -EFAULT;
    }
    
    // 遍历所有P4D
    for (int i = 0; i < PTRS_PER_PGD; i++) {
        p4d_t *p4d = p4d_offset(pgd, i * PGDIR_SIZE);
        
        if (p4d_bad(*p4d)) {
            // 发现损坏的P4D
            return -EFAULT;
        }
        
        if (p4d_present(*p4d)) {
            // 递归验证PUD
            int ret = validate_p4d_integrity(p4d);
            if (ret < 0) {
                return ret;
            }
        }
    }
    
    return 0;
}

// 递归页表完整性验证
static int validate_p4d_integrity(p4d_t *p4d) {
    for (int i = 0; i < PTRS_PER_P4D; i++) {
        pud_t *pud = pud_offset(p4d, i * P4D_SIZE);
        
        if (pud_bad(*pud)) {
            return -EFAULT;
        }
        
        if (pud_present(*pud)) {
            int ret = validate_pud_integrity(pud);
            if (ret < 0) {
                return ret;
            }
        }
    }
    
    return 0;
}

// 页表条目权限验证
static int validate_pte_permissions(pte_t *pte, unsigned long addr) {
    // 检查权限设置的合理性
    if (pte_present(*pte)) {
        // 对于用户空间,执行权限应该被限制
        if (!(addr & PAGE_OFFSET) && pte_exec(*pte)) {
            // 用户空间不应该有执行权限(除非特殊情况)
            return -EACCES;
        }
        
        // 检查物理地址的有效性
        phys_addr_t pa = pte_pfn(*pte) << PAGE_SHIFT;
        if (!pfn_valid(pte_pfn(*pte))) {
            return -EFAULT;
        }
    }
    
    return 0;
}

9.2 地址空间隔离

地址空间隔离的安全防护:

c 复制代码
// 地址空间隔离验证
static int validate_address_space_isolation(struct mm_struct *mm1, struct mm_struct *mm2) {
    // 确保两个地址空间没有重叠
    if (mm1 == mm2) {
        return 0; // 同一地址空间
    }
    
    // 检查ASID是否不同
    if (mm1->asid == mm2->asid && mm1->asid != 0) {
        // ASID冲突,可能导致隔离失败
        return -EFAULT;
    }
    
    // 验证页表不共享
    if (page_table_overlaps(mm1->pgd, mm2->pgd)) {
        return -EFAULT;
    }
    
    return 0;
}

// 页表重叠检测
static bool page_table_overlaps(pgd_t *pgd1, pgd_t *pgd2) {
    // 检查是否有共享的页表页面
    for (int i = 0; i < PTRS_PER_PGD; i++) {
        p4d_t *p4d1 = p4d_offset(pgd1, i * PGDIR_SIZE);
        p4d_t *p4d2 = p4d_offset(pgd2, i * PGDIR_SIZE);
        
        if (p4d_present(*p4d1) && p4d_present(*p4d2)) {
            if (p4d_page(*p4d1) == p4d_page(*p4d2)) {
                // 发现共享的页表页面
                return true;
            }
        }
    }
    
    return false;
}

// 地址转换安全检查
static int validate_address_translation(unsigned long va, phys_addr_t pa) {
    // 检查虚拟地址范围
    if (va >= TASK_SIZE_MAX) {
        // 内核空间访问,需要权限验证
        if (!capable(CAP_SYS_ADMIN)) {
            return -EACCES;
        }
    }
    
    // 检查物理地址有效性
    if (!phys_addr_valid(pa)) {
        return -EFAULT;
    }
    
    // 检查地址对齐
    if (!IS_ALIGNED(va, sizeof(void *)) || !IS_ALIGNED(pa, PAGE_SIZE)) {
        return -EINVAL;
    }
    
    // 检查是否为安全映射
    if (is_unsafe_mapping(va, pa)) {
        return -EACCES;
    }
    
    return 0;
}

10. 扩展性分析

10.1 多架构支持

跨架构的MMU管理扩展:

c 复制代码
// 架构特定的MMU操作接口
struct mmu_ops {
    const char *arch_name;
    
    // 页表管理
    pgd_t *(*alloc_pgd)(struct mm_struct *mm);
    void (*free_pgd)(struct mm_struct *mm, pgd_t *pgd);
    
    // 地址映射
    void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
    void (*set_pmd_at)(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pmd_t pmd);
    
    // TLB管理
    void (*flush_tlb_all)(void);
    void (*flush_tlb_mm)(struct mm_struct *mm);
    void (*flush_tlb_page)(struct vm_area_struct *vma, unsigned long addr);
    
    // 页表遍历
    pgd_t *(*pgd_offset)(struct mm_struct *mm, unsigned long address);
    pte_t *(*pte_offset)(pmd_t *pmd, unsigned long address);
};

// ARM64 MMU操作实现
static const struct mmu_ops arm64_mmu_ops = {
    .arch_name = "arm64",
    .alloc_pgd = arm64_alloc_pgd,
    .free_pgd = arm64_free_pgd,
    .set_pte_at = arm64_set_pte_at,
    .set_pmd_at = arm64_set_pmd_at,
    .flush_tlb_all = arm64_flush_tlb_all,
    .flush_tlb_mm = arm64_flush_tlb_mm,
    .flush_tlb_page = arm64_flush_tlb_page,
    .pgd_offset = arm64_pgd_offset,
    .pte_offset = arm64_pte_offset,
};

// x86 MMU操作实现
static const struct mmu_ops x86_mmu_ops = {
    .arch_name = "x86_64",
    .alloc_pgd = x86_alloc_pgd,
    // ... 其他操作
};

// 运行时架构选择
static const struct mmu_ops *select_mmu_ops(void)
{
#ifdef CONFIG_ARM64
    return &arm64_mmu_ops;
#elif defined(CONFIG_X86_64)
    return &x86_mmu_ops;
#else
    return NULL;
#endif
}

10.2 功能扩展

MMU功能扩展能力:

c 复制代码
// 高级MMU功能扩展
struct advanced_mmu_features {
    bool support_large_pages;      // 支持大页
    bool support_access_tracking;  // 支持访问跟踪
    bool support_memory_tagging;   // 支持内存标签
    bool support_page_attributes;  // 支持页面属性
    bool support_nested_paging;    // 支持嵌套分页
};

// MMU扩展API
struct extended_mmu_api {
    // 大页管理
    int (*alloc_huge_pmd)(struct mm_struct *mm, unsigned long addr);
    void (*free_huge_pmd)(struct mm_struct *mm, pmd_t *pmd);
    
    // 访问跟踪
    int (*enable_access_tracking)(struct mm_struct *mm, unsigned long addr, size_t size);
    int (*disable_access_tracking)(struct mm_struct *mm, unsigned long addr, size_t size);
    int (*get_access_info)(struct mm_struct *mm, unsigned long addr, struct access_info *info);
    
    // 内存标签
    int (*set_memory_tag)(unsigned long addr, size_t size, uint8_t tag);
    int (*get_memory_tag)(unsigned long addr, uint8_t *tag);
    
    // 页面属性
    int (*set_page_attributes)(unsigned long addr, size_t size, unsigned long attrs);
    int (*get_page_attributes)(unsigned long addr, unsigned long *attrs);
};

11. 调试和维护

11.1 MMU调试支持

MMU调试支持:

c 复制代码
// MMU调试宏
#define MMU_DEBUG(fmt, ...) \
    pr_debug("MMU: " fmt, ##__VA_ARGS__)

#define MMU_DEBUG_ADDR(addr, pgd) \
    MMU_DEBUG("address=%lx, pgd=%p\n", addr, pgd)

#define MMU_DEBUG_PTE(pte, addr) \
    MMU_DEBUG("pte=%lx at %lx\n", pte_val(*pte), addr)

// 详细调试模式
#ifdef CONFIG_MMU_DEBUG
static void mmu_debug_translation(unsigned long va) {
    MMU_DEBUG("=== ADDRESS TRANSLATION DEBUG ===\n");
    MMU_DEBUG("Virtual address: %lx\n", va);
    
    // 页表遍历调试
    pgd_t *pgd = pgd_offset(current->mm, va);
    MMU_DEBUG("PGD: %p, value: %lx\n", pgd, pgd_val(*pgd));
    
    if (pgd_present(*pgd)) {
        p4d_t *p4d = p4d_offset(pgd, va);
        MMU_DEBUG("P4D: %p, value: %lx\n", p4d, p4d_val(*p4d));
        
        if (p4d_present(*p4d)) {
            pud_t *pud = pud_offset(p4d, va);
            MMU_DEBUG("PUD: %p, value: %lx\n", pud, pud_val(*pud));
            
            if (pud_present(*pud)) {
                pmd_t *pmd = pmd_offset(pud, va);
                MMU_DEBUG("PMD: %p, value: %lx\n", pmd, pmd_val(*pmd));
                
                if (pmd_present(*pmd)) {
                    pte_t *pte = pte_offset(pmd, va);
                    MMU_DEBUG("PTE: %p, value: %lx\n", pte, pte_val(*pte));
                    
                    if (pte_present(*pte)) {
                        phys_addr_t pa = pte_pfn(*pte) << PAGE_SHIFT;
                        MMU_DEBUG("Physical address: %lx\n", pa);
                    }
                }
            }
        }
    }
    
    MMU_DEBUG("=== END ADDRESS TRANSLATION DEBUG ===\n");
}
#endif

11.2 错误检测和恢复

MMU错误处理:

c 复制代码
// MMU错误检测
static int mmu_detect_errors(struct mm_struct *mm) {
    // 检测页表错误
    if (detect_page_table_errors(mm->pgd)) {
        MMU_DEBUG("Page table errors detected\n");
        return -EFAULT;
    }
    
    // 检测TLB一致性
    if (detect_tlb_inconsistencies(mm)) {
        MMU_DEBUG("TLB inconsistencies detected\n");
        return -EFAULT;
    }
    
    // 检测ASID冲突
    if (detect_asid_conflicts(mm->asid)) {
        MMU_DEBUG("ASID conflicts detected\n");
        return -EINVAL;
    }
    
    return 0;
}

// 错误恢复机制
static int mmu_recover_from_errors(struct mm_struct *mm, int error) {
    MMU_DEBUG("Attempting MMU error recovery: %d\n", error);
    
    switch (error) {
    case -EFAULT:
        // 页表错误:重建页表
        return rebuild_page_tables(mm);
        
    case -EINVAL:
        // ASID错误:重新分配ASID
        return reallocate_asid(mm);
        
    default:
        MMU_DEBUG("Unrecoverable MMU error\n");
        return error;
    }
}

// 页表重建
static int rebuild_page_tables(struct mm_struct *mm) {
    // 释放旧页表
    pgd_free(mm, mm->pgd);
    
    // 分配新页表
    mm->pgd = pgd_alloc(mm);
    if (!mm->pgd) {
        return -ENOMEM;
    }
    
    // 重新建立关键映射
    return reestablish_critical_mappings(mm);
}

12. 总结

ARM64 mm mmu子模块作为ARM64内存管理子系统中MMU管理的核心组件,通过完整的页表创建、地址映射和MMU上下文管理的功能,为ARM64平台提供了高效可靠的地址转换和内存访问控制。该模块实现了多级页表的创建和维护、虚拟地址到物理地址的映射关系、页表项的权限控制和属性设置,通过精心设计的页表结构和地址转换算法,在保证内存访问安全性的同时实现了接近硬件极限的地址转换性能。源码分析显示,模块采用了工厂模式、策略模式和组合模式等多种设计模式,为MMU管理提供了灵活高效的实现框架。

相关推荐
Doro再努力10 小时前
Vim 快速上手实操手册:从入门到生产环境实战
linux·编辑器·vim
不凉帅10 小时前
NO.7系统架构设计和软件质量
系统架构
wypywyp10 小时前
8. ubuntu 虚拟机 linux 服务器 TCP/IP 概念辨析
linux·服务器·ubuntu
Doro再努力10 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
senijusene10 小时前
Linux软件编程:IO编程,标准IO(1)
linux·运维·服务器
忧郁的橙子.10 小时前
02-本地部署Ollama、Python
linux·运维·服务器
醇氧10 小时前
【linux】查看发行版信息
linux·运维·服务器
No8g攻城狮11 小时前
【Linux】Windows11 安装 WSL2 并运行 Ubuntu 22.04 详细操作步骤
linux·运维·ubuntu
XiaoFan01211 小时前
免密批量抓取日志并集中输出
java·linux·服务器