mmap映射物理内存之三invalid cache

发布于:2025-06-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

目录

  流程设计

invalid 命令

内核态invalid

内核态invalid,用户态mmap物理地址

PAN机制

  PAN机制历程   硬件支持     

ARMv8.1-PAN 特性

Linux 内核的适配

 软件模拟 PAN(SW PAN)

背景

Linux 的实现

总结


   

前述刷新cache的流程也同样可以用于invalid 的操作。

  流程设计

 1)写程序写数据到内存。

 2) 读程序读数据,可能从cache读到老数据,这里invalid

invalid 命令

参考clean的操作,我们采用对应的指令。

DC IVAC, Data or unified Cache line Invalidate by VA to PoC
于是我们设计类似的接口

	 for (i = 0; i < gen_test_size; i = i + 64)
	{
		  temp_addr=(unsigned char *)((unsigned char *)test_virt_addr_r+i);
		  __asm volatile("dc ivac,%0"::"r"(temp_addr));
     }

但实际运行的时候,报 指令无权限。也就是 用户态不能执行这个指令

内核态invalid

内核接口,直接调用同样的指令invalid 操作

// 失效指定范围的 D-Cache
static void invalidate_dcache_range(unsigned long start, unsigned long end) {
    for (; start < end; start += cache_line_size()) {
        asm volatile("dc ivac, %0" :: "r"(start));
    }
    dsb(ish); // 数据同步屏障
}


if (copy_from_user(&range, (void __user *)arg, sizeof(range))) {
        return -EFAULT;
    }

 invalidate_dcache_range(range.addr, range.addr + range.length);
   

用户态接口

 // 分配测试内存
    size_t size = 4096;
    char *buffer = malloc(size);
    strcpy(buffer, "Test data");

    // 构造参数
    struct cache_range range = {
        .addr = (unsigned long)buffer,
        .length = size
    };

    // 调用 IOCTL 失效 Cache
    if (ioctl(fd, 0, &range) < 0) {

上述代码可以正常运行。 

内核态invalid,用户态mmap物理地址

内核态同上,但是用户态测试用的地址变为mmap映射

于是我们得到了内核异常,报段错误

  576.716499][ 4] [ T2037] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000007f7b5da740
[  576.728329][ 4] [ T2037] Mem abort info:
[  576.732249][ 4] [ T2037]   ESR = 0x9600014f
[  576.736429][ 4] [ T2037]   EC = 0x25: DABT (current EL), IL = 32 bits
[  576.742867][ 4] [ T2037]   SET = 0, FnV = 0
[  576.747048][ 4] [ T2037]   EA = 0, S1PTW = 0
[  576.751313][ 4] [ T2037] Data abort info:
[  576.755318][ 4] [ T2037]   ISV = 0, ISS = 0x0000014f
[  576.760278][ 4] [ T2037]   CM = 1, WnR = 1
[  576.764371][ 4] [ T2037] user pgtable: 4k pages, 39-bit VAs, pgdp=0000002241257000

PAN机制

         PAN(Privileged Access Never) 是 ARMv8 架构引入的一种安全特性,用于防止 内核态(Privileged Mode)直接访问用户态(User Mode)内存,从而增强系统对内存访问漏洞的防护能力。其核心思想是:即使在内核态,也不能绕过 MMU 权限检查直接访问用户空间数据,必须通过安全的拷贝函数(如 copy_from_user)  

PAN 通过 ARM 的页表权限控制,强制内核态访问用户地址时触发异常(即使 MMU 处于内核态)。

  • 若内核需访问用户数据,必须通过 copy_from_user 等安全接口(这些函数会临时禁用 PAN)

    目前板卡上此功能并未开启。通过malloc分配的内存可以invalid,也可以验证这一点

zcat /proc/config.gz |grep CONFIG_ARM64_SW_TTBR0_PAN

CONFIG_ARM64_SW_TTBR0_PAN is not set

  PAN机制历程   硬件支持     

ARMv8.1-PAN 特性

  • 引入时间:2014 年(ARMv8.1-A 架构)。

  • 核心机制

    • 新增 SCTLR_ELx.PAN 控制位(EL1/EL2/EL3均可配置)。

    • 内核态访问用户地址时触发 Permission Fault(即使 MMU 允许)。

  • 指令支持

    • SETPAN 指令动态切换 PAN 状态(需配合 ERET 使用)。

Linux 内核的适配

Linux 的实现

  • 初始支持
    Linux 4.10(2016年)合并 ARMv8.1-PAN 支持,通过 CONFIG_ARM64_PAN 启用。

  • 动态切换
    在合法访问用户数据时(如系统调用),临时禁用 PAN:

     软件模拟 PAN(SW PAN)

    背景

  • 兼容旧硬件
    部分 ARMv8.0 处理器(如 Cortex-A53/A57)无硬件 PAN,需软件模拟。

  • 实现原理

    • 修改页表权限,使用户空间内存在内核态 不可访问

    • 通过 TTBR0 切换模拟 PAN 效果。

  • SW PAN 补丁
    Linux 4.3(2015年)引入 CONFIG_ARM64_SW_TTBR0_PAN,通过动态切换 TTBR0 实现:

  • 性能代价
    每次用户/内核数据拷贝需切换 TTBR0,开销显著高于硬件 PAN。

总结

   1)mmap映射的地址并不能被invalid。

    2)也不能被lock

   总体的拷贝速率比内核管理的慢。后续我们采用巨页来映射,看是否相关的操作是否可行。

   


网站公告

今日签到

点亮在社区的每一天
去签到