Messages in this thread | | | Date | Thu, 25 Apr 2019 14:30:45 +0200 | From | Peter Zijlstra <> | Subject | Re: x86/paravirt: Detect over-sized patching bugs in paravirt_patch_call() |
| |
On Thu, Apr 25, 2019 at 01:40:04PM +0200, Peter Zijlstra wrote: > So this then fails to patch the immediate; but the compiler emitted: > > 175: ff 25 00 00 00 00 jmpq *0x0(%rip) # 17b <syscall_return_via_sysret+0x75> > 177: R_X86_64_PC32 pv_ops+0xfc > > and pv_ops+0xfc is (+4 because of reloc magic): > > void (*usergs_sysret64)(void); /* 0x100 0x8 */ > > which defaults to: > > arch/x86/kernel/paravirt.c: .cpu.usergs_sysret64 = native_usergs_sysret64, > > which in turn reads like: > > 0000000000000000 <native_usergs_sysret64>: > 0: 0f 01 f8 swapgs > 3: 48 0f 07 sysretq > > So I _really_ don't understand how: > > > Which with the vanilla kernel crashes on boot much, much later: > > > > [ 2.478026] PANIC: double fault, error_code: 0x0 > > happens.
Just spoke to Juergen on IRC; the most likely explanation is that (because of PTI) the pv_ops table isn't mapped in the user page-tables and therefore the indirect jump comes unstuck.
| |