| 1 | /*	$OpenBSD: ghcb.h,v 1.7 2026/02/16 15:06:03 hshoexer Exp $	*/ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 2024, 2025 Hans-Joerg Hoexer <hshoexer@genua.de> |
| 5 | * |
| 6 | * Permission to use, copy, modify, and distribute this software for any |
| 7 | * purpose with or without fee is hereby granted, provided that the above |
| 8 | * copyright notice and this permission notice appear in all copies. |
| 9 | * |
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 17 | */ |
| 18 | |
| 19 | #ifndef _MACHINE_GHCB_H_ |
| 20 | #define _MACHINE_GHCB_H_ |
| 21 | |
| 22 | #ifndef _LOCORE |
| 23 | |
| 24 | #include <sys/systm.h> |
| 25 | |
| 26 | #include <machine/frame.h> |
| 27 | |
| 28 | #define GHCB_OFFSET(m)			((m) / 8) |
| 29 | #define GHCB_IDX(m)			(GHCB_OFFSET((m)) / 8) |
| 30 | #define GHCB_BIT(m)			(GHCB_OFFSET((m)) % 8) |
| 31 | |
| 32 | #define GHCB_XSS			0x140 |
| 33 | #define GHCB_RAX			0x1F8 |
| 34 | #define GHCB_RBX			0x318 |
| 35 | #define GHCB_RCX			0x308 |
| 36 | #define GHCB_RDX			0x310 |
| 37 | #define GHCB_SW_EXITCODE		0x390 |
| 38 | #define GHCB_SW_EXITINFO1		0x398 |
| 39 | #define GHCB_SW_EXITINFO2		0x3A0 |
| 40 | #define GHCB_SW_SCRATCH			0x3A8 |
| 41 | #define GHCB_XCR0			0x3E8 |
| 42 | |
| 43 | #define GHCB_MAX			0xFFF |
| 44 | |
| 45 | struct ghcb_sa { |
| 46 | 	uint8_t			v_pad0[0xcb];		/* 000h-0CAh */ |
| 47 | 	uint8_t			v_cpl;			/* 0CBh */ |
| 48 | 	uint8_t			v_pad1[0x74];		/* 0CCh-13Fh */ |
| 49 | 	uint64_t		v_xss;			/* 140h */ |
| 50 | 	uint8_t			v_pad2[0x18];		/* 148h-15Fh */ |
| 51 | 	uint64_t		v_dr7;			/* 160h */ |
| 52 | 	uint8_t			v_pad3[0x10];		/* 168h-177h */ |
| 53 | 	uint64_t		v_rip;			/* 178h */ |
| 54 | 	uint8_t			v_pad4[0x58];		/* 180h-1D7h */ |
| 55 | 	uint64_t		v_rsp;			/* 1D8h */ |
| 56 | 	uint8_t			v_pad5[0x18];		/* 1E0h-1F7h */ |
| 57 | 	uint64_t		v_rax;			/* 1F8h */ |
| 58 | 	uint8_t			v_pad6[0x108];		/* 200h-307h */ |
| 59 | 	uint64_t		v_rcx;			/* 308h */ |
| 60 | 	uint64_t		v_rdx;			/* 310h */ |
| 61 | 	uint64_t		v_rbx;			/* 318h */ |
| 62 | 	uint8_t			v_pad7[0x8];		/* 320h-327h */ |
| 63 | 	uint64_t		v_rbp;			/* 328h */ |
| 64 | 	uint64_t		v_rsi;			/* 330h */ |
| 65 | 	uint64_t		v_rdi;			/* 338h */ |
| 66 | 	uint64_t		v_r8;			/* 340h */ |
| 67 | 	uint64_t		v_r9;			/* 348h */ |
| 68 | 	uint64_t		v_r10;			/* 350h */ |
| 69 | 	uint64_t		v_r11;			/* 358h */ |
| 70 | 	uint64_t		v_r12;			/* 360h */ |
| 71 | 	uint64_t		v_r13;			/* 368h */ |
| 72 | 	uint64_t		v_r14;			/* 370h */ |
| 73 | 	uint64_t		v_r15;			/* 378h */ |
| 74 | 	uint8_t			v_pad8[0x10];		/* 380h-38Fh */ |
| 75 | 	uint64_t		v_sw_exitcode;		/* 390h */ |
| 76 | 	uint64_t		v_sw_exitinfo1;		/* 398h */ |
| 77 | 	uint64_t		v_sw_exitinfo2;		/* 3a0h */ |
| 78 | 	uint64_t		v_sw_scratch;		/* 3a8h */ |
| 79 | 	uint8_t			v_pad9[0x38];		/* 3B0h-3E7h */ |
| 80 | 	uint64_t		v_xcr0;			/* 3E8h */ |
| 81 | #define GHCB_VB_SZ	0x10 |
| 82 | 	uint8_t			valid_bitmap[GHCB_VB_SZ]; |
| 83 | 							/* 3F0h-3FFh */ |
| 84 | 	uint64_t		v_x87_state_gpa;	/* 400h */ |
| 85 | 	uint8_t			v_pad10[0x3f8];		/* 408h-7FFh */ |
| 86 | 	uint8_t			v_sharedbuf[0x7f0];	/* 800h-FEFh */ |
| 87 | 	uint8_t			v_pad11[0xa];		/* FF0h-FF9h */ |
| 88 | 	uint16_t		v_ghcb_proto_version;	/* FFAh-FFBh */ |
| 89 | 	uint32_t		v_ghcb_usage;		/* FFCh-FFFh */ |
| 90 | }; |
| 91 | |
| 92 | #define GHCB_SZ8	0 |
| 93 | #define GHCB_SZ16	1 |
| 94 | #define GHCB_SZ32	2 |
| 95 | #define GHCB_SZ64	3 |
| 96 | |
| 97 | struct ghcb_sync { |
| 98 | 	uint8_t			valid_bitmap[GHCB_VB_SZ]; |
| 99 | |
| 100 | 	int			sz_a; |
| 101 | 	int			sz_b; |
| 102 | 	int			sz_c; |
| 103 | 	int			sz_d; |
| 104 | }; |
| 105 | #endif /* !_LOCORE */ |
| 106 | |
| 107 | /* Definitions used with the MSR protocol */ |
| 108 | #define MSR_PROTO_CPUID_REQ	0x4 |
| 109 | #define MSR_PROTO_CPUID_RESP	0x5 |
| 110 | #define MSR_PROTO_TERMINATE	0x100 |
| 111 | |
| 112 | #ifndef _LOCORE |
| 113 | |
| 114 | extern vaddr_t ghcb_vaddr; |
| 115 | extern paddr_t ghcb_paddr; |
| 116 | |
| 117 | struct ghcb_extra_regs { |
| 118 | 	uint64_t	 exitcode; |
| 119 | 	uint64_t	 exitinfo1; |
| 120 | 	uint64_t	 exitinfo2; |
| 121 | 	uint64_t	 scratch; |
| 122 | 	void		*data; |
| 123 | 	size_t		 data_sz; |
| 124 | }; |
| 125 | |
| 126 | void	ghcb_clear(struct ghcb_sa *); |
| 127 | int	ghcb_valbm_set(uint8_t *, int); |
| 128 | int	ghcb_valbm_isset(uint8_t *, int); |
| 129 | int	ghcb_verify_bm(uint8_t *, uint8_t *); |
| 130 | int	ghcb_valid(struct ghcb_sa *); |
| 131 | int	ghcb_empty(struct ghcb_sa *); |
| 132 | |
| 133 | void	ghcb_sync_val(int, int, struct ghcb_sync *); |
| 134 | void	ghcb_sync_out(struct trapframe *, const struct ghcb_extra_regs *, |
| 135 | 	 struct ghcb_sa *, struct ghcb_sync *); |
| 136 | void	ghcb_sync_in(struct trapframe *, struct ghcb_extra_regs *, |
| 137 | 	 struct ghcb_sa *, struct ghcb_sync *); |
| 138 | void	_ghcb_mem_rw(vaddr_t, int, void *, bool); |
| 139 | void	_ghcb_io_rw(uint16_t, int, uint32_t *, bool); |
| 140 | |
| 141 | static inline uint8_t |
| 142 | ghcb_mem_read_1(vaddr_t addr) |
| 143 | { |
| 144 | 	uint8_t val; |
| 145 | |
| 146 | 	_ghcb_mem_rw(addr, GHCB_SZ8, &val, true); |
| 147 | 	return val; |
| 148 | } |
| 149 | |
| 150 | static inline uint16_t |
| 151 | ghcb_mem_read_2(vaddr_t addr) |
| 152 | { |
| 153 | 	uint16_t val; |
| 154 | |
| 155 | 	_ghcb_mem_rw(addr, GHCB_SZ16, &val, true); |
| 156 | 	return val; |
| 157 | } |
| 158 | |
| 159 | static inline uint32_t |
| 160 | ghcb_mem_read_4(vaddr_t addr) |
| 161 | { |
| 162 | 	uint32_t val; |
| 163 | |
| 164 | 	_ghcb_mem_rw(addr, GHCB_SZ32, &val, true); |
| 165 | 	return val; |
| 166 | } |
| 167 | |
| 168 | static inline uint64_t |
| 169 | ghcb_mem_read_8(vaddr_t addr) |
| 170 | { |
| 171 | 	uint64_t val; |
| 172 | |
| 173 | 	_ghcb_mem_rw(addr, GHCB_SZ64, &val, true); |
| 174 | 	return val; |
| 175 | } |
| 176 | |
| 177 | static inline void |
| 178 | ghcb_mem_write_1(vaddr_t addr, uint8_t v) |
| 179 | { |
| 180 | 	_ghcb_mem_rw(addr, GHCB_SZ8, &v, false); |
| 181 | } |
| 182 | |
| 183 | static inline void |
| 184 | ghcb_mem_write_2(vaddr_t addr, uint16_t v) |
| 185 | { |
| 186 | 	_ghcb_mem_rw(addr, GHCB_SZ16, &v, false); |
| 187 | } |
| 188 | |
| 189 | static inline void |
| 190 | ghcb_mem_write_4(vaddr_t addr, uint32_t v) |
| 191 | { |
| 192 | 	_ghcb_mem_rw(addr, GHCB_SZ32, &v, false); |
| 193 | } |
| 194 | |
| 195 | static inline void |
| 196 | ghcb_mem_write_8(vaddr_t addr, uint64_t v) |
| 197 | { |
| 198 | 	_ghcb_mem_rw(addr, GHCB_SZ64, &v, false); |
| 199 | } |
| 200 | |
| 201 | static inline uint8_t |
| 202 | ghcb_io_read_1(uint16_t port) |
| 203 | { |
| 204 | 	uint32_t val; |
| 205 | |
| 206 | 	_ghcb_io_rw(port, GHCB_SZ8, &val, true); |
| 207 | 	return val; |
| 208 | } |
| 209 | |
| 210 | static inline uint16_t |
| 211 | ghcb_io_read_2(uint16_t port) |
| 212 | { |
| 213 | 	uint32_t val; |
| 214 | |
| 215 | 	_ghcb_io_rw(port, GHCB_SZ16, &val, true); |
| 216 | 	return val; |
| 217 | } |
| 218 | |
| 219 | static inline uint32_t |
| 220 | ghcb_io_read_4(uint16_t port) |
| 221 | { |
| 222 | 	uint32_t val; |
| 223 | |
| 224 | 	_ghcb_io_rw(port, GHCB_SZ32, &val, true); |
| 225 | 	return val; |
| 226 | } |
| 227 | |
| 228 | static inline void |
| 229 | ghcb_io_write_1(uint16_t port, uint8_t v) |
| 230 | { |
| 231 | 	uint32_t val = v; |
| 232 | |
| 233 | 	_ghcb_io_rw(port, GHCB_SZ8, &val, false); |
| 234 | } |
| 235 | |
| 236 | static inline void |
| 237 | ghcb_io_write_2(uint16_t port, uint16_t v) |
| 238 | { |
| 239 | 	uint32_t val = v; |
| 240 | |
| 241 | 	_ghcb_io_rw(port, GHCB_SZ16, &val, false); |
| 242 | } |
| 243 | |
| 244 | static inline void |
| 245 | ghcb_io_write_4(uint16_t port, uint32_t v) |
| 246 | { |
| 247 | 	_ghcb_io_rw(port, GHCB_SZ32, &v, false); |
| 248 | } |
| 249 | |
| 250 | #endif /* !_LOCORE */ |
| 251 | |
| 252 | #endif /* !_MACHINE_GHCB_H_ */ |