我想在我的内核模块中编写一个函数来使虚拟地址的物理页Map无效。但是,我不知道如何刷新虚拟地址页的tlb条目。我尝试在模块代码中使用“flush_tlb_range”。但是,它报告“函数'flush_tlb_range'的隐式声明”。
下面是我的代码中的一个片段
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
u64 mypool_get_page(u64 gfn, bool write_fault, bool *writable){
u64 kvm_hva;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma = current->mm->mmap;
unsigned int level;
pte_t *ptep;
kvm_hva = map_lookup(index);
....
//invalid kvm_hva in page table
ptep = lookup_address(kvm_hva, &level);
if (ptep) {
pte_clear(mm, kvm_hva, ptep);
flush_tlb_range(vma,kvm_hva, kvm_hva+PAGE_SIZE);
}
...
}
这是我的Makefile
mypool-objs := pool-main.o maptable.o
obj-m += mypool.o
KERNEL := /lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
modules :
$(MAKE) -C $(KERNEL) M=$(PWD) modules
.PHONEY:clean
clean :
rm -rf *.o *.ko
有人能教我如何在内核模块中使tlb无效吗?
我还尝试使用'flush_tlb_mm_range'。但是,它还报告函数“flush_tlb_mm_range”的隐式声明。
1条答案
按热度按时间vpfxa7rd1#
有多种方法可以实现目标,这取决于你想要实现的目标。
第一选项
如果您使用的是x86,则可以使用以下命令刷新当前运行的CPU的TLB条目
但是,这并不能**确保系统其余核心之间的一致性。您需要执行TLBSHOOTDOWN并手动执行IPI以同步TLB。对于其他架构,例如ARM64,这不是必需的。
第二选项
更改Linux内核并导出要使用的函数的符号。这是一种非常肮脏的方法,不应该在生产环境中使用,但如果只是为了测试,这应该足够了。
第三种选择
使用
kallsyms_lookup_name
查找函数的地址。下面是一个示例内核模块。请注意,启用IBT和AFAIK时存在问题,目前没有解决此问题的方案stackoverflow-discussion。