xref: /openbsd-src/sys/arch/amd64/include/codepatch.h (revision 7350f337b9e3eb4461d99580e625c7ef148d107c)
1 /*      $OpenBSD: codepatch.h,v 1.9 2019/05/17 19:07:16 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 void codepatch_disable(void);
35 
36 #endif /* !_LOCORE */
37 
38 /*
39  * Mark the start of some code snippet to be patched.
40  */
41 #define	CODEPATCH_START	998:
42 /*
43  * Mark the end of some code to be patched, and assign the given tag.
44  */
45 #define	CODEPATCH_END2(startnum,tag)		 \
46 	999:					 \
47 	.section .codepatch, "a"		;\
48 	.quad startnum##b			;\
49 	.short (999b - startnum##b)		;\
50 	.short tag				;\
51 	.int 0					;\
52 	.previous
53 #define	CODEPATCH_END(tag)	CODEPATCH_END2(998,tag)
54 
55 #define CPTAG_STAC		1
56 #define CPTAG_CLAC		2
57 #define CPTAG_EOI		3
58 #define CPTAG_XRSTOR		4
59 #define CPTAG_XSAVE		5
60 #define CPTAG_MELTDOWN_NOP	6
61 #define CPTAG_PCID_SET_REUSE	7
62 #define CPTAG_MDS		8
63 #define CPTAG_MDS_VMM		9
64 
65 /*
66  * As stac/clac SMAP instructions are 3 bytes, we want the fastest
67  * 3 byte nop sequence possible here.  This will be replaced by
68  * stac/clac instructions if SMAP is detected after booting.
69  *
70  * This would be 'nop (%rax)' if binutils could cope.
71  * Intel documents multi-byte NOP sequences as being available
72  * on all family 0x6 and 0xf processors (ie 686+)
73  */
74 #define SMAP_NOP	.byte 0x0f, 0x1f, 0x00
75 #define SMAP_STAC	CODEPATCH_START			;\
76 			SMAP_NOP			;\
77 			CODEPATCH_END(CPTAG_STAC)
78 #define SMAP_CLAC	CODEPATCH_START			;\
79 			SMAP_NOP			;\
80 			CODEPATCH_END(CPTAG_CLAC)
81 
82 #define	PCID_SET_REUSE_SIZE	12
83 #define	PCID_SET_REUSE_NOP					\
84 	997:							;\
85 	.byte	0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00	;\
86 	.byte	0x0f, 0x1f, 0x40, 0x00				;\
87 	CODEPATCH_END2(997, CPTAG_PCID_SET_REUSE)
88 
89 #endif /* _MACHINE_CODEPATCH_H_ */
90