1 回答

TA貢獻1951條經驗 獲得超3個贊
usergs指的是x86-64 swapgs指令,該指令gs
與內部保存的GS值交換給內核,以從syscall入口點查找內核堆棧。交換也交換緩存的gsbase段信息,而不是根據gs
值本身從GDT重新加載。(wrgsbase
可以獨立于GDT / LDT更改GS基礎)
AMD的設計是syscall
不更改RSP以指向內核堆棧,并且不讀取/寫入任何內存,因此syscall
它本身可以很快。但是隨后您進入內核,其中所有寄存器都保存著它們的用戶空間值。請參閱為什么Windows64使用與x86-64上所有其他操作系統不同的調用約定?在2000年左右內核開發人員和AMD架構師之間討論郵件列表討論的一些鏈接,在出售任何AMD64 CPU之前調整其設計syscall
并swapgs
使其可用。
顯然,要跟蹤GS當前是內核還是用戶值對于錯誤處理是很棘手的:沒有辦法說“我現在要kernelgs”。您必須知道是否swapgs
在任何錯誤處理路徑中運行。唯一的指令是交換,而不是將其設置為一個與另一個。
閱讀arch/x86/entry/entry_64.S
例如https://github.com/torvalds/linux/blob/9fb71c2f230df44bdd237e9a4457849a3909017d/arch/x86/entry/entry_64.S#L1267(來自當前Linux)中的注釋,其中提到了usergs,下一個注釋塊描述了swapgs
在執行之前使用內核gsbase跳轉到一些錯誤處理代碼。
IIRC,Linux內核[gs:0]
在該線程的內核堆棧的最低地址處擁有一個線程信息塊。該塊包括內核堆棧指針(作為絕對地址,而不是相對于gs
)。
如果此錯誤基本上是在誘使內核rsp
從用戶控制的gsbase加載內核,或者搞砸了死胡同,swapgs
從而使它gs
在某些時候出現錯誤,我不會感到驚訝。
- 1 回答
- 0 關注
- 361 瀏覽
添加回答
舉報