性能优化特性之:E0PD

简介: 本文介绍了倚天实例上进行安全特性关闭以提升性能的特性:E0PD,并且从优化原理、使用方法、性能收益等方面做了详细阐述。

优化原理

E0PD是ARMv8.5扩展引入的一个硬件防护特性,它用来替代KPTI避免来自用户态的Meltdown漏洞攻击。KPTI技术通过在返回用户态时unmap kernel space的方式避免内核地址空间的暴露,因此在退出内核态时unmap内核页表以及在进入内核态时重新映射内核页表会带来极大性能开销。E0PD在硬件侧防护内核地址空间从而使内核可以绕过KPTI,因而带来性能提升。

在内核优化方面,开启E0PD绕过KPTI的代码如下(省略一些无关的代码片段)。在boot阶段,内核调用unmap_kernel_at_el0函数检测是否需要开启KPTI unmap内核地址空间功能,其中的重要一项检测就是调用kaslr_requires_kpti,在此函数内检查硬件是否支持E0PD并且内核是否打开E0PD,若是则返回false,表示不需要启用KPTI功能。

static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
        int scope)
{
  …………
  /* Useful for KASLR robustness */
  if (kaslr_requires_kpti()) {
    if (!__kpti_forced) {
      str = "KASLR";
      __kpti_forced = 1;
    }
  }
  …………
  /* Forced? */
  if (__kpti_forced) {
    pr_info_once("kernel page table isolation forced %s by %s\n",
           __kpti_forced > 0 ? "ON" : "OFF", str);
    return __kpti_forced > 0;
  }
  …………
}
/*
 * This check is triggered during the early boot before the cpufeature
 * is initialised. Checking the status on the local CPU allows the boot
 * CPU to detect the need for non-global mappings and thus avoiding a
 * pagetable re-write after all the CPUs are booted. This check will be
 * anyway run on individual CPUs, allowing us to get the consistent
 * state once the SMP CPUs are up and thus make the switch to non-global
 * mappings if required.
 */
bool kaslr_requires_kpti(void)
{
  if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE))
    return false;
  /*
   * E0PD does a similar job to KPTI so can be used instead
   * where available.
   */
  if (IS_ENABLED(CONFIG_ARM64_E0PD)) {
    u64 mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
    if (cpuid_feature_extract_unsigned_field(mmfr2,
            ID_AA64MMFR2_E0PD_SHIFT))
      return false;
  }
  /*
   * Systems affected by Cavium erratum 24756 are incompatible
   * with KPTI.
   */
  if (IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) {
    extern const struct midr_range cavium_erratum_27456_cpus[];
    if (is_midr_in_range_list(read_cpuid_id(),
            cavium_erratum_27456_cpus))
      return false;
  }
  return kaslr_offset() > 0;
}

使用方法

使用Alinux3.2208及以后版本

Alinux3在2208版本(内核版本5.10.134)已默认启用 说明:从upstream打上E0PD相关patch(anck 5.10已经合入),

  • 3e6c69a arm64: Add initial support for E0PD
  • 92ac6fd arm64: Don't use KPTI where we have E0PD

编译内核时启用E0PD特性

如果需要自己编译内核,可以在编译参数中打开E0PD配置

CONFIG_ARM64_E0PD=y

性能收益

KPTI的内核地址空间map、unmap操作在通用路径上,所以E0PD对KPTI的优化影响广泛。在我们的测试中,E0PD优化对基础benchmark和E2E应该都带来了5-23%的大幅度性能提升。




---------------------------------------------------------------------------------------

更多调优信息,请参考:

龙蜥社区:https://openanolis.cn/

KeenTune SIG:https://openanolis.cn/sig/KeenTune

阿里云龙蜥操作系统专区:https://developer.aliyun.com/group/aliyun_linux

相关文章
|
Linux Anolis
性能优化特性之:EXT4 Fast Commit
本文介绍了倚天实例上进行IO优化的特性:Fast Commit,并对其优化原理、使用方法进行了详细阐述
|
存储 固态存储 关系型数据库
性能优化特性之:16K原子写
本文介绍了在倚天实例上进行内存优化的调优特性:16K原子写 的优化原理、使用方法。
|
数据中心 Anolis
性能优化特性之:LSE指令集编译优化
本文介绍了倚天实例上的编译优化特性:LSE,并从优化原理、使用方法进行了详细阐述。
|
存储 缓存 安全
认识SMMU以及理理SMMU与TrustZone的联系?
认识SMMU以及理理SMMU与TrustZone的联系?
789 0
|
监控 调度 开发工具
IO神器blktrace使用介绍
## 前言 1. blktrace的作者正是block io的maintainer,开发此工具,可以更好的追踪IO的过程。 2. blktrace 结合btt可以统计一个IO是在调度队列停留的时间长,还是在硬件上消耗的时间长,利用这个工具可以协助分析和优化问题。 ## blktrace的原理 一个I/O请求的处理过程,可以梳理为这样一张简单的图: ![](http://image
20428 0
|
7月前
|
NoSQL Linux 编译器
GDB符号表概念和在Linux下获取符号表的方法
通过掌握这些关于GDB符号表的知识,你可以更好地管理和理解你的程序,希望这些知识可以帮助你更有效地进行调试工作。
336 16
|
存储 网络协议 Linux
高效调试与分析:利用ftrace进行Linux内核追踪(下)
高效调试与分析:利用ftrace进行Linux内核追踪
|
关系型数据库 MySQL PostgreSQL
性能优化特性之:code_hugepage - 代码大页
本文介绍了倚天实例上的内存优化特性:代码段大页,并从优化原理、使用方法、性能收益进行详细阐述。
|
存储 关系型数据库 MySQL
带你读《2022龙蜥社区全景白皮书》——5.3.4 跨处理器节点内存访问优化
带你读《2022龙蜥社区全景白皮书》——5.3.4 跨处理器节点内存访问优化
854 88
|
芯片 Anolis
性能优化特性之:TLBI - TLB range优化
本文介绍了倚天实例上的内存优化特性:TLBi,并从优化原理、使用方法进行详细阐述。