修改ARM KVM中CNTFRQ_EL0的值,供客人启动

发布于 2025-01-23 13:17:58 字数 2096 浏览 3 评论 0原文

我发现有一个 patch for Linux在linux上运行的系统 CNTFRQ寄存器。从补丁:

cntfrq {,_ el0}通常是不幸的情况 从固件方面编程错误,将其运到内核 围绕它工作。这通常是通过提供替代方案来完成的 设备树中的频率。

不幸的是,CNTFRQ可从EL0访问,为用户空间提供了 错误的频率,并且每个CPU可能有不同的频率, 绝对不是您想要的。可能的解决方法是陷入困境 进入内核并模仿它(与VDSO一起 禁用),这就是本系列正在实现的目标。

据我所知,CNTFRQ寄存器仅从EL3(Monitor)中写作,并且可以从所有例外级别中读取。我的也有错误配置的CNTFRQ,它将Bootloader设置为0(我无法修改)。

我想要的是在主机机器上运行Windows Arm,该机器机器也有错误编程的CNTFRQ寄存器。 Windows只是不会将CNTFRQ设置为0启动。由于Linux是开源内核,我们只能在代码中应用补丁,但是Windows是商业OS,因此我认为修补其代码(以及也是如此)更难到二进制补丁)。

我想到的:

  • 陷阱并模仿KNTFRQ在KVM陷阱中读取的读物
  • ,并从Qemu仿真
  • (我认为这太慢)使用GDB使用相同的东西来列出QEMU的指令,然后检查它是否是从CNTFRQ读取的,然后设置设置读取的正确值。
  • 二进制补丁窗口(不确定在哪里修补)。

有什么想法吗?先感谢您!如果我错了,请纠正我。


编辑1 : 我将ntoskrnl.exe加载到ida上,然后使用一个称为的脚本IDA-ARM-SYSTEM-HIGHLIGHTING

然后我搜索了CNTFRQ并得到了3个结果:

列表中的第一个:

注意:是我用来修补EDK2启动在KVM上的补丁程序,它实际上可以工作。补丁程序将读取cntfrq_el0设置为26MHz(26000000)。因此,我可以使用该值来修补cntfrq_el0ntoskrnl.exe中读取吗?

另外,假装值26MHz(0x18cba80)可以使用时,当我尝试替换MRS x8,#3,c14,c0,c0,#0带有ldr x8,= 0x18CBA80,它需要3个说明!

有什么想法吗?再一次,非常感谢!

I found that there is a patch for Linux to run on systems that have misprogrammed CNTFRQ register. From the patch:

It is an unfortunate situation that CNTFRQ{,_EL0} is often
misprogrammed from the firmware side, leaving it up to the kernel to
work around it. This is usually done by providing an alternative
frequency in the Device Tree.

Unfortunately, CNTFRQ is accessible from EL0, giving userspace the
wrong frequency, and potentially a different frequency per CPU, which
is definitely not what you want. A possible workaround is to trap this
into the kernel and to emulate it (together with the VDSO being
disabled), and this is what this series is achieving.

From what I know, the CNTFRQ register is only writable from EL3 (monitor), and readable from all exception levels. Mine also has misconfigured CNTFRQ, it's set to 0 by bootloader (which I cannot modify).

What I want is to run Windows ARM on KVM on the host machine which also has misprogrammed CNTFRQ register. Windows just simply won't boot with CNTFRQ set to 0. Since Linux is an open source kernel, we can just apply patches in the code, but Windows is a commercial OS, so I think it's somewhat illegal to patch its code (and also harder to binary patch).

What I have think of:

  • Trap and emulate the read from CNTFRQ in KVM
  • Trap and emulate from QEMU
  • (I think this is too slow) Use the same thing GDB use to list instructions from QEMU, then check if it's reading from CNTFRQ, then set the correct value to the read.
  • Binary patch Windows (not sure where to patch).

Any ideas? Thank you in advance! Please correct me if I'm wrong.


Edit 1:
I loaded ntoskrnl.exe to IDA and then use a script called ida-arm-system-highlight.

Then I searched for CNTFRQ and got 3 results:
IDA search result

The first one in the list:
1st search

Note: This is the patch I used to patch EDK2 to boot on my KVM, and it actually worked. The patch set the read CNTFRQ_EL0 to be 26Mhz (26000000). So could I use that value to patch CNTFRQ_EL0 read in ntoskrnl.exe?

Also, pretend that the value 26Mhz (0x18CBA80) works, when I tried replacing MRS X8, #3, c14, c0, #0 with LDR X8, =0x18CBA80, it takes 3 instructions!

take 3 instructions

Any ideas? Again, thanks a lot!

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文