Skip to content

Commit c9a5e40

Browse files
committed
XTF: Use fastcall by default for 32bit
This passes up to 3 parameters in registers, rather than on the stack. Most transformations are easy. The exec_user() infrastructure took two parameters on the stack and used an ad-hoc %eax/%ecx arrangement with %edx as a scratch register. Fastcall uses %eax/%edx, so switch the scratch regsiter to %ecx instead. memop-seg was already using %eax, and needs a bit of care now that addr isn't on the stack. However, it does remove the need for stack_adj which simplifies the result. Signed-off-by: Andrew Cooper <[email protected]>
1 parent 2499e95 commit c9a5e40

File tree

6 files changed

+25
-45
lines changed

6 files changed

+25
-45
lines changed

arch/x86/entry_32.S

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,8 @@ handle_exception:
8484
mov %eax, %ds
8585
mov %eax, %es
8686

87-
push %esp /* struct cpu_regs * */
87+
mov %esp, %eax /* struct cpu_regs * */
8888
call do_exception
89-
add $4, %esp
9089

9190
RESTORE_ALL
9291

@@ -104,17 +103,10 @@ ENTRY(entry_ret_to_kernel) /* int $X86_VEC_RET2KERN */
104103
ret
105104
ENDFUNC(entry_ret_to_kernel)
106105

107-
ENTRY(exec_user_param)
108-
/*
109-
* 2*4(%esp) ulong p1
110-
* 1*4(%esp) ulong (*fn)(ulong)
111-
* 0*4(%esp) return address
112-
*/
106+
ENTRY(exec_user_param) /* %eax = ulong (*fn)(ulong p1), %edx = ulong p1 */
113107
push %ebp
114108

115109
/* Prepare to "call" exec_user_stub(). */
116-
mov (1+1)*4(%esp), %eax /* Pass fn() in %eax */
117-
mov (1+2)*4(%esp), %ecx /* Pass p1 in %ecx */
118110
push $1f /* Fake return addr as if we'd called exec_user_stub(). */
119111
mov %esp, %ebp /* Stash %esp for entry_ret_to_kernel(). */
120112

@@ -125,10 +117,10 @@ ENTRY(exec_user_param)
125117
pushf /* EFLAGS */
126118

127119
/* Apply and/or masks to eflags. */
128-
mov exec_user_efl_and_mask, %edx
129-
and %edx, (%esp)
130-
mov exec_user_efl_or_mask, %edx
131-
or %edx, (%esp)
120+
mov exec_user_efl_and_mask, %ecx
121+
and %ecx, (%esp)
122+
mov exec_user_efl_or_mask, %ecx
123+
or %ecx, (%esp)
132124

133125
push exec_user_cs /* CS */
134126
push $exec_user_stub /* EIP */
@@ -142,13 +134,9 @@ ENTRY(exec_user_param)
142134
ENDFUNC(exec_user_param)
143135

144136
.pushsection .text.user, "ax", @progbits
145-
ENTRY(exec_user_stub)
146-
/*
147-
* For SMEP/SMAP safety, no shared stack can be used, so all
148-
* parameters are passed in registers.
149-
*/
150-
push %ecx /* Push p1 for fn()'s call frame. */
151-
call *%eax /* fn(p1) */
137+
ENTRY(exec_user_stub) /* %eax = ulong (*fn)(ulong p1), %edx = ulong p1 */
138+
xchg %eax, %edx /* Swap p1 to be first parameter to fn(). */
139+
call *%edx /* fn(p1) */
152140

153141
int $X86_VEC_RET2KERN /* Return to kernel privilege. */
154142
ENDFUNC(exec_user_stub)
@@ -167,9 +155,8 @@ ENTRY(entry_EVTCHN)
167155
mov %eax, %ds
168156
mov %eax, %es
169157

170-
push %esp /* struct cpu_regs * */
158+
mov %esp, %eax /* struct cpu_regs * */
171159
call do_evtchn
172-
add $4, %esp
173160

174161
RESTORE_ALL
175162

@@ -195,9 +182,8 @@ ENTRY(entry_SYSCALL)
195182
mov %eax, %ds
196183
mov %eax, %es
197184

198-
push %esp /* struct cpu_regs * */
185+
mov %esp, %eax /* struct cpu_regs * */
199186
call do_syscall
200-
add $4, %esp
201187

202188
RESTORE_ALL
203189

@@ -222,9 +208,8 @@ ENTRY(entry_SYSENTER)
222208
mov %eax, %ds
223209
mov %eax, %es
224210

225-
push %esp /* struct cpu_regs * */
211+
mov %esp, %eax /* struct cpu_regs * */
226212
call do_sysenter
227-
add $4, %esp
228213

229214
RESTORE_ALL
230215

arch/x86/hvm/head.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ GLOBAL(_elf_start) /* HVM common setup. */
7373
#ifdef __x86_64__
7474
lea .Lmain_err_msg(%rip), %rdi
7575
#else
76-
push $.Lmain_err_msg
76+
mov $.Lmain_err_msg, %eax
7777
#endif
7878
call panic
7979
ENDFUNC(_elf_start)

arch/x86/pv/head.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ GLOBAL(_elf_start)
3535
#ifdef __x86_64__
3636
lea .Lmain_err_msg(%rip), %rdi
3737
#else
38-
push $.Lmain_err_msg
38+
mov $.Lmain_err_msg, %eax
3939
#endif
4040
call panic
4141
ENDFUNC(_elf_start)

build/common.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ COMMON_CFLAGS += -Wno-unused-parameter -Winline
4343
COMMON_AFLAGS-x86_32 := -m32
4444
COMMON_AFLAGS-x86_64 := -m64
4545

46-
COMMON_CFLAGS-x86_32 := -m32
46+
COMMON_CFLAGS-x86_32 := -m32 -mregparm=3
4747
COMMON_CFLAGS-x86_64 := -m64
4848

4949
defcfg-pv := $(ROOT)/config/default-pv.cfg.in

tests/memop-seg/asm.S

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ ENTRY(stub_\seg\()_abs) /* exinfo_t stub_\seg_abs(unsigned long addr) */
1212
* Switch segment if necessary. The old segment is preserved on the
1313
* stack for the duration of the test.
1414
*/
15-
.local stack_adj
16-
stack_adj = 0
17-
1815
.if \load_seg
1916
.ifeqs "\seg", "none"
2017
push %ds
@@ -25,19 +22,22 @@ ENTRY(stub_\seg\()_abs) /* exinfo_t stub_\seg_abs(unsigned long addr) */
2522
push $(GDTE_AVAIL1 << 3 | 3)
2623
pop %\seg
2724
.endif
28-
stack_adj = 1
2925
.endif
3026
#endif
3127

32-
/* No exception if we don't fault. Also reused by the 64bit case. */
33-
xor %eax, %eax
34-
3528
/* The bottom bit of 'addr' encodes FEP. */
3629
#ifdef __i386__
37-
testb $1, (1 + stack_adj)*4(%esp)
30+
testb $1, %al
3831
#else
3932
testb $1, %dil
4033
#endif
34+
35+
/*
36+
* No exception if we don't fault.
37+
* Reused by the 64bit case, and careful to not clobber flags.
38+
*/
39+
mov $0, %eax
40+
4141
jz 1f
4242

4343
_ASM_XEN_FEP
@@ -82,9 +82,6 @@ ENTRY(stub_\seg\()_\reg) /* exinfo_t stub_\seg_\reg(unsigned long addr) */
8282
* Switch segment if necessary. The old segment is preserved on the
8383
* stack for the duration of the test.
8484
*/
85-
.local stack_adj
86-
stack_adj = 0
87-
8885
.if \load_seg
8986
.ifeqs "\seg", "none"
9087
push %ds
@@ -95,7 +92,6 @@ ENTRY(stub_\seg\()_\reg) /* exinfo_t stub_\seg_\reg(unsigned long addr) */
9592
push $(GDTE_AVAIL1 << 3 | 3)
9693
pop %\seg
9794
.endif
98-
stack_adj = 1
9995
.endif
10096
#endif
10197

@@ -106,7 +102,7 @@ ENTRY(stub_\seg\()_\reg) /* exinfo_t stub_\seg_\reg(unsigned long addr) */
106102

107103
/* Move 'addr' into \reg */
108104
#ifdef __i386__
109-
mov (1 + stack_adj)*4(%esp), %\reg
105+
mov %eax, %\reg
110106
#else
111107
mov %rdi, %\reg
112108
#endif

tests/nmi-taskswitch-priv/main.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ asm("exit_NMI_task:"
5454
"push %ebx;"
5555
"push %ebp;"
5656

57-
"push %esp;"
57+
"mov %esp, %eax;"
5858
"call do_exception;"
59-
"add $1*4, %esp;"
6059

6160
"pop %ebp;"
6261
"pop %ebx;"

0 commit comments

Comments
 (0)