CPUID、SGX中使用CPUID
CPUID官网手册
返回值汇总表位于《Intel® 64 and IA-32 Architectures Software Developer's Manual Combined Volumes 2A Vol》的Table 3-8. Information Returned by CPUID Instruction。
这个表占了足足19页,吓人。不过很丰富,很有用。
官网下载地址如下,注意是在2A卷中。
https://software.intel.com/content/www/us/en/develop/download/intel-64-and-ia-32-architectures-software-developers-manual-volume-2a-instruction-set-reference-a-l.html
下完以后搜索Table 3-8. Information Returned by CPUID Instruction就能快速找到。
SGX中使用CPUID
正常来说,Enclave内部是不可以使用CPUID指令的(SGX手册上有说)。但实际中Enclave内部却有cpuid硬件的直接使用,挺奇怪?难道是SGX更新了?
至于为什么Enclave内部为什么不能用CPUID硬件指令,相关资料挺少,我的猜测是CPUID硬件指令需要系统权限(但似乎并不是)或者存在某些安全影响(什么安全影响尚不清楚)。
总之,Enclave内部不能使用cpuid指令,不可信世界是可以任意使用cpuid指令。
1. 不可信世界端(可任意调用cpuid硬件指令)
如下几个是壳函数,最终会调用实际执行CPUID的函数
//位于/psw/urts/cpu_features.h
inline void sgx_cpuid(unsigned int in_eax, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
{int cpu_info[4] = {0};__cpuid(cpu_info, in_eax);*eax = cpu_info[0];*ebx = cpu_info[1];*ecx = cpu_info[2];*edx = cpu_info[3];
}
//位于/psw/urts/cpu_features.h
inline void sgx_cpuidex(unsigned int in_eax, unsigned int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
{int cpu_info[4] = {0};__cpuidex(cpu_info, in_eax, leaf);*eax = cpu_info[0];*ebx = cpu_info[1];*ecx = cpu_info[2];*edx = cpu_info[3];
}
下面这个函数是一个OCALL函数,专门承载Enclave内部对CPUID指令调用的需求,因为Enclave内部是不能使用CPUID硬件指令。这个OCALL已经被写到了psw/urts/linux/urts{_internal}.lds符号文件、common/inc/sgx_tstdc.edl这个Enclave接口描述文件中,方便Enclave内部调用。
//psw/urts/se_ocalls.cpp
extern "C" void sgx_oc_cpuidex(int cpuinfo[4], int leaf, int subleaf)
{__cpuidex(cpuinfo, leaf, subleaf);
}
上述几个壳函数都是最终调用__cpuid{ex}这个壳函数
//位于common/inc/internal/linux/cpuid_gnu.h
static inline void __cpuidex(int a[4], int b, int c)
{a[0] = b;a[2] = c;cpuid(&a[0], &a[1], &a[2], &a[3]);
}
//位于common/inc/internal/linux/cpuid_gnu.h
static inline void __cpuid(int a[4], int b)
{a[0] = b;a[2] = 0;cpuid(&a[0], &a[1], &a[2], &a[3]);
}
__cpuid{ex}壳函数最终会调用下面这个cpuid函数,并执行CPUID硬件指令。这些函数定义下common文件夹下面,这个common指代的是什么意思。
//位于common/inc/internal/linux/cpuid_gnu.h/* This is a PIC-compliant version of CPUID */
static inline void cpuid(int *eax, int *ebx, int *ecx, int *edx)
{
#if defined(__x86_64__)asm("cpuid": "=a" (*eax),"=b" (*ebx),"=c" (*ecx),"=d" (*edx): "0" (*eax), "2" (*ecx));#else/*on 32bit, ebx can NOT be used as PIC code*/asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1": "=a" (*eax), "=r" (*ebx), "=c" (*ecx), "=d" (*edx): "0" (*eax), "2" (*ecx));
#endif
}
2. Enclave内部(不能直接使用cpuid硬件指令)
//位于sdk/tlibc/gen/se_cpuid.c
sgx_status_t sgx_cpuid(int cpuinfo[4], int leaf)
{return sgx_cpuidex(cpuinfo, leaf, 0);
}
//位于sdk/tlibc/gen/se_cpuid.c
sgx_status_t sgx_cpuidex(int cpuinfo[4], int leaf, int subleaf)
{if (cpuinfo == NULL)return SGX_ERROR_INVALID_PARAMETER;return sgx_oc_cpuidex(cpuinfo, leaf, subleaf);
}
Enclave内部的壳函数会通过sgx_oc_cpuidex这个OCALL函数切换到不可新世界调用CPUID硬件指令
下面这两个函数位于sdk内(sdk是Enclave内部程序所依赖的静态库),这就很奇怪了,为什么Enclave内部会需要定义这两个函数,难道能直接用?
//位于sdk/gperftools/gperftools-2.7/src/base/atomicops-internals-x86.cc// Inline cpuid instruction. In PIC compilations, %ebx contains the address
// of the global offset table. To avoid breaking such executables, this code
// must preserve that register's value across cpuid instructions.
#if defined(__i386__)
#define cpuid(a, b, c, d, inp) \asm ("mov %%ebx, %%edi\n" \"cpuid\n" \"xchg %%edi, %%ebx\n" \: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
#elif defined (__x86_64__)
#define cpuid(a, b, c, d, inp) \asm ("mov %%rbx, %%rdi\n" \"cpuid\n" \"xchg %%rdi, %%rbx\n" \: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
#endif
//位于sdk/libcapable/linux/sgx_capable.cpp/* __cpuid(unsinged int info[4], unsigned int leaf, unsigned int subleaf); */
/* Because gcc's __get_cpuid() intrinsic is difficult to work with */
#define __cpuid(x,y,z) asm volatile("cpuid":"=a"(x[0]),"=b"(x[1]),"=c"(x[2]),"=d"(x[3]):"a"(y),"c"(z))
CPUID、SGX中使用CPUID相关推荐
- c linux 获取cpuid_[C] 在GCC中获取CPUID信息(兼容VC)
前面我们尝试过在VC中获取CPUID信息.现在再来试试GCC编译器. 一.调用CPUID指令 怎么调用CPUID指令呢?有三种办法-- 1. 用汇编语言编写一个cpuid函数,然后调整链接器配置,在C ...
- [C] 在GCC中获取CPUID信息(兼容VC)
作者:zyl910 前面我们尝试过在VC中获取CPUID信息.现在再来试试GCC编译器. 一.调用CPUID指令 怎么调用CPUID指令呢?有三种办法-- 1. 用汇编语言编写一个cpuid函数,然后 ...
- Qt 程序中获取 CPUID UUID 等系统信息的方法(win 平台,wmic)
Qt 程序中获取 CPUID UUID 等系统信息的方法(win 平台,wmic) 最近的程序中要加入序列号注册的功能.这就需要获得电脑的一些基本信息,比如 UUID .或者 CPUID 一类的固定的 ...
- xp计算机硬盘序列号,发表一个最简单的XP以上系统中获取CPUID、硬盘序列号、BIOS序列号等等的函数!(100分)...
//uses ActiveX, ComObj; //这个函数使用了WMI,而且只获取第一个硬件/软件设置的信息. //用户可以根据需要自行修改. function GetWMIProperty(WMI ...
- Intel 64/x86_64/IA-32/x86处理器指令集 - CPUID (1) - 概述
CPUID指令 Introduction of CPUID instruction 根据Wikipedia,CPUID指令是x86处理器体系结构的补充指令,使得软件可以枚举当前运行的处理器的详细特性, ...
- linux cpuid指令,通过CPUID指令获取CPU信息
1.简介 在计算机领域中需要用到CPU信息的地方有很多.比如,在可信计算中,需要收集终端的软硬件的完整性信息,其中就包含CPU的信息:再比如,一些加密软件需要绑定CPU的某些信息,去生成加密密钥.本文 ...
- Intel x86_64 CPUID指令介绍
Intel CPUID指令简介 一.CPUID简介 1.1 CPUID 功能简介 1.2 处理器是否支持 CPUID指令 1.3 指令返回基本信息 1.4 指令返回扩展信息 二.CPUID指令参数输入 ...
- Intel CPU的CPUID指令
Intel有一个超过100页的文档,专门介绍cpuid这条指令,可见这条指令涉及内容的丰富. 记得去年的时候,曾经有个"英布之剑"问过我这条指令,当时并没有给出一个满意的回答,现在 ...
- 通过CPUID指令读取处理器信息
一.CPUID简介 CPUID操作码是一个面向x86架构的处理器补充指令,它的名称派生自CPU识别,作用是允许软件通过CPUID指令读取处理器的详细信息. 二.CPUID基本原理 CPUID有很多fu ...
最新文章
- Django model.py表单设置默认值允许为空
- Exchange 2013部署系列之(十)信息权限保护RMS和Exchange 2013的整合
- VLAN,trunk,以太网通道
- 电话订票每日开始时间(几点放票) - 北京本地宝
- C++ Primer 5th笔记(chap 16 模板和泛型编程)包扩展
- Sql Group by 使用
- 杭电2013-蟠桃记(C++)
- Linux netfilter源码分析(2)
- Java开发中遇到具有挑战的事_170道Java工程师面试题,你敢挑战吗?
- android 标题栏进度圈使用方法,Android 标题栏显示进度条
- 20155209 林虹宇 Exp3 免杀原理与实践
- 使用 Python 的人脸识别系统
- 程序员的自我修养 -- 读书笔记
- 5G促进VR产业规模化运用,2000亿市场等着被瓜分 | 附报告下载
- 5G在智慧农业中的实践和探索
- 【ubuntu】Ubuntu系统下安装石墨文档
- iphone html 手机震动,苹果如何让你手机震动爽到极致 全靠震动马达
- Oracle卸载教程
- [Java 教程 00] 计算机基础
- 常见的 PHP IDE 开发工具汇总 (LAMP)
热门文章
- Unity shader Note :高级纹理(CubeMap反射折射菲涅尔,Rendermap镜子玻璃,程序纹理)
- facebook [ yoga ]
- 听计算机课评语与建议,听课评语与建议
- BERT and beyond
- 苹果手机升级13无法开机_iOS13.5正式更新,升级过程中死机怎么解决?
- WinEdt+CTeX+pst-optic宏包使用初体验
- git 新建分支并切换到该分支_git分支的创建、删除、切换、合并
- 小米盒子3 增强版 体验
- 老式硬盘物理结构和CHS 3D寻址
- 怎样在python的turtle中输入文字_如何用Python的turtle库写出自己的名字?