如何使用 LKM 中的 perf-interface 读取已退出的指令?
How to read instructions retired using the perf-interface inside a LKM?
如何从内部内核space读取PMU?
对于分析任务,我需要从内核内部读取 PMU 提供的退役指令。 perf_event_open 系统调用似乎提供了这种能力。在我的源代码中我
#include <linux/syscalls.h>
为 perf_event_attr 结构设置我的参数并调用 sys_perf_event_open()。提到的 header 包含函数声明。检查“/proc/kallsyms”时,确认存在名称为sys_perf_event_open的系统调用。该符号在全球可用,由 T:
表示
ffffffff8113fe70 T sys_perf_event_open
所以据我所知一切都应该有效。
仍然,在编译或插入 LKM 时,我得到 warning/error sys_perf_event_open 不存在。
WARNING: "sys_perf_event_open" [/home/vagrant/mods/lkm_read_pmu/read_pmu.ko] undefined!
我需要做什么才能获得那些已停用的指令计数器?
/proc/kallsyms
文件显示源代码中定义的所有内核符号。对了,大写的T在内核二进制文件的文本部分表示一个全局符号,但这里的“全局”是C语言的意思。也就是说,它可以在内核本身的其他文件中使用。您不能仅仅因为它是全局的就从内核模块调用内核函数。
内核模块只能使用在内核源代码中用EXPORT_SYMBOL
导出的内核符号。从内核 2.6.0 开始,none 的系统调用被导出,所以你不能从内核模块调用它们中的任何一个,包括 sys_perf_event_open
。系统调用实际上是为从用户 space 调用而设计的。这一切意味着您不能在内核模块中使用 perf_event 子系统。
也就是说,我认为您可以修改内核以将 EXPORT_SYMBOL
添加到 sys_perf_event_open
。这将使它成为一个导出符号,这意味着它可以从内核模块中使用。
如何从内部内核space读取PMU?
对于分析任务,我需要从内核内部读取 PMU 提供的退役指令。 perf_event_open 系统调用似乎提供了这种能力。在我的源代码中我
#include <linux/syscalls.h>
为 perf_event_attr 结构设置我的参数并调用 sys_perf_event_open()。提到的 header 包含函数声明。检查“/proc/kallsyms”时,确认存在名称为sys_perf_event_open的系统调用。该符号在全球可用,由 T:
表示ffffffff8113fe70 T sys_perf_event_open
所以据我所知一切都应该有效。
仍然,在编译或插入 LKM 时,我得到 warning/error sys_perf_event_open 不存在。
WARNING: "sys_perf_event_open" [/home/vagrant/mods/lkm_read_pmu/read_pmu.ko] undefined!
我需要做什么才能获得那些已停用的指令计数器?
/proc/kallsyms
文件显示源代码中定义的所有内核符号。对了,大写的T在内核二进制文件的文本部分表示一个全局符号,但这里的“全局”是C语言的意思。也就是说,它可以在内核本身的其他文件中使用。您不能仅仅因为它是全局的就从内核模块调用内核函数。
内核模块只能使用在内核源代码中用EXPORT_SYMBOL
导出的内核符号。从内核 2.6.0 开始,none 的系统调用被导出,所以你不能从内核模块调用它们中的任何一个,包括 sys_perf_event_open
。系统调用实际上是为从用户 space 调用而设计的。这一切意味着您不能在内核模块中使用 perf_event 子系统。
也就是说,我认为您可以修改内核以将 EXPORT_SYMBOL
添加到 sys_perf_event_open
。这将使它成为一个导出符号,这意味着它可以从内核模块中使用。