xref: /openbsd-src/sys/arch/amd64/include/codepatch.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1 /*      $OpenBSD: codepatch.h,v 1.18 2023/07/31 04:01:07 guenther Exp $    */
2 /*
3  * Copyright (c) 2014-2015 Stefan Fritsch <sf@sfritsch.de>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #ifndef _MACHINE_CODEPATCH_H_
19 #define _MACHINE_CODEPATCH_H_
20 
21 #include <machine/param.h>
22 
23 #ifndef _LOCORE
24 
25 /* code in this section will be unmapped after boot */
26 #define __cptext __attribute__((section(".cptext")))
27 
28 __cptext void *codepatch_maprw(vaddr_t *nva, vaddr_t dest);
29 __cptext void codepatch_unmaprw(vaddr_t nva);
30 __cptext void codepatch_fill_nop(void *caddr, uint16_t len);
31 __cptext void codepatch_nop(uint16_t tag);
32 __cptext void codepatch_replace(uint16_t tag, const void *code, size_t len);
33 __cptext void codepatch_call(uint16_t _tag, void *_func);
34 __cptext void codepatch_jmp(uint16_t _tag, void *_func);
35 void codepatch_disable(void);
36 
37 #endif /* !_LOCORE */
38 
39 /*
40  * Mark the start of some code snippet to be patched.
41  */
42 #define	CODEPATCH_START	998:
43 /*
44  * Mark the end of some code to be patched, and assign the given tag.
45  */
46 #define	CODEPATCH_END2(startnum,tag)		 \
47 	999:					 \
48 	.section .codepatch, "a"		;\
49 	.quad startnum##b			;\
50 	.short (999b - startnum##b)		;\
51 	.short tag				;\
52 	.int 0					;\
53 	.previous
54 #define	CODEPATCH_END(tag)	CODEPATCH_END2(998,tag)
55 
56 #define CPTAG_STAC		1
57 #define CPTAG_CLAC		2
58 #define CPTAG_EOI		3
59 #define CPTAG_XRSTOR		4
60 #define CPTAG_XSAVE		5
61 #define CPTAG_MELTDOWN_NOP	6
62 #define CPTAG_MELTDOWN_ALLTRAPS	7
63 #define CPTAG_PCID_SET_REUSE	8
64 #define CPTAG_MDS		9
65 #define CPTAG_MDS_VMM		10
66 #define CPTAG_FENCE_SWAPGS_MIS_TAKEN	11
67 #define CPTAG_FENCE_NO_SAFE_SMAP	12
68 #define CPTAG_XRSTORS			13
69 #define CPTAG_RETPOLINE_RAX		14
70 #define CPTAG_RETPOLINE_R11		15
71 #define CPTAG_RETPOLINE_R13		16
72 
73 /*
74  * stac/clac SMAP instructions have lfence like semantics.  Let's
75  * guarantee those semantics on older cpus.
76  */
77 #define SMAP_NOP	lfence
78 #define SMAP_STAC	CODEPATCH_START			;\
79 			SMAP_NOP			;\
80 			CODEPATCH_END(CPTAG_STAC)
81 #define SMAP_CLAC	CODEPATCH_START			;\
82 			SMAP_NOP			;\
83 			CODEPATCH_END(CPTAG_CLAC)
84 
85 /* CVE-2019-1125: block speculation after swapgs */
86 #define	FENCE_SWAPGS_MIS_TAKEN \
87 	CODEPATCH_START				; \
88 	lfence					; \
89 	CODEPATCH_END(CPTAG_FENCE_SWAPGS_MIS_TAKEN)
90 /* block speculation when a correct SMAP impl would have been enough */
91 #define	FENCE_NO_SAFE_SMAP \
92 	CODEPATCH_START				; \
93 	lfence					; \
94 	CODEPATCH_END(CPTAG_FENCE_NO_SAFE_SMAP)
95 
96 #define	PCID_SET_REUSE_SIZE	12
97 #define	PCID_SET_REUSE_NOP					\
98 	997:							;\
99 	.byte	0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00	;\
100 	.byte	0x0f, 0x1f, 0x40, 0x00				;\
101 	CODEPATCH_END2(997, CPTAG_PCID_SET_REUSE)
102 
103 /* Would be neat if these could be in something like .cptext */
104 #define CODEPATCH_CODE(symbol, instructions...)		\
105 	.section .rodata;				\
106 	.globl	symbol;					\
107 symbol:	instructions;					\
108 	.size	symbol, . - symbol
109 
110 /* provide a (short) variable with the length of the patch */
111 #define CODEPATCH_CODE_LEN(symbol, instructions...)	\
112 	CODEPATCH_CODE(symbol, instructions);		\
113 996:	.globl	symbol##_len;				\
114 	.align	2;					\
115 symbol##_len:						\
116 	.short	996b - symbol;				\
117 	.size	symbol##_len, 2
118 
119 #endif /* _MACHINE_CODEPATCH_H_ */
120