xref: /openbsd-src/sys/arch/amd64/include/codepatch.h (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*      $OpenBSD: codepatch.h,v 1.14 2020/03/11 07:27:08 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, 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 
69 /*
70  * stac/clac SMAP instructions have lfence like semantics.  Let's
71  * guarantee those semantics on older cpus.
72  */
73 #define SMAP_NOP	lfence
74 #define SMAP_STAC	CODEPATCH_START			;\
75 			SMAP_NOP			;\
76 			CODEPATCH_END(CPTAG_STAC)
77 #define SMAP_CLAC	CODEPATCH_START			;\
78 			SMAP_NOP			;\
79 			CODEPATCH_END(CPTAG_CLAC)
80 
81 /* CVE-2019-1125: block speculation after swapgs */
82 #define	FENCE_SWAPGS_MIS_TAKEN \
83 	CODEPATCH_START				; \
84 	lfence					; \
85 	CODEPATCH_END(CPTAG_FENCE_SWAPGS_MIS_TAKEN)
86 /* block speculation when a correct SMAP impl would have been enough */
87 #define	FENCE_NO_SAFE_SMAP \
88 	CODEPATCH_START				; \
89 	lfence					; \
90 	CODEPATCH_END(CPTAG_FENCE_NO_SAFE_SMAP)
91 
92 #define	PCID_SET_REUSE_SIZE	12
93 #define	PCID_SET_REUSE_NOP					\
94 	997:							;\
95 	.byte	0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00	;\
96 	.byte	0x0f, 0x1f, 0x40, 0x00				;\
97 	CODEPATCH_END2(997, CPTAG_PCID_SET_REUSE)
98 
99 #endif /* _MACHINE_CODEPATCH_H_ */
100