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管理提供了灵活高效的实现框架。

相关推荐
Apipi*6 小时前
30天速通Linux 第六章信号及信号处理
linux·运维·信号处理
天启HTTP7 小时前
爬虫防封核心原理:IP轮换机制与风控规避逻辑
linux·服务器·网络·爬虫·tcp/ip
问商十三载8 小时前
AI引擎生成式优化实践:刑事辩护律师团队IP构建
大数据·人工智能
会议咨询9 小时前
2026年大数据、信息系统与智能通信国际会议(BDIIC 2026)
大数据·信息系统·智能通信
Raas1009 小时前
MAI Gateway(魔芋企业级AI网关)能力解析:AI网关能做故障转移吗?AI网关核心功能详解
大数据·人工智能·网关·ai·gateway·mai gateway
广州浮点FLOATLIC9 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
IT研究所10 小时前
AI-ITR平台如何减少客户问题反复升级?
大数据·运维·人工智能·低代码·自然语言处理·安全架构·企微
BLUcoding10 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom
AIgorithmGEEK10 小时前
[Linux]从手写报头到内核套路:序列化、反序列化与自定义协议全链路
linux·运维·服务器·网络·序列化·反序列化
Nil20810 小时前
leetcode 139单词拆分
linux·运维·服务器