Intel MKTME 在Linux Kernel中的初始化和Key编辑API
Intel MKTME 在Linux Kernel中的初始化和Key编辑API
PCONFIG指令枚举 & MKTME Target枚举
检查cpu是否包含某feature,用的是boot_cpu_has([feature_encode])
__builtin_constant_p 是编译器gcc内置函数,用于判断一个值是否为编译时常量,如果是常数,函数返回1 ,否则返回0。由于编译时,cpu_has传入的bit一定是常量,类似 X86_FEATURE_PCONFIG代表的18*32+18,因此这里的__builtin_constant_p返回true。
所以针对CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit),就可以转化为:
Feature_bit即上面的类似于X86_FEATURE_PCONFIG的数,例如1832+18,其中1832,是为了保证这个feature_bit的高于5个bit的位置为word数组中的index,即18 << 5,低5bit为这个feature在这个word中的bit_index,所以上面的这一堆CHECK_BIT_IN_MASK_WORD中,只会有一个宏的(feature_bit)>>5)==(word)为真,(feature_bit & 31)获得该feature bit的低5位,假设低5位为5'b 10010,即十进制18,那么1<<18,正好能与预设的REQUIRED_MASK18 做与运算,获取在该mask中,bit18是否设置为1的结果。
综上, REQUIRED_MASK_BIT_SET(X86_FEATURE_PCONFIG),就是在确认:
在REQUIRED_MASK18中,bit18是否为1,而在arch/x86/include/asm中,REQUIRED_MASK被设置为0,所以REQUIRED_MASK_BIT_SET(X86_FEATURE_PCONFIG)返回0.
kernel引入REQUIRED_MASK的目的,是为了设置优先级,即对于某些基础feature,如FPU,PSE,MSR,PAE等,会首先查询REQUIRED MASK,这样设计,即,REQUIRED_MASKn的优先级高于cpu->capabilities数组。kernel的注释中说明,我们必须构造一个最小feature集,以支持非常早期(early not old)的kernel功能。
回到我们的feature-X86_FEATURE_PCONFIG,这个feature会导致 REQUIRED_MASK_BIT_SET返回0,所以需要查看test_cpu_cap(c,bit).即test_cpu_cap(&boot_cpu_data,X86_FEATURE_PCONFIG).
即,返回boot_cpu_data->x86_capability中,该bit是否为1。那么boot_cpu_data->x86_capability是何时赋值的。
首先看到x86_capability[21]是一个基础元素为32bit unsigned int类型,包含21个元素的数组。
kernel定义了一个枚举结构,其中一共19个元素,分别代表CPUID的不同leaf。
PCONFIG的枚举是在CPUID[EAX=7,ECX=0].EDX[bit18]枚举的,因此查询CPU是否支持PCONFIG指令,需要查询x86_capability[CPUID_7_EDX],即x86_capability[18]的bit18是否为1.
在get_cpu_cap()中,会根据cpuid的取值,对c->x86_capability[CPUID_7_EDX]进行赋值:
在intel_pconfig_init()时,会检查是否支持PCONFIG指令,如果不支持,直接返回0.
如果支持PCONFIG,那么就需要对PCONFIG可以操作的target进行枚举。
CPUID[EAX=1BH,ECX=n].EAX会返回subleaf-type
0表示无效subleaf-type,并且EBX=ECX=EDX=0.
非0表示有效subleaf-type,该subleaf-type的其它相关信息会记录在EBX,ECX,EDX中。
现在只支持subleaf-type为1的subleaf,即TARGETID-subleaf-type, EBX,ECX,EDX中记录的是TARGETID数值。
即如果CPUID[EAX=1BH,ECX=n].EAX返回1,那么EBX ECX EDX中记录TARGETID数值。
任何TARGETID不为0均为有效TARGETID,目前只支持TARGETID=1,即MKMET TARGET。
而PCONFIG Leaf,也就是运行PCONFIG时,EAX输入的值与这个TARGET没有关系。
所以,针对上述代码,subleaf=0,CPUID[EAX=1BH,ECX=0].EAX会返回subleaf-type=1,即TARGETID-subleaf-type, EBX,ECX,EDX中记录的是TARGETID数值。而EBX,ECX,EDX中均会返回1,表示支持TARGETID=1.
另外spec明确规定要使用EAX=0来用PCONFIG编辑MKTME,因此之后编辑MKTME时,需要使用PCONFIG EAX=0.
至此,PCONFIG的枚举代码梳理完成。
MKTME key的编辑API
kernel只是简单提供了一个向key table写入key entry的API: mktme_key_program.
__EOF__

本文链接:https://www.cnblogs.com/haiyonghao/p/16340911.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了