xref: /openbsd/sys/arch/amd64/include/codepatch.h (revision 6cbac32f)
1 /*      $OpenBSD: codepatch.h,v 1.19 2024/02/12 01:18:17 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 #define CPTAG_IBPB_NOP			17
73 
74 /*
75  * stac/clac SMAP instructions have lfence like semantics.  Let's
76  * guarantee those semantics on older cpus.
77  */
78 #define SMAP_NOP	lfence
79 #define SMAP_STAC	CODEPATCH_START			;\
80 			SMAP_NOP			;\
81 			CODEPATCH_END(CPTAG_STAC)
82 #define SMAP_CLAC	CODEPATCH_START			;\
83 			SMAP_NOP			;\
84 			CODEPATCH_END(CPTAG_CLAC)
85 
86 /* CVE-2019-1125: block speculation after swapgs */
87 #define	FENCE_SWAPGS_MIS_TAKEN \
88 	CODEPATCH_START				; \
89 	lfence					; \
90 	CODEPATCH_END(CPTAG_FENCE_SWAPGS_MIS_TAKEN)
91 /* block speculation when a correct SMAP impl would have been enough */
92 #define	FENCE_NO_SAFE_SMAP \
93 	CODEPATCH_START				; \
94 	lfence					; \
95 	CODEPATCH_END(CPTAG_FENCE_NO_SAFE_SMAP)
96 
97 #define	PCID_SET_REUSE_SIZE	12
98 #define	PCID_SET_REUSE_NOP					\
99 	997:							;\
100 	.byte	0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00	;\
101 	.byte	0x0f, 0x1f, 0x40, 0x00				;\
102 	CODEPATCH_END2(997, CPTAG_PCID_SET_REUSE)
103 
104 /* Would be neat if these could be in something like .cptext */
105 #define CODEPATCH_CODE(symbol, instructions...)		\
106 	.section .rodata;				\
107 	.globl	symbol;					\
108 symbol:	instructions;					\
109 	.size	symbol, . - symbol
110 
111 /* provide a (short) variable with the length of the patch */
112 #define CODEPATCH_CODE_LEN(symbol, instructions...)	\
113 	CODEPATCH_CODE(symbol, instructions);		\
114 996:	.globl	symbol##_len;				\
115 	.align	2;					\
116 symbol##_len:						\
117 	.short	996b - symbol;				\
118 	.size	symbol##_len, 2
119 
120 #endif /* _MACHINE_CODEPATCH_H_ */
121