1 回答

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