对arm64中的堆栈指针感到困惑,当内核在EL2上运行时,sp​​与SP_EL2寄存器不同

发布于 2025-01-10 03:12:58 字数 834 浏览 1 评论 0原文

在虚拟机上调试 Linux 启动时,我发现堆栈指针寄存器很奇怪。我在 start_kernel 函数的早期就处于 printk 例程中。 (此时串口未连接,数据仅写入日志缓冲区)。 当我在函数 vsnprintf (linux-5.4.21) 中时,当我检查堆栈指针时,会看到这样的情况(这是在 qemu 上运行的 arm64 虚拟机上看到的)。

(gdb) info reg sp
sp             0xffffffc0105d3bf0  0xffffffc0105d3bf0
(gdb) info reg SP_EL2
SP_EL2         0x407cd70           67620208
(gdb) info reg SP_EL1
SP_EL1         0x0                 0
(gdb) info reg SP_EL0
SP_EL0         0xffffffc0105d9f00  -274603335936

就我而言,内核在 EL2 上运行,因此我认为 sp 值将等于 SP_EL2,但事实并非如此。相反,SP_EL2 仍然设置为由 u-boot 程序设置的物理地址(u-boot 程序运行在 0x4000000 ~ 范围,linux 内核运行在 0x80000000 ~ 范围,只有 8MB)。< br> 我知道当内核在 EL2 上运行时,PS_EL0 包含 init_task 的地址。但是为什么不使用 SP_EL2 以及当我向下执行函数调用时递减的真实 sp 值是什么? ADD:我检查了SPSel寄存器设置为1。所以SP_EL2正在被使用。所以我的问题是:为什么不使用 SP_EL2?实际使用的这个sp寄存器是什么?

While debugging linux booting on a virtual machine, I found the stack pointer registers are strange. I was in a printk routine early in the start_kernel function. (the serial port is not connected so the data is just wrtten to the log buffer at this time).
When I'm in the function vsnprintf (linux-5.4.21), when I examine the stack pointers, it is seen like this(this is seen for the arm64 virtual machine running on qemu).

(gdb) info reg sp
sp             0xffffffc0105d3bf0  0xffffffc0105d3bf0
(gdb) info reg SP_EL2
SP_EL2         0x407cd70           67620208
(gdb) info reg SP_EL1
SP_EL1         0x0                 0
(gdb) info reg SP_EL0
SP_EL0         0xffffffc0105d9f00  -274603335936

In my case, the kernel runs at EL2 so I thought the sp value will be equal to SP_EL2 but it's not. Instead the SP_EL2 is set still as it has been set by the u-boot program, a physical address (u-boot program was running at 0x4000000 ~ range, and the linux kernel is running at 0x80000000 ~ range, with only 8MB).
I know PS_EL0 contains the address of init_task when kernel is running at EL2. But why is SP_EL2 not being used and what is this real sp value which is decremented as I go down the function calls?
ADD : I checked SPSel register is set to 1. So SP_EL2 is being used. So my questiog is : why isn't SP_EL2 being used? and what is this sp register which is actually being used?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北恋 2025-01-17 03:12:58

这只是 QEMU 将 SP_ELx 系统寄存器显示到 gdbstub 时的一个小错误:您应该忽略 guest 虚拟机当前所处的异常级别的 SP_ELx 值,而查看正常的 sp 寄存器。

该错误的原因在于,从架构上来说,如果您在来宾 CPU 上运行代码,则无法访问 SP_ELx 系统寄存器以获取等于或高于您正在运行的异常级别。因此,EL2 代码本身无法读取 SP_EL2——只有 EL3 可以使用 SP_EL2 系统寄存器。 EL2 代码查看其自己的堆栈指针的唯一方法是使用 SP。 QEMU 利用这一点来避免必须做额外的工作来确保与当前 SP 相同的 SP_ELx 系统寄存器值与真实 SP 寄存器同步。但是 gdbstub 访问器允许您作为 gdb 用户读取当前运行的代码无法访问的系统寄存器。大多数情况下,这可以正常工作,但有时你会得到无意义的结果,就像这样。

This is just a minor bug in QEMU's display of the SP_ELx system registers to the gdbstub: you should ignore the SP_ELx value for the exception level the guest is currently at, and look at the normal sp register instead.

The reason for the bug is that architecturally, if you're code running on the guest CPU you cannot access the SP_ELx system register for an exception level that's equal to or higher than the one you're running at. So EL2 code cannot itself read SP_EL2 -- only EL3 can use the SP_EL2 system register. The only way EL2 code can look at its own stack pointer is to use SP. QEMU takes advantage of this to avoid having to do extra work to ensure that the SP_ELx system register value that would be the same as the current SP is in sync with the real SP register. But the gdbstub accessors let you as the gdb user read system registers that the currently running code doesn't have the ability to access. Mostly that works OK, but occasionally you get nonsense results, like this one.

伤感在游骋 2025-01-17 03:12:58

https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/SP-EL2--Stack-Pointer--EL2-

保存与 EL2 关联的堆栈指针。在 EL2 执行时,SPSel 的值。 SP 确定当前堆栈指针:

https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/SP-EL2--Stack-Pointer--EL2-

Holds the stack pointer associated with EL2. When executing at EL2, the value of SPSel. SP determines the current stack pointer:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文