Skip to content

Commit 768a30c

Browse files
Andrew Boienashif
authored andcommitted
x86: organize 64-bit ESF
The callee-saved registers have been separated out and will not be saved/restored if exception debugging is shut off. Signed-off-by: Andrew Boie <[email protected]>
1 parent 7353c7f commit 768a30c

File tree

2 files changed

+53
-38
lines changed

2 files changed

+53
-38
lines changed

arch/x86/core/intel64/locore.S

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ except: /*
347347
* already there from hardware trap and EXCEPT_*() stub.
348348
*/
349349

350-
pushq %r15
350+
pushq %r11
351351

352352
#ifdef CONFIG_USERSPACE
353353
/* Swap GS register values and page tables if we came from user mode */
@@ -356,81 +356,86 @@ except: /*
356356
swapgs
357357
#ifdef CONFIG_X86_KPTI
358358
/* Load kernel's page table */
359-
movq $z_x86_kernel_ptables, %r15
360-
movq %r15, %cr3
359+
movq $z_x86_kernel_ptables, %r11
360+
movq %r11, %cr3
361361
#endif /* CONFIG_X86_KPTI */
362362
1:
363363
#ifdef CONFIG_X86_BOUNDS_CHECK_BYPASS_MITIGATION
364364
/* swapgs variant of Spectre V1. Disable speculation past this point */
365365
lfence
366366
#endif /* CONFIG_X86_BOUNDS_CHECK_BYPASS_MITIGATION */
367367
#ifdef CONFIG_X86_KPTI
368-
/* Save old trampoline stack pointer in R15 */
369-
movq %rsp, %r15
368+
/* Save old trampoline stack pointer in R11 */
369+
movq %rsp, %r11
370370

371371
/* Switch to the exception stack */
372372
movq %gs:__x86_tss64_t_ist7_OFFSET, %rsp
373373

374374
/* Transplant trampoline stack contents */
375-
pushq 56(%r15) /* SS */
376-
pushq 48(%r15) /* RSP */
377-
pushq 40(%r15) /* RFLAGS */
378-
pushq 32(%r15) /* CS */
379-
pushq 24(%r15) /* RIP */
380-
pushq 16(%r15) /* Error code */
381-
pushq 8(%r15) /* Vector */
382-
pushq (%r15) /* Stashed R15 */
383-
movq $0, (%r15) /* Cover our tracks */
375+
pushq 56(%r11) /* SS */
376+
pushq 48(%r11) /* RSP */
377+
pushq 40(%r11) /* RFLAGS */
378+
pushq 32(%r11) /* CS */
379+
pushq 24(%r11) /* RIP */
380+
pushq 16(%r11) /* Error code */
381+
pushq 8(%r11) /* Vector */
382+
pushq (%r11) /* Stashed R15 */
383+
movq $0, (%r11) /* Cover our tracks */
384384

385385
/* We're done, it's safe to re-enable interrupts. */
386386
sti
387387
#endif /* CONFIG_X86_KPTI */
388388
#endif /* CONFIG_USERSPACE */
389389

390+
/* In addition to r11, push the rest of the caller-saved regs */
391+
/* Positioning of this fxsave is important, RSP must be 16-byte
392+
* aligned
393+
*/
390394
subq $X86_FXSAVE_SIZE, %rsp
391395
fxsave (%rsp)
392-
pushq %r14
393-
pushq %r13
394-
pushq %r12
395-
pushq %r11
396396
pushq %r10
397397
pushq %r9
398398
pushq %r8
399399
pushq %rdi
400400
pushq %rsi
401-
pushq %rbp
402401
pushq %rdx
403402
pushq %rcx
404-
pushq %rbx
405403
pushq %rax
406-
404+
#ifdef CONFIG_EXCEPTION_DEBUG
405+
/* Callee saved regs */
406+
pushq %r15
407+
pushq %r14
408+
pushq %r13
409+
pushq %r12
410+
pushq %rbp
411+
pushq %rbx
412+
#endif /* CONFIG_EXCEPTION_DEBUG */
407413
movq %rsp, %rdi
408414

409-
/* TODO we don't need to push so many registers if we are not
410-
* dumping out exception info since RBX, RBP, R12-R15 are callee-saved
411-
*/
412415
call z_x86_exception
413416

414417
/* If we returned, the exception was handled successfully and the
415418
* thread may resume (the pushed RIP may have been modified)
416419
*/
417-
popq %rax
420+
#ifdef CONFIG_EXCEPTION_DEBUG
418421
popq %rbx
422+
popq %rbp
423+
popq %r12
424+
popq %r13
425+
popq %r14
426+
popq %r15
427+
#endif /* CONFIG_EXCEPTION_DEBUG */
428+
popq %rax
419429
popq %rcx
420430
popq %rdx
421-
popq %rbp
422431
popq %rsi
423432
popq %rdi
424433
popq %r8
425434
popq %r9
426435
popq %r10
427-
popq %r11
428-
popq %r12
429-
popq %r13
430-
popq %r14
431436
fxrstor (%rsp)
432437
addq $X86_FXSAVE_SIZE, %rsp
433-
popq %r15
438+
popq %r11
434439

435440
/* Drop the vector/err code pushed by the HW or EXCEPT_*() stub */
436441
add $16, %rsp

include/arch/x86/intel64/arch.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,32 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void)
3232
*/
3333

3434
struct x86_esf {
35-
unsigned long rax;
35+
#ifdef CONFIG_EXCEPTION_DEBUG
36+
/* callee-saved */
3637
unsigned long rbx;
38+
unsigned long rbp;
39+
unsigned long r12;
40+
unsigned long r13;
41+
unsigned long r14;
42+
unsigned long r15;
43+
#endif /* CONFIG_EXCEPTION_DEBUG */
44+
45+
/* Caller-saved regs */
46+
unsigned long rax;
3747
unsigned long rcx;
3848
unsigned long rdx;
39-
unsigned long rbp;
4049
unsigned long rsi;
4150
unsigned long rdi;
4251
unsigned long r8;
4352
unsigned long r9;
4453
unsigned long r10;
45-
unsigned long r11;
46-
unsigned long r12;
47-
unsigned long r13;
48-
unsigned long r14;
54+
/* Must be aligned 16 bytes from the end of this struct due to
55+
* requirements of 'fxsave (%rsp)'
56+
*/
4957
char fxsave[X86_FXSAVE_SIZE];
50-
unsigned long r15;
58+
unsigned long r11;
59+
60+
/* Pushed by CPU or assembly stub */
5161
unsigned long vector;
5262
unsigned long code;
5363
unsigned long rip;

0 commit comments

Comments
 (0)