|
@@ -97,7 +97,7 @@ For 32-bit we have the following conventions - kernel is built with
|
|
|
|
|
|
#define SIZEOF_PTREGS 21*8
|
|
#define SIZEOF_PTREGS 21*8
|
|
|
|
|
|
-.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax
|
|
|
|
|
|
+.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0
|
|
/*
|
|
/*
|
|
* Push registers and sanitize registers of values that a
|
|
* Push registers and sanitize registers of values that a
|
|
* speculation attack might otherwise want to exploit. The
|
|
* speculation attack might otherwise want to exploit. The
|
|
@@ -105,8 +105,14 @@ For 32-bit we have the following conventions - kernel is built with
|
|
* could be put to use in a speculative execution gadget.
|
|
* could be put to use in a speculative execution gadget.
|
|
* Interleave XOR with PUSH for better uop scheduling:
|
|
* Interleave XOR with PUSH for better uop scheduling:
|
|
*/
|
|
*/
|
|
|
|
+ .if \save_ret
|
|
|
|
+ pushq %rsi /* pt_regs->si */
|
|
|
|
+ movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */
|
|
|
|
+ movq %rdi, 8(%rsp) /* pt_regs->di (overwriting original return address) */
|
|
|
|
+ .else
|
|
pushq %rdi /* pt_regs->di */
|
|
pushq %rdi /* pt_regs->di */
|
|
pushq %rsi /* pt_regs->si */
|
|
pushq %rsi /* pt_regs->si */
|
|
|
|
+ .endif
|
|
pushq \rdx /* pt_regs->dx */
|
|
pushq \rdx /* pt_regs->dx */
|
|
pushq %rcx /* pt_regs->cx */
|
|
pushq %rcx /* pt_regs->cx */
|
|
pushq \rax /* pt_regs->ax */
|
|
pushq \rax /* pt_regs->ax */
|
|
@@ -131,6 +137,9 @@ For 32-bit we have the following conventions - kernel is built with
|
|
pushq %r15 /* pt_regs->r15 */
|
|
pushq %r15 /* pt_regs->r15 */
|
|
xorq %r15, %r15 /* nospec r15*/
|
|
xorq %r15, %r15 /* nospec r15*/
|
|
UNWIND_HINT_REGS
|
|
UNWIND_HINT_REGS
|
|
|
|
+ .if \save_ret
|
|
|
|
+ pushq %rsi /* return address on top of stack */
|
|
|
|
+ .endif
|
|
.endm
|
|
.endm
|
|
|
|
|
|
.macro POP_REGS pop_rdi=1 skip_r11rcx=0
|
|
.macro POP_REGS pop_rdi=1 skip_r11rcx=0
|