xref: /linux/tools/testing/selftests/x86/thunks.S (revision e58e871becec2d3b04ed91c0c16fe8deac9c9dfa)
1/*
2 * thunks.S - assembly helpers for mixed-bitness code
3 * Copyright (c) 2015 Andrew Lutomirski
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * General Public License for more details.
13 *
14 * These are little helpers that make it easier to switch bitness on
15 * the fly.
16 */
17
18	.text
19
20	.global call32_from_64
21	.type call32_from_64, @function
22call32_from_64:
23	// rdi: stack to use
24	// esi: function to call
25
26	// Save registers
27	pushq %rbx
28	pushq %rbp
29	pushq %r12
30	pushq %r13
31	pushq %r14
32	pushq %r15
33	pushfq
34
35	// Switch stacks
36	mov %rsp,(%rdi)
37	mov %rdi,%rsp
38
39	// Switch to compatibility mode
40	pushq $0x23  /* USER32_CS */
41	pushq $1f
42	lretq
43
441:
45	.code32
46	// Call the function
47	call *%esi
48	// Switch back to long mode
49	jmp $0x33,$1f
50	.code64
51
521:
53	// Restore the stack
54	mov (%rsp),%rsp
55
56	// Restore registers
57	popfq
58	popq %r15
59	popq %r14
60	popq %r13
61	popq %r12
62	popq %rbp
63	popq %rbx
64
65	ret
66
67.size call32_from_64, .-call32_from_64
68