慢慢欣赏arm64内核启动20 primary_entry之__cpu_setup代码第二部分

展示代码

	/*
	 * Memory region attributes
	 */
	mov_q	x5, MAIR_EL1_SET
#ifdef CONFIG_ARM64_MTE
	/*
	 * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported
	 * (ID_AA64PFR1_EL1[11:8] > 1).
	 */
	mrs	x10, ID_AA64PFR1_EL1
	ubfx	x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4
	cmp	x10, #ID_AA64PFR1_MTE
	b.lt	1f

	/* Normal Tagged memory type at the corresponding MAIR index */
	mov	x10, #MAIR_ATTR_NORMAL_TAGGED
	bfi	x5, x10, #(8 *  MT_NORMAL_TAGGED), #8

	/* initialize GCR_EL1: all non-zero tags excluded by default */
	mov	x10, #(SYS_GCR_EL1_RRND | SYS_GCR_EL1_EXCL_MASK)
	msr_s	SYS_GCR_EL1, x10

	/*
	 * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
	 * RGSR_EL1.SEED must be non-zero for IRG to produce
	 * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
	 * must initialize it.
	 */
	mrs	x10, CNTVCT_EL0
	ands	x10, x10, #SYS_RGSR_EL1_SEED_MASK
	csinc	x10, x10, xzr, ne
	lsl	x10, x10, #SYS_RGSR_EL1_SEED_SHIFT
	msr_s	SYS_RGSR_EL1, x10

	/* clear any pending tag check faults in TFSR*_EL1 */
	msr_s	SYS_TFSR_EL1, xzr
	msr_s	SYS_TFSRE0_EL1, xzr
1:
#endif
	msr	mair_el1, x5

分析过程

内存属性

第1行到第3行是注释,表示下面的代码段是设置内存属性

第4行涉及到 MAIR_EL1_SET,定义如下

/*
 * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and
 * changed during __cpu_setup to Normal Tagged if the system supports MTE.
 */
#define MAIR_EL1_SET                            \
    (MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) |    \
     MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRE, MT_DEVICE_nGnRE) |    \
     MAIR_ATTRIDX(MAIR_ATTR_DEVICE_GRE, MT_DEVICE_GRE) |        \
     MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) |        \
     MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) |            \
     MAIR_ATTRIDX(MAIR_ATTR_NORMAL_WT, MT_NORMAL_WT) |        \
     MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED))

将该宏定义的值存放在 x5,

MAIR_EL1寄存器,参考芯片手册 MAIR_EL1, Memory Attribute Indirection Register (EL1),含义如下
Provides the memory attribute encodings corresponding to the possible AttrIndx values in a Long-descriptor format translation table entry for stage 1 translations at EL1.

MAIR_EL1 定义内存属性的集合,通过编码的形式存储在8个域里面,页表通过索引指向某一个项表明页表对应内存的属性。Linux内核使用了7个属性
更详细的中文介绍可以参考参考文献1

MAIR_ATTRIDX 的宏定义如下

/* Position the attr at the correct index */
#define MAIR_ATTRIDX(attr, idx)		((attr) << ((idx) * 8))

属性相关的宏定义如下

/* MAIR_ELx memory attributes (used by Linux) */
#define MAIR_ATTR_DEVICE_nGnRnE		UL(0x00)
#define MAIR_ATTR_DEVICE_nGnRE		UL(0x04)
#define MAIR_ATTR_DEVICE_GRE		UL(0x0c)
#define MAIR_ATTR_NORMAL_NC		UL(0x44)
#define MAIR_ATTR_NORMAL_WT		UL(0xbb)
#define MAIR_ATTR_NORMAL_TAGGED		UL(0xf0)
#define MAIR_ATTR_NORMAL		UL(0xff)
#define MAIR_ATTR_MASK			UL(0xff)

索引相关的宏定义如下

/*
 * Memory types available.
 *
 * IMPORTANT: MT_NORMAL must be index 0 since vm_get_page_prot() may 'or' in
 *	      the MT_NORMAL_TAGGED memory type for PROT_MTE mappings. Note
 *	      that protection_map[] only contains MT_NORMAL attributes.
 */
#define MT_NORMAL		0
#define MT_NORMAL_TAGGED	1
#define MT_NORMAL_NC		2
#define MT_NORMAL_WT		3
#define MT_DEVICE_nGnRnE	4
#define MT_DEVICE_nGnRE		5
#define MT_DEVICE_GRE		6

CONFIG_ARM64_MTE

第5行涉及到一个条件编译选项 CONFIG_ARM64_MTE
CONFIG_ARM64_MTE 是 Linux 内核中针对 ARM64 架构的一个配置选项,它代表了对内存标签扩展(Memory Tagging Extension, MTE)的支持。
MTE 是 ARMv8.5-A 架构中引入的一项安全技术,旨在提高系统的内存安全性。
MTE 允许操作系统和应用程序为内存中的每个数据项附加一个或多个标签(或称为元数据),这些标签随数据一起移动,并在数据被访问或修改时进行检查。
这种机制可以帮助检测和控制多种内存错误,如缓冲区溢出、越界访问等,从而增强系统的安全性和稳定性。
当 CONFIG_ARM64_MTE 在 Linux 内核配置中被启用时,内核将支持并启用对 ARM64 设备上 MTE 功能的支持。这包括:
    初始化和管理标签:内核将负责初始化内存标签,并确保在系统运行时正确管理和维护这些标签。
    安全策略:内核可能实现特定的安全策略,这些策略基于标签来限制对内存区域的访问,从而减少潜在的安全风险。
    性能优化:虽然 MTE 主要是为了增强安全性而设计的,但内核也可能尝试通过优化标签的处理来提高性能。
要启用 CONFIG_ARM64_MTE,我们使用开发板的 ARM64 CPU 必须支持 MTE 功能,并且配套的 Linux 内核版本需要支持该特性。
此外,可能还需要确保固件(如 UEFI 或 UBOOT)也支持 MTE,以便在启动时正确配置 CPU。
总之,CONFIG_ARM64_MTE 是一个强大的安全特性,它可以帮助 Linux 系统在 ARM64 架构上更好地抵御内存相关的安全威胁。然而,在启用它之前,需要综合考虑上述因素再确定是否使能。
笔者使用的 linux 版本使能了 CONFIG_ARM64_MTE

ID_AA64PFR1_EL1

第6行到第9行是注释,意思如下:
如果 支持 MTE,即 (ID_AA64PFR1_EL1[11:8] > 1),那么更新如下寄存器 MAIR_EL1, GCR_EL1 and TFSR*_EL1
根据该思路,我们继续阅读代码

第10行涉及寄存器 ID_AA64PFR1_EL1 即 AArch64 Processor Feature Register 1,含义如下
Reserved for future expansion of information about implemented PE features in AArch64 state.
代码读取该寄存器的内容,并存放到 x10

第11行涉及宏定义 ID_AA64PFR1_MTE_SHIFT,其定义如下

#define ID_AA64PFR1_MTE_SHIFT        8

该行语句的含义是获取 x10 的 bits[11:8]后,存放在 x10,详见 参考2 或者 armv8.5版本以后的芯片手册,定义如下

MTE, bits [11:8]
Support for the Memory Tagging Extension. Defined values are:
0b0000    Memory Tagging Extension is not implemented.
0b0001    Memory Tagging Extension instructions accessible at EL0 are implemented. Instructions and System Registers defined by the extension not configurably accessible at EL0 are Unallocated and other System Register fields defined by the extension are RES0.
0b0010    Memory Tagging Extension is implemented.

第12行涉及到 ID_AA64PFR1_MTE,其定义如下

#define ID_AA64PFR1_MTE            0x2

第13行的含义是,如果 x10 也就是 MTE 相关的位域的值小于2,也就是硬件寄存器不支持MTE的话,那么跳转到第38行,退出 CONFIG_ARM64_MTE 的条件编译

第16行涉及 MAIR_ATTR_NORMAL_TAGGED,定义如下

#define MAIR_ATTR_NORMAL_TAGGED		UL(0xf0)

将 0xf0 存储在 x10 里面

第17行涉及到 MT_NORMAL_TAGGED,内存类型相关的宏定义在本章节的前面部分有描述

这样该指令变化为

	bfi	x5, x10, #8, #8

bfi指令的含义如下:
Bitfield Insert copies a bitfield of <width> bits from the least significant bits of the source register to bit position <lsb> of the destination register, leaving the other destination bits unchanged
即取 x10 的位域 bits[7:0] 替换 x5 的位域 bits[15:8]

GCR_EL1

第19到第21行给寄存器 GCR_EL1 进行初始化
GCR_EL1, Tag Control Register 的含义如下
在 ARMv8.5 中,GCR_EL1 寄存器是一个新的系统寄存器,它与内存标签扩展(Memory Tagging Extension,MTE)相关。其主要包括如下两个域
RRND, bit [16]
    Controls generation of tag values by the IRG instruction.    控制IRG指令生成标记值
    0b0    IRG generates a tag value as defined by RandomTag().    通过定义的 RandomTag 生成 tag 值
    0b1    IRG generates an implementation-specific tag value with a distribution of tag values no worse than generated with GCR_EL1.RRND == 0. 厂家自定义生成 tag 值
Exclude, bits [15:0]
    Allocation Tag values excluded from selection by ChooseNonExcludedTag(). 生成的 tag 值不等于该值
第20行的两个宏的定义如下

/* GCR_EL1 Definitions */
#define SYS_GCR_EL1_RRND	(BIT(16))
#define SYS_GCR_EL1_EXCL_MASK	0xffffUL

表明 tag 的值使用厂家自定义的 tag 生成,生成的 tag 值始终不等于 0xffffUL

第23行到第28行是注释,直译过来就是
如果GCR_EL1寄存器中的RRND=1的实现方式与RRND=0时相同,那么为了使IRG能够产生伪随机数,RGSR_EL1.SEED(即RGSR_EL1寄存器中的SEED字段)必须是非零的。由于RGSR_EL1寄存器在复位后处于未知状态,我们必须对其进行初始化。
不容易理解,我们先继续看看代码吧。

CNTVCT_EL0

第29行涉及到寄存器 CNTVCT_EL0 即 Counter-timer Virtual Count register,该寄存器是 64bits 的寄存器,含义如下
Holds the 64-bit virtual count value. The virtual count value is equal to the physical count value minus the virtual offset visible in CNTVOFF_EL2.
该语句的含义是将 该寄存器的值存放到 x10

第30行涉及到 SYS_RGSR_EL1_SEED_MASK,其宏定义如下

#define SYS_RGSR_EL1_SEED_MASK	0xffffUL

该语句的含义是将 从 CNTVCT_EL0 读取出来的值,只取低 16bits,该结果影响 标志寄存器 PSTATE,如果运算的结果为0,则 PSTATE 的 Z 为0

第31行涉及到arm64汇编指令 CSINC 即选择增量(Conditional Select Increment)指令
Conditional Select Increment returns, in the destination register, the value of the first source register if the condition is TRUE, and otherwise returns the value of the second source register incremented by 1.
也就是说,当 ne 的时候,也就是说 x10 的值不为0,则保持 x10 的值不变,否则 x10 的值为1

RGSR_EL1

第32行和第33行涉及的寄存器 SYS_RGSR_EL1 RGSR_EL1, Random Allocation Tag Seed Register,其含义如下
Random Allocation Tag Seed Register.
其中,SEED 域如下:
SEED, bits [23:8]
    Seed register used for generating values returned by RandomAllocationTag().
SYS_RGSR_EL1_SEED_SHIFT 涉及的宏定义

#define SYS_RGSR_EL1_SEED_SHIFT	8

所以第36行的含义是将 x10 逻辑左移 8bit,然后存放在 RGSR_EL1,作为随机数产生器的种子。

第36行涉及寄存器 TFSR_EL1,ag Fault Status Register (EL1)
该寄存器的含义如下
Holds accumulated Tag Check Faults occurring in EL1 that are not taken precisely.
该行语句清除该寄存器。

第37行涉及寄存器 TFSRE0_EL1, Tag Fault Status Register (EL0)
该寄存器的含义如下
Holds accumulated Tag Check Faults occurring in EL0 that are not taken precisely
该行语句清除该寄存器。

第40行将 x5 寄存器存入 mair_el1,如果硬件支持并且内核使能了 MTE 配置选项,在 第16行和第17行修改了 MT_NORMAL_TAGGED 属性值,这是最关键的地方

参考文献

参考1

ARM64内存属性及MAIR配置
https://blog.csdn.net/suifengershi2000/article/details/122805722

参考2

ARM64 CPU Feature Registers

ARM64 CPU Feature Registers — The Linux Kernel documentation

参考3

Memory安全和硬件Memory Tagging技术(4)
https://aijishu.com/a/1060000000347739

参考4

硬件支持的MemoryTag技术 - ARM MTE
https://zhuanlan.zhihu.com/p/545432403?utm_id=0

参考5

ARM64安全特性之MTE
https://blog.csdn.net/andlee/article/details/134817702

参考6

ARM64上开启MTE 
https://www.cnblogs.com/pengdonglin137/p/18031444

参考7

ARM64启动汇编和内存初始化(中) --- (二)
https://www.cnblogs.com/jianhua1992/p/16842866.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值