1*6cbac32fSguenther /* $OpenBSD: codepatch.h,v 1.19 2024/02/12 01:18:17 guenther Exp $ */ 261d6df42Ssf /* 361d6df42Ssf * Copyright (c) 2014-2015 Stefan Fritsch <sf@sfritsch.de> 461d6df42Ssf * 561d6df42Ssf * Permission to use, copy, modify, and distribute this software for any 661d6df42Ssf * purpose with or without fee is hereby granted, provided that the above 761d6df42Ssf * copyright notice and this permission notice appear in all copies. 861d6df42Ssf * 961d6df42Ssf * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1061d6df42Ssf * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1161d6df42Ssf * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1261d6df42Ssf * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1361d6df42Ssf * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1461d6df42Ssf * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1561d6df42Ssf * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1661d6df42Ssf */ 1761d6df42Ssf 1861d6df42Ssf #ifndef _MACHINE_CODEPATCH_H_ 1961d6df42Ssf #define _MACHINE_CODEPATCH_H_ 2061d6df42Ssf 2161d6df42Ssf #include <machine/param.h> 2261d6df42Ssf 2361d6df42Ssf #ifndef _LOCORE 2461d6df42Ssf 255f6ecb19Ssf /* code in this section will be unmapped after boot */ 265f6ecb19Ssf #define __cptext __attribute__((section(".cptext"))) 275f6ecb19Ssf 285f6ecb19Ssf __cptext void *codepatch_maprw(vaddr_t *nva, vaddr_t dest); 295f6ecb19Ssf __cptext void codepatch_unmaprw(vaddr_t nva); 305f6ecb19Ssf __cptext void codepatch_fill_nop(void *caddr, uint16_t len); 315f6ecb19Ssf __cptext void codepatch_nop(uint16_t tag); 32183b7dd1Sguenther __cptext void codepatch_replace(uint16_t tag, const void *code, size_t len); 33b8d87cb1Sguenther __cptext void codepatch_call(uint16_t _tag, void *_func); 34b8d87cb1Sguenther __cptext void codepatch_jmp(uint16_t _tag, void *_func); 355f6ecb19Ssf void codepatch_disable(void); 3661d6df42Ssf 3761d6df42Ssf #endif /* !_LOCORE */ 3861d6df42Ssf 3961d6df42Ssf /* 4061d6df42Ssf * Mark the start of some code snippet to be patched. 4161d6df42Ssf */ 4261d6df42Ssf #define CODEPATCH_START 998: 4361d6df42Ssf /* 4461d6df42Ssf * Mark the end of some code to be patched, and assign the given tag. 4561d6df42Ssf */ 46f95e373fSguenther #define CODEPATCH_END2(startnum,tag) \ 4761d6df42Ssf 999: \ 4861d6df42Ssf .section .codepatch, "a" ;\ 49f95e373fSguenther .quad startnum##b ;\ 50f95e373fSguenther .short (999b - startnum##b) ;\ 5161d6df42Ssf .short tag ;\ 522daa5239Ssf .int 0 ;\ 5361d6df42Ssf .previous 54f95e373fSguenther #define CODEPATCH_END(tag) CODEPATCH_END2(998,tag) 5561d6df42Ssf 5661d6df42Ssf #define CPTAG_STAC 1 5761d6df42Ssf #define CPTAG_CLAC 2 58984d4744Ssf #define CPTAG_EOI 3 59c9de630fSguenther #define CPTAG_XRSTOR 4 60c9de630fSguenther #define CPTAG_XSAVE 5 611fc8fad1Sguenther #define CPTAG_MELTDOWN_NOP 6 625c3fa5a3Sguenther #define CPTAG_MELTDOWN_ALLTRAPS 7 635c3fa5a3Sguenther #define CPTAG_PCID_SET_REUSE 8 645c3fa5a3Sguenther #define CPTAG_MDS 9 655c3fa5a3Sguenther #define CPTAG_MDS_VMM 10 665c3fa5a3Sguenther #define CPTAG_FENCE_SWAPGS_MIS_TAKEN 11 675c3fa5a3Sguenther #define CPTAG_FENCE_NO_SAFE_SMAP 12 6855fdb5faSguenther #define CPTAG_XRSTORS 13 691538f8cbSguenther #define CPTAG_RETPOLINE_RAX 14 701538f8cbSguenther #define CPTAG_RETPOLINE_R11 15 711538f8cbSguenther #define CPTAG_RETPOLINE_R13 16 72*6cbac32fSguenther #define CPTAG_IBPB_NOP 17 7361d6df42Ssf 74019cf0fbSguenther /* 7567ca69ecSguenther * stac/clac SMAP instructions have lfence like semantics. Let's 7667ca69ecSguenther * guarantee those semantics on older cpus. 77019cf0fbSguenther */ 7867ca69ecSguenther #define SMAP_NOP lfence 79019cf0fbSguenther #define SMAP_STAC CODEPATCH_START ;\ 80019cf0fbSguenther SMAP_NOP ;\ 81019cf0fbSguenther CODEPATCH_END(CPTAG_STAC) 82019cf0fbSguenther #define SMAP_CLAC CODEPATCH_START ;\ 83019cf0fbSguenther SMAP_NOP ;\ 84019cf0fbSguenther CODEPATCH_END(CPTAG_CLAC) 85019cf0fbSguenther 865c3fa5a3Sguenther /* CVE-2019-1125: block speculation after swapgs */ 875c3fa5a3Sguenther #define FENCE_SWAPGS_MIS_TAKEN \ 885c3fa5a3Sguenther CODEPATCH_START ; \ 895c3fa5a3Sguenther lfence ; \ 905c3fa5a3Sguenther CODEPATCH_END(CPTAG_FENCE_SWAPGS_MIS_TAKEN) 915c3fa5a3Sguenther /* block speculation when a correct SMAP impl would have been enough */ 925c3fa5a3Sguenther #define FENCE_NO_SAFE_SMAP \ 935c3fa5a3Sguenther CODEPATCH_START ; \ 945c3fa5a3Sguenther lfence ; \ 955c3fa5a3Sguenther CODEPATCH_END(CPTAG_FENCE_NO_SAFE_SMAP) 965c3fa5a3Sguenther 97f95e373fSguenther #define PCID_SET_REUSE_SIZE 12 98f95e373fSguenther #define PCID_SET_REUSE_NOP \ 99f95e373fSguenther 997: ;\ 100f95e373fSguenther .byte 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 ;\ 101f95e373fSguenther .byte 0x0f, 0x1f, 0x40, 0x00 ;\ 102f95e373fSguenther CODEPATCH_END2(997, CPTAG_PCID_SET_REUSE) 103f95e373fSguenther 10440ce500bSguenther /* Would be neat if these could be in something like .cptext */ 10540ce500bSguenther #define CODEPATCH_CODE(symbol, instructions...) \ 10640ce500bSguenther .section .rodata; \ 10740ce500bSguenther .globl symbol; \ 10840ce500bSguenther symbol: instructions; \ 10940ce500bSguenther .size symbol, . - symbol 11040ce500bSguenther 11140ce500bSguenther /* provide a (short) variable with the length of the patch */ 11240ce500bSguenther #define CODEPATCH_CODE_LEN(symbol, instructions...) \ 11340ce500bSguenther CODEPATCH_CODE(symbol, instructions); \ 11440ce500bSguenther 996: .globl symbol##_len; \ 11540ce500bSguenther .align 2; \ 11640ce500bSguenther symbol##_len: \ 11740ce500bSguenther .short 996b - symbol; \ 11840ce500bSguenther .size symbol##_len, 2 11940ce500bSguenther 12061d6df42Ssf #endif /* _MACHINE_CODEPATCH_H_ */ 121