MIPS架构下如何保护ioremap返回地址对应的页面不可写入?
用pte_wrprotect保护ioremap映射地址的操作步骤
要保护ioremap返回的内核虚拟地址,需找到对应地址的页表项(PTE),修改其属性为只读,最后刷新TLB确保生效。以下是具体实现:
必要头文件
确保包含内核页表操作相关的头文件:
#include <linux/mm.h> #include <asm/pgtable.h>
完整操作代码
char *addr; addr = ioremap(0x207f700000, PAGE_SIZE); if (!addr) { // 处理ioremap失败逻辑 return -ENOMEM; } // 1. 查找虚拟地址对应的页表项指针 pte_t *pte; pte = lookup_address((unsigned long)addr, &init_mm); if (!pte) { // 未找到对应页表项,清理后返回错误 iounmap(addr); return -EINVAL; } // 2. 锁定页表并修改为只读属性 spinlock_t *ptl = pte_lockptr(&init_mm, pte); spin_lock(ptl); // 将页表项设置为只读 set_pte_at(&init_mm, (unsigned long)addr, pte, pte_wrprotect(*pte)); spin_unlock(ptl); // 3. 刷新TLB,确保CPU更新页表缓存 flush_tlb_kernel_range((unsigned long)addr, (unsigned long)addr + PAGE_SIZE);
关键注意事项
- 内核态执行:所有页表操作函数仅能在内核上下文调用,用户态无法直接访问。
- 页表锁保护:修改页表时必须持有
pte_lockptr获取的自旋锁,避免并发修改引发的竞态问题。 - 多页面处理:如果
ioremap的区域超过一个PAGE_SIZE,需要遍历每个页面的起始地址,重复上述查找、修改、刷新操作。 - 恢复可写:若后续需要解除只读保护,可使用
pte_mkwrite(*pte)替代pte_wrprotect(*pte),执行相同的锁和TLB刷新流程。 - 错误处理:必须检查
ioremap和lookup_address的返回值,避免空指针或无效地址操作导致内核崩溃。
内容的提问来源于stack exchange,提问作者liuye
相关产品推荐
相关产品推荐

