xref: /openbmc/linux/arch/x86/kernel/sev-shared.c (revision be58f710)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * AMD Encrypted Register State Support
4  *
5  * Author: Joerg Roedel <jroedel@suse.de>
6  *
7  * This file is not compiled stand-alone. It contains code shared
8  * between the pre-decompression boot code and the running Linux kernel
9  * and is included directly into both code-bases.
10  */
11 
12 #ifndef __BOOT_COMPRESSED
13 #define error(v)	pr_err(v)
14 #define has_cpuflag(f)	boot_cpu_has(f)
15 #endif
16 
17 static bool __init sev_es_check_cpu_features(void)
18 {
19 	if (!has_cpuflag(X86_FEATURE_RDRAND)) {
20 		error("RDRAND instruction not supported - no trusted source of randomness available\n");
21 		return false;
22 	}
23 
24 	return true;
25 }
26 
27 static void __noreturn sev_es_terminate(unsigned int reason)
28 {
29 	u64 val = GHCB_MSR_TERM_REQ;
30 
31 	/*
32 	 * Tell the hypervisor what went wrong - only reason-set 0 is
33 	 * currently supported.
34 	 */
35 	val |= GHCB_SEV_TERM_REASON(0, reason);
36 
37 	/* Request Guest Termination from Hypvervisor */
38 	sev_es_wr_ghcb_msr(val);
39 	VMGEXIT();
40 
41 	while (true)
42 		asm volatile("hlt\n" : : : "memory");
43 }
44 
45 static bool sev_es_negotiate_protocol(void)
46 {
47 	u64 val;
48 
49 	/* Do the GHCB protocol version negotiation */
50 	sev_es_wr_ghcb_msr(GHCB_MSR_SEV_INFO_REQ);
51 	VMGEXIT();
52 	val = sev_es_rd_ghcb_msr();
53 
54 	if (GHCB_MSR_INFO(val) != GHCB_MSR_SEV_INFO_RESP)
55 		return false;
56 
57 	if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTO_OUR ||
58 	    GHCB_MSR_PROTO_MIN(val) > GHCB_PROTO_OUR)
59 		return false;
60 
61 	return true;
62 }
63 
64 static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb)
65 {
66 	ghcb->save.sw_exit_code = 0;
67 	memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
68 }
69 
70 static bool vc_decoding_needed(unsigned long exit_code)
71 {
72 	/* Exceptions don't require to decode the instruction */
73 	return !(exit_code >= SVM_EXIT_EXCP_BASE &&
74 		 exit_code <= SVM_EXIT_LAST_EXCP);
75 }
76 
77 static enum es_result vc_init_em_ctxt(struct es_em_ctxt *ctxt,
78 				      struct pt_regs *regs,
79 				      unsigned long exit_code)
80 {
81 	enum es_result ret = ES_OK;
82 
83 	memset(ctxt, 0, sizeof(*ctxt));
84 	ctxt->regs = regs;
85 
86 	if (vc_decoding_needed(exit_code))
87 		ret = vc_decode_insn(ctxt);
88 
89 	return ret;
90 }
91 
92 static void vc_finish_insn(struct es_em_ctxt *ctxt)
93 {
94 	ctxt->regs->ip += ctxt->insn.length;
95 }
96 
97 static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
98 					  struct es_em_ctxt *ctxt,
99 					  u64 exit_code, u64 exit_info_1,
100 					  u64 exit_info_2)
101 {
102 	enum es_result ret;
103 
104 	/* Fill in protocol and format specifiers */
105 	ghcb->protocol_version = GHCB_PROTOCOL_MAX;
106 	ghcb->ghcb_usage       = GHCB_DEFAULT_USAGE;
107 
108 	ghcb_set_sw_exit_code(ghcb, exit_code);
109 	ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
110 	ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
111 
112 	sev_es_wr_ghcb_msr(__pa(ghcb));
113 	VMGEXIT();
114 
115 	if ((ghcb->save.sw_exit_info_1 & 0xffffffff) == 1) {
116 		u64 info = ghcb->save.sw_exit_info_2;
117 		unsigned long v;
118 
119 		info = ghcb->save.sw_exit_info_2;
120 		v = info & SVM_EVTINJ_VEC_MASK;
121 
122 		/* Check if exception information from hypervisor is sane. */
123 		if ((info & SVM_EVTINJ_VALID) &&
124 		    ((v == X86_TRAP_GP) || (v == X86_TRAP_UD)) &&
125 		    ((info & SVM_EVTINJ_TYPE_MASK) == SVM_EVTINJ_TYPE_EXEPT)) {
126 			ctxt->fi.vector = v;
127 			if (info & SVM_EVTINJ_VALID_ERR)
128 				ctxt->fi.error_code = info >> 32;
129 			ret = ES_EXCEPTION;
130 		} else {
131 			ret = ES_VMM_ERROR;
132 		}
133 	} else {
134 		ret = ES_OK;
135 	}
136 
137 	return ret;
138 }
139 
140 /*
141  * Boot VC Handler - This is the first VC handler during boot, there is no GHCB
142  * page yet, so it only supports the MSR based communication with the
143  * hypervisor and only the CPUID exit-code.
144  */
145 void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
146 {
147 	unsigned int fn = lower_bits(regs->ax, 32);
148 	unsigned long val;
149 
150 	/* Only CPUID is supported via MSR protocol */
151 	if (exit_code != SVM_EXIT_CPUID)
152 		goto fail;
153 
154 	sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EAX));
155 	VMGEXIT();
156 	val = sev_es_rd_ghcb_msr();
157 	if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
158 		goto fail;
159 	regs->ax = val >> 32;
160 
161 	sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EBX));
162 	VMGEXIT();
163 	val = sev_es_rd_ghcb_msr();
164 	if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
165 		goto fail;
166 	regs->bx = val >> 32;
167 
168 	sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_ECX));
169 	VMGEXIT();
170 	val = sev_es_rd_ghcb_msr();
171 	if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
172 		goto fail;
173 	regs->cx = val >> 32;
174 
175 	sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EDX));
176 	VMGEXIT();
177 	val = sev_es_rd_ghcb_msr();
178 	if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP)
179 		goto fail;
180 	regs->dx = val >> 32;
181 
182 	/*
183 	 * This is a VC handler and the #VC is only raised when SEV-ES is
184 	 * active, which means SEV must be active too. Do sanity checks on the
185 	 * CPUID results to make sure the hypervisor does not trick the kernel
186 	 * into the no-sev path. This could map sensitive data unencrypted and
187 	 * make it accessible to the hypervisor.
188 	 *
189 	 * In particular, check for:
190 	 *	- Availability of CPUID leaf 0x8000001f
191 	 *	- SEV CPUID bit.
192 	 *
193 	 * The hypervisor might still report the wrong C-bit position, but this
194 	 * can't be checked here.
195 	 */
196 
197 	if (fn == 0x80000000 && (regs->ax < 0x8000001f))
198 		/* SEV leaf check */
199 		goto fail;
200 	else if ((fn == 0x8000001f && !(regs->ax & BIT(1))))
201 		/* SEV bit */
202 		goto fail;
203 
204 	/* Skip over the CPUID two-byte opcode */
205 	regs->ip += 2;
206 
207 	return;
208 
209 fail:
210 	/* Terminate the guest */
211 	sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST);
212 }
213 
214 static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
215 					  void *src, char *buf,
216 					  unsigned int data_size,
217 					  unsigned int count,
218 					  bool backwards)
219 {
220 	int i, b = backwards ? -1 : 1;
221 	enum es_result ret = ES_OK;
222 
223 	for (i = 0; i < count; i++) {
224 		void *s = src + (i * data_size * b);
225 		char *d = buf + (i * data_size);
226 
227 		ret = vc_read_mem(ctxt, s, d, data_size);
228 		if (ret != ES_OK)
229 			break;
230 	}
231 
232 	return ret;
233 }
234 
235 static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt,
236 					   void *dst, char *buf,
237 					   unsigned int data_size,
238 					   unsigned int count,
239 					   bool backwards)
240 {
241 	int i, s = backwards ? -1 : 1;
242 	enum es_result ret = ES_OK;
243 
244 	for (i = 0; i < count; i++) {
245 		void *d = dst + (i * data_size * s);
246 		char *b = buf + (i * data_size);
247 
248 		ret = vc_write_mem(ctxt, d, b, data_size);
249 		if (ret != ES_OK)
250 			break;
251 	}
252 
253 	return ret;
254 }
255 
256 #define IOIO_TYPE_STR  BIT(2)
257 #define IOIO_TYPE_IN   1
258 #define IOIO_TYPE_INS  (IOIO_TYPE_IN | IOIO_TYPE_STR)
259 #define IOIO_TYPE_OUT  0
260 #define IOIO_TYPE_OUTS (IOIO_TYPE_OUT | IOIO_TYPE_STR)
261 
262 #define IOIO_REP       BIT(3)
263 
264 #define IOIO_ADDR_64   BIT(9)
265 #define IOIO_ADDR_32   BIT(8)
266 #define IOIO_ADDR_16   BIT(7)
267 
268 #define IOIO_DATA_32   BIT(6)
269 #define IOIO_DATA_16   BIT(5)
270 #define IOIO_DATA_8    BIT(4)
271 
272 #define IOIO_SEG_ES    (0 << 10)
273 #define IOIO_SEG_DS    (3 << 10)
274 
275 static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
276 {
277 	struct insn *insn = &ctxt->insn;
278 	*exitinfo = 0;
279 
280 	switch (insn->opcode.bytes[0]) {
281 	/* INS opcodes */
282 	case 0x6c:
283 	case 0x6d:
284 		*exitinfo |= IOIO_TYPE_INS;
285 		*exitinfo |= IOIO_SEG_ES;
286 		*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
287 		break;
288 
289 	/* OUTS opcodes */
290 	case 0x6e:
291 	case 0x6f:
292 		*exitinfo |= IOIO_TYPE_OUTS;
293 		*exitinfo |= IOIO_SEG_DS;
294 		*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
295 		break;
296 
297 	/* IN immediate opcodes */
298 	case 0xe4:
299 	case 0xe5:
300 		*exitinfo |= IOIO_TYPE_IN;
301 		*exitinfo |= (u8)insn->immediate.value << 16;
302 		break;
303 
304 	/* OUT immediate opcodes */
305 	case 0xe6:
306 	case 0xe7:
307 		*exitinfo |= IOIO_TYPE_OUT;
308 		*exitinfo |= (u8)insn->immediate.value << 16;
309 		break;
310 
311 	/* IN register opcodes */
312 	case 0xec:
313 	case 0xed:
314 		*exitinfo |= IOIO_TYPE_IN;
315 		*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
316 		break;
317 
318 	/* OUT register opcodes */
319 	case 0xee:
320 	case 0xef:
321 		*exitinfo |= IOIO_TYPE_OUT;
322 		*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
323 		break;
324 
325 	default:
326 		return ES_DECODE_FAILED;
327 	}
328 
329 	switch (insn->opcode.bytes[0]) {
330 	case 0x6c:
331 	case 0x6e:
332 	case 0xe4:
333 	case 0xe6:
334 	case 0xec:
335 	case 0xee:
336 		/* Single byte opcodes */
337 		*exitinfo |= IOIO_DATA_8;
338 		break;
339 	default:
340 		/* Length determined by instruction parsing */
341 		*exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16
342 						     : IOIO_DATA_32;
343 	}
344 	switch (insn->addr_bytes) {
345 	case 2:
346 		*exitinfo |= IOIO_ADDR_16;
347 		break;
348 	case 4:
349 		*exitinfo |= IOIO_ADDR_32;
350 		break;
351 	case 8:
352 		*exitinfo |= IOIO_ADDR_64;
353 		break;
354 	}
355 
356 	if (insn_has_rep_prefix(insn))
357 		*exitinfo |= IOIO_REP;
358 
359 	return ES_OK;
360 }
361 
362 static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
363 {
364 	struct pt_regs *regs = ctxt->regs;
365 	u64 exit_info_1, exit_info_2;
366 	enum es_result ret;
367 
368 	ret = vc_ioio_exitinfo(ctxt, &exit_info_1);
369 	if (ret != ES_OK)
370 		return ret;
371 
372 	if (exit_info_1 & IOIO_TYPE_STR) {
373 
374 		/* (REP) INS/OUTS */
375 
376 		bool df = ((regs->flags & X86_EFLAGS_DF) == X86_EFLAGS_DF);
377 		unsigned int io_bytes, exit_bytes;
378 		unsigned int ghcb_count, op_count;
379 		unsigned long es_base;
380 		u64 sw_scratch;
381 
382 		/*
383 		 * For the string variants with rep prefix the amount of in/out
384 		 * operations per #VC exception is limited so that the kernel
385 		 * has a chance to take interrupts and re-schedule while the
386 		 * instruction is emulated.
387 		 */
388 		io_bytes   = (exit_info_1 >> 4) & 0x7;
389 		ghcb_count = sizeof(ghcb->shared_buffer) / io_bytes;
390 
391 		op_count    = (exit_info_1 & IOIO_REP) ? regs->cx : 1;
392 		exit_info_2 = min(op_count, ghcb_count);
393 		exit_bytes  = exit_info_2 * io_bytes;
394 
395 		es_base = insn_get_seg_base(ctxt->regs, INAT_SEG_REG_ES);
396 
397 		/* Read bytes of OUTS into the shared buffer */
398 		if (!(exit_info_1 & IOIO_TYPE_IN)) {
399 			ret = vc_insn_string_read(ctxt,
400 					       (void *)(es_base + regs->si),
401 					       ghcb->shared_buffer, io_bytes,
402 					       exit_info_2, df);
403 			if (ret)
404 				return ret;
405 		}
406 
407 		/*
408 		 * Issue an VMGEXIT to the HV to consume the bytes from the
409 		 * shared buffer or to have it write them into the shared buffer
410 		 * depending on the instruction: OUTS or INS.
411 		 */
412 		sw_scratch = __pa(ghcb) + offsetof(struct ghcb, shared_buffer);
413 		ghcb_set_sw_scratch(ghcb, sw_scratch);
414 		ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_IOIO,
415 					  exit_info_1, exit_info_2);
416 		if (ret != ES_OK)
417 			return ret;
418 
419 		/* Read bytes from shared buffer into the guest's destination. */
420 		if (exit_info_1 & IOIO_TYPE_IN) {
421 			ret = vc_insn_string_write(ctxt,
422 						   (void *)(es_base + regs->di),
423 						   ghcb->shared_buffer, io_bytes,
424 						   exit_info_2, df);
425 			if (ret)
426 				return ret;
427 
428 			if (df)
429 				regs->di -= exit_bytes;
430 			else
431 				regs->di += exit_bytes;
432 		} else {
433 			if (df)
434 				regs->si -= exit_bytes;
435 			else
436 				regs->si += exit_bytes;
437 		}
438 
439 		if (exit_info_1 & IOIO_REP)
440 			regs->cx -= exit_info_2;
441 
442 		ret = regs->cx ? ES_RETRY : ES_OK;
443 
444 	} else {
445 
446 		/* IN/OUT into/from rAX */
447 
448 		int bits = (exit_info_1 & 0x70) >> 1;
449 		u64 rax = 0;
450 
451 		if (!(exit_info_1 & IOIO_TYPE_IN))
452 			rax = lower_bits(regs->ax, bits);
453 
454 		ghcb_set_rax(ghcb, rax);
455 
456 		ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_IOIO, exit_info_1, 0);
457 		if (ret != ES_OK)
458 			return ret;
459 
460 		if (exit_info_1 & IOIO_TYPE_IN) {
461 			if (!ghcb_rax_is_valid(ghcb))
462 				return ES_VMM_ERROR;
463 			regs->ax = lower_bits(ghcb->save.rax, bits);
464 		}
465 	}
466 
467 	return ret;
468 }
469 
470 static enum es_result vc_handle_cpuid(struct ghcb *ghcb,
471 				      struct es_em_ctxt *ctxt)
472 {
473 	struct pt_regs *regs = ctxt->regs;
474 	u32 cr4 = native_read_cr4();
475 	enum es_result ret;
476 
477 	ghcb_set_rax(ghcb, regs->ax);
478 	ghcb_set_rcx(ghcb, regs->cx);
479 
480 	if (cr4 & X86_CR4_OSXSAVE)
481 		/* Safe to read xcr0 */
482 		ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK));
483 	else
484 		/* xgetbv will cause #GP - use reset value for xcr0 */
485 		ghcb_set_xcr0(ghcb, 1);
486 
487 	ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0);
488 	if (ret != ES_OK)
489 		return ret;
490 
491 	if (!(ghcb_rax_is_valid(ghcb) &&
492 	      ghcb_rbx_is_valid(ghcb) &&
493 	      ghcb_rcx_is_valid(ghcb) &&
494 	      ghcb_rdx_is_valid(ghcb)))
495 		return ES_VMM_ERROR;
496 
497 	regs->ax = ghcb->save.rax;
498 	regs->bx = ghcb->save.rbx;
499 	regs->cx = ghcb->save.rcx;
500 	regs->dx = ghcb->save.rdx;
501 
502 	return ES_OK;
503 }
504 
505 static enum es_result vc_handle_rdtsc(struct ghcb *ghcb,
506 				      struct es_em_ctxt *ctxt,
507 				      unsigned long exit_code)
508 {
509 	bool rdtscp = (exit_code == SVM_EXIT_RDTSCP);
510 	enum es_result ret;
511 
512 	ret = sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, 0, 0);
513 	if (ret != ES_OK)
514 		return ret;
515 
516 	if (!(ghcb_rax_is_valid(ghcb) && ghcb_rdx_is_valid(ghcb) &&
517 	     (!rdtscp || ghcb_rcx_is_valid(ghcb))))
518 		return ES_VMM_ERROR;
519 
520 	ctxt->regs->ax = ghcb->save.rax;
521 	ctxt->regs->dx = ghcb->save.rdx;
522 	if (rdtscp)
523 		ctxt->regs->cx = ghcb->save.rcx;
524 
525 	return ES_OK;
526 }
527