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相关推荐

  1. c linux 获取cpuid_[C] 在GCC中获取CPUID信息(兼容VC)

    前面我们尝试过在VC中获取CPUID信息.现在再来试试GCC编译器. 一.调用CPUID指令 怎么调用CPUID指令呢?有三种办法-- 1. 用汇编语言编写一个cpuid函数,然后调整链接器配置,在C ...

  2. [C] 在GCC中获取CPUID信息(兼容VC)

    作者:zyl910 前面我们尝试过在VC中获取CPUID信息.现在再来试试GCC编译器. 一.调用CPUID指令 怎么调用CPUID指令呢?有三种办法-- 1. 用汇编语言编写一个cpuid函数,然后 ...

  3. Qt 程序中获取 CPUID UUID 等系统信息的方法(win 平台,wmic)

    Qt 程序中获取 CPUID UUID 等系统信息的方法(win 平台,wmic) 最近的程序中要加入序列号注册的功能.这就需要获得电脑的一些基本信息,比如 UUID .或者 CPUID 一类的固定的 ...

  4. xp计算机硬盘序列号,发表一个最简单的XP以上系统中获取CPUID、硬盘序列号、BIOS序列号等等的函数!(100分)...

    //uses ActiveX, ComObj; //这个函数使用了WMI,而且只获取第一个硬件/软件设置的信息. //用户可以根据需要自行修改. function GetWMIProperty(WMI ...

  5. Intel 64/x86_64/IA-32/x86处理器指令集 - CPUID (1) - 概述

    CPUID指令 Introduction of CPUID instruction 根据Wikipedia,CPUID指令是x86处理器体系结构的补充指令,使得软件可以枚举当前运行的处理器的详细特性, ...

  6. linux cpuid指令,通过CPUID指令获取CPU信息

    1.简介 在计算机领域中需要用到CPU信息的地方有很多.比如,在可信计算中,需要收集终端的软硬件的完整性信息,其中就包含CPU的信息:再比如,一些加密软件需要绑定CPU的某些信息,去生成加密密钥.本文 ...

  7. Intel x86_64 CPUID指令介绍

    Intel CPUID指令简介 一.CPUID简介 1.1 CPUID 功能简介 1.2 处理器是否支持 CPUID指令 1.3 指令返回基本信息 1.4 指令返回扩展信息 二.CPUID指令参数输入 ...

  8. Intel CPU的CPUID指令

    Intel有一个超过100页的文档,专门介绍cpuid这条指令,可见这条指令涉及内容的丰富. 记得去年的时候,曾经有个"英布之剑"问过我这条指令,当时并没有给出一个满意的回答,现在 ...

  9. 通过CPUID指令读取处理器信息

    一.CPUID简介 CPUID操作码是一个面向x86架构的处理器补充指令,它的名称派生自CPU识别,作用是允许软件通过CPUID指令读取处理器的详细信息. 二.CPUID基本原理 CPUID有很多fu ...

最新文章

  1. Django model.py表单设置默认值允许为空
  2. Exchange 2013部署系列之(十)信息权限保护RMS和Exchange 2013的整合
  3. VLAN,trunk,以太网通道
  4. 电话订票每日开始时间(几点放票) - 北京本地宝
  5. C++ Primer 5th笔记(chap 16 模板和泛型编程)包扩展
  6. Sql Group by 使用
  7. 杭电2013-蟠桃记(C++)
  8. Linux netfilter源码分析(2)
  9. Java开发中遇到具有挑战的事_170道Java工程师面试题,你敢挑战吗?
  10. android 标题栏进度圈使用方法,Android 标题栏显示进度条
  11. 20155209 林虹宇 Exp3 免杀原理与实践
  12. 使用 Python 的人脸识别系统
  13. 程序员的自我修养 -- 读书笔记
  14. 5G促进VR产业规模化运用,2000亿市场等着被瓜分 | 附报告下载
  15. 5G在智慧农业中的实践和探索
  16. 【ubuntu】Ubuntu系统下安装石墨文档
  17. iphone html 手机震动,苹果如何让你手机震动爽到极致 全靠震动马达
  18. Oracle卸载教程
  19. [Java 教程 00] 计算机基础
  20. 常见的 PHP IDE 开发工具汇总 (LAMP)

热门文章

  1. Unity shader Note :高级纹理(CubeMap反射折射菲涅尔,Rendermap镜子玻璃,程序纹理)
  2. facebook [ yoga ]
  3. 听计算机课评语与建议,听课评语与建议
  4. BERT and beyond
  5. 苹果手机升级13无法开机_iOS13.5正式更新,升级过程中死机怎么解决?
  6. WinEdt+CTeX+pst-optic宏包使用初体验
  7. git 新建分支并切换到该分支_git分支的创建、删除、切换、合并
  8. 小米盒子3 增强版 体验
  9. 老式硬盘物理结构和CHS 3D寻址
  10. 怎样在python的turtle中输入文字_如何用Python的turtle库写出自己的名字?