我正在尝试编写一个自定义内核,它使用%gs
作为分段基础来加载和存储x86_64下的CPU本地信息。 (我正在使用QEMU 2.1.0运行我的内核,如果这很重要。)I previously asked about this issue,但从那时起我发现了更多的信息,而且这些更改并不完全适合我之前的问题。
我使用IA32_GS_BASE
MSR加载CPU本地数据结构的地址。但是,无论我做什么,似乎MSR中的地址都没有被尊重。 %gs
仍然评估为零,因此我得到的地址是:(a)使用时崩溃,(b)不指向我之前加载的数据结构。
我有两个假设。一个是我需要在确认MSR值之前执行某种缓存清除操作。另一个是我没有正确设置MSR。但是,IA32_GS_BASE
非常记录不清,我找不到任何证据来支持这两种理论。
任何指针? (没有双关语。)
答案 0 :(得分:1)
根据我的测试,您的问题不会立即与GS
基础相关。
在qemu中运行时会出现双重故障,并未提供有关GS
问题的任何指示。使用bochs运行时,我无法从代码中获得任何合理的调试输出,但我可以使用内置调试器来证明至少GS
base的设置和读取操作有效。
(0) [0x000000000030d346] 0008:ffffff800030d346 (unk. ctxt): wrmsr ; 0f30
<bochs:20> r
rax: 0x00000000_00828c00 rcx: 0x00000000_c0000101
rdx: 0x00000000_ffffff80 rbx: 0xffffff80_00833480
rsp: 0xffffff80_0010bfb0 rbp: 0xffffff80_0010bfb0
rsi: 0xffffff80_0010bf48 rdi: 0xffffff80_00828c00
r8 : 0xffffff80_007dbe03 r9 : 0x00000000_0000007f
r10: 0x00000021_00000000 r11: 0xffffff80_00cf9000
r12: 0x80000000_00c74003 r13: 0x00000000_00000084
r14: 0x00000000_00a33000 r15: 0xffffff80_00c75000
rip: 0xffffff80_0030d346
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
我相信这个断点应该在你的_cpu_data_realloc
函数中。查看寄存器,我们可以看到MSR 0xc0000101
将使用0xffffff8000828c00
的值编写,这将正确设置GS
base。事实上,在一次触发事故发生后,bochs很友好地证实了这一点:
10725675946i[CPU0 ] | MSR_GS_BASE:ffffff8000828c00
我在后续使用GS
时放置了另一个断点,不确定源代码中的位置:
(0) [0x00000000003232b2] 0008:ffffff80003232b2 (unk. ctxt): mov r14d, dword ptr gs:0x000000000000001c ; 65448b34251c000000
好的,所以它显示为gs:0x1c
。测试表明这是零。为了证明确实从正确的内存位置读取了值,让我们将它设置为有趣的东西:
<bochs:21> page 0xffffff8000828c1c
PML4: 0x0000000000c72023 ps A pcd pwt S W P
PDPE: 0x0000000000c6e023 ps A pcd pwt S W P
PDE: 0x0000000000a7e023 ps A pcd pwt S W P
PTE: 0x0000000000828063 g pat D A pcd pwt S W P
linear page 0xffffff8000828000 maps to physical page 0x0000000000828000
<bochs:22> setpmem 0x828c1c 4 0x42424242
然后加载执行没有问题,并且确实加载了该值:
<bochs:23> s
Next at t=91228625505
(0) [0x00000000003232bb] 0008:ffffff80003232bb (unk. ctxt): lea rdi, qword ptr ds:[rip+5863966] ; 488d3d1e7a5900
<bochs:24> r
rax: 0x00000000_00000000 rcx: 0xffffff80_0087ae80
rdx: 0xffffff80_008bad10 rbx: 0xffffff80_0075b564
rsp: 0xffffff80_0010bde0 rbp: 0xffffff80_0010be10
rsi: 0x00000000_00000072 rdi: 0xffffff80_0075b564
r8 : 0x00000000_00000010 r9 : 0x00000000_00000000
r10: 0x00000000_00000000 r11: 0x00000000_00000000
r12: 0xffffff80_0010bec4 r13: 0x00000000_00000084
r14: 0x00000000_42424242 r15: 0xffffff80_008f2b38
rip: 0xffffff80_003232bb
eflags 0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
无论你遇到什么问题,都可能在其他地方。
答案 1 :(得分:0)