1/*
2 * AMD Secure Encrypted Virtualization (SEV) driver interface
3 *
4 * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
5 *
6 * Author: Brijesh Singh <brijesh.singh@amd.com>
7 *
8 * SEV spec 0.14 is available at:
9 * http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef __PSP_SEV_H__
17#define __PSP_SEV_H__
18
19#include <uapi/linux/psp-sev.h>
20
21#ifdef CONFIG_X86
22#include <linux/mem_encrypt.h>
23
24#define __psp_pa(x) __sme_pa(x)
25#else
26#define __psp_pa(x) __pa(x)
27#endif
28
29#define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */
30
31/**
32 * SEV platform state
33 */
34enum sev_state {
35 SEV_STATE_UNINIT = 0x0,
36 SEV_STATE_INIT = 0x1,
37 SEV_STATE_WORKING = 0x2,
38
39 SEV_STATE_MAX
40};
41
42/**
43 * SEV platform and guest management commands
44 */
45enum sev_cmd {
46 /* platform commands */
47 SEV_CMD_INIT = 0x001,
48 SEV_CMD_SHUTDOWN = 0x002,
49 SEV_CMD_FACTORY_RESET = 0x003,
50 SEV_CMD_PLATFORM_STATUS = 0x004,
51 SEV_CMD_PEK_GEN = 0x005,
52 SEV_CMD_PEK_CSR = 0x006,
53 SEV_CMD_PEK_CERT_IMPORT = 0x007,
54 SEV_CMD_PDH_CERT_EXPORT = 0x008,
55 SEV_CMD_PDH_GEN = 0x009,
56 SEV_CMD_DF_FLUSH = 0x00A,
57 SEV_CMD_DOWNLOAD_FIRMWARE = 0x00B,
58 SEV_CMD_GET_ID = 0x00C,
59
60 /* Guest commands */
61 SEV_CMD_DECOMMISSION = 0x020,
62 SEV_CMD_ACTIVATE = 0x021,
63 SEV_CMD_DEACTIVATE = 0x022,
64 SEV_CMD_GUEST_STATUS = 0x023,
65
66 /* Guest launch commands */
67 SEV_CMD_LAUNCH_START = 0x030,
68 SEV_CMD_LAUNCH_UPDATE_DATA = 0x031,
69 SEV_CMD_LAUNCH_UPDATE_VMSA = 0x032,
70 SEV_CMD_LAUNCH_MEASURE = 0x033,
71 SEV_CMD_LAUNCH_UPDATE_SECRET = 0x034,
72 SEV_CMD_LAUNCH_FINISH = 0x035,
73
74 /* Guest migration commands (outgoing) */
75 SEV_CMD_SEND_START = 0x040,
76 SEV_CMD_SEND_UPDATE_DATA = 0x041,
77 SEV_CMD_SEND_UPDATE_VMSA = 0x042,
78 SEV_CMD_SEND_FINISH = 0x043,
79
80 /* Guest migration commands (incoming) */
81 SEV_CMD_RECEIVE_START = 0x050,
82 SEV_CMD_RECEIVE_UPDATE_DATA = 0x051,
83 SEV_CMD_RECEIVE_UPDATE_VMSA = 0x052,
84 SEV_CMD_RECEIVE_FINISH = 0x053,
85
86 /* Guest debug commands */
87 SEV_CMD_DBG_DECRYPT = 0x060,
88 SEV_CMD_DBG_ENCRYPT = 0x061,
89
90 SEV_CMD_MAX,
91};
92
93/**
94 * struct sev_data_init - INIT command parameters
95 *
96 * @flags: processing flags
97 * @tmr_address: system physical address used for SEV-ES
98 * @tmr_len: len of tmr_address
99 */
100struct sev_data_init {
101 u32 flags; /* In */
102 u32 reserved; /* In */
103 u64 tmr_address; /* In */
104 u32 tmr_len; /* In */
105} __packed;
106
107/**
108 * struct sev_data_pek_csr - PEK_CSR command parameters
109 *
110 * @address: PEK certificate chain
111 * @len: len of certificate
112 */
113struct sev_data_pek_csr {
114 u64 address; /* In */
115 u32 len; /* In/Out */
116} __packed;
117
118/**
119 * struct sev_data_cert_import - PEK_CERT_IMPORT command parameters
120 *
121 * @pek_address: PEK certificate chain
122 * @pek_len: len of PEK certificate
123 * @oca_address: OCA certificate chain
124 * @oca_len: len of OCA certificate
125 */
126struct sev_data_pek_cert_import {
127 u64 pek_cert_address; /* In */
128 u32 pek_cert_len; /* In */
129 u32 reserved; /* In */
130 u64 oca_cert_address; /* In */
131 u32 oca_cert_len; /* In */
132} __packed;
133
134/**
135 * struct sev_data_download_firmware - DOWNLOAD_FIRMWARE command parameters
136 *
137 * @address: physical address of firmware image
138 * @len: len of the firmware image
139 */
140struct sev_data_download_firmware {
141 u64 address; /* In */
142 u32 len; /* In */
143} __packed;
144
145/**
146 * struct sev_data_get_id - GET_ID command parameters
147 *
148 * @address: physical address of region to place unique CPU ID(s)
149 * @len: len of the region
150 */
151struct sev_data_get_id {
152 u64 address; /* In */
153 u32 len; /* In/Out */
154} __packed;
155/**
156 * struct sev_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
157 *
158 * @pdh_address: PDH certificate address
159 * @pdh_len: len of PDH certificate
160 * @cert_chain_address: PDH certificate chain
161 * @cert_chain_len: len of PDH certificate chain
162 */
163struct sev_data_pdh_cert_export {
164 u64 pdh_cert_address; /* In */
165 u32 pdh_cert_len; /* In/Out */
166 u32 reserved; /* In */
167 u64 cert_chain_address; /* In */
168 u32 cert_chain_len; /* In/Out */
169} __packed;
170
171/**
172 * struct sev_data_decommission - DECOMMISSION command parameters
173 *
174 * @handle: handle of the VM to decommission
175 */
176struct sev_data_decommission {
177 u32 handle; /* In */
178} __packed;
179
180/**
181 * struct sev_data_activate - ACTIVATE command parameters
182 *
183 * @handle: handle of the VM to activate
184 * @asid: asid assigned to the VM
185 */
186struct sev_data_activate {
187 u32 handle; /* In */
188 u32 asid; /* In */
189} __packed;
190
191/**
192 * struct sev_data_deactivate - DEACTIVATE command parameters
193 *
194 * @handle: handle of the VM to deactivate
195 */
196struct sev_data_deactivate {
197 u32 handle; /* In */
198} __packed;
199
200/**
201 * struct sev_data_guest_status - SEV GUEST_STATUS command parameters
202 *
203 * @handle: handle of the VM to retrieve status
204 * @policy: policy information for the VM
205 * @asid: current ASID of the VM
206 * @state: current state of the VM
207 */
208struct sev_data_guest_status {
209 u32 handle; /* In */
210 u32 policy; /* Out */
211 u32 asid; /* Out */
212 u8 state; /* Out */
213} __packed;
214
215/**
216 * struct sev_data_launch_start - LAUNCH_START command parameters
217 *
218 * @handle: handle assigned to the VM
219 * @policy: guest launch policy
220 * @dh_cert_address: physical address of DH certificate blob
221 * @dh_cert_len: len of DH certificate blob
222 * @session_address: physical address of session parameters
223 * @session_len: len of session parameters
224 */
225struct sev_data_launch_start {
226 u32 handle; /* In/Out */
227 u32 policy; /* In */
228 u64 dh_cert_address; /* In */
229 u32 dh_cert_len; /* In */
230 u32 reserved; /* In */
231 u64 session_address; /* In */
232 u32 session_len; /* In */
233} __packed;
234
235/**
236 * struct sev_data_launch_update_data - LAUNCH_UPDATE_DATA command parameter
237 *
238 * @handle: handle of the VM to update
239 * @len: len of memory to be encrypted
240 * @address: physical address of memory region to encrypt
241 */
242struct sev_data_launch_update_data {
243 u32 handle; /* In */
244 u32 reserved;
245 u64 address; /* In */
246 u32 len; /* In */
247} __packed;
248
249/**
250 * struct sev_data_launch_update_vmsa - LAUNCH_UPDATE_VMSA command
251 *
252 * @handle: handle of the VM
253 * @address: physical address of memory region to encrypt
254 * @len: len of memory region to encrypt
255 */
256struct sev_data_launch_update_vmsa {
257 u32 handle; /* In */
258 u32 reserved;
259 u64 address; /* In */
260 u32 len; /* In */
261} __packed;
262
263/**
264 * struct sev_data_launch_measure - LAUNCH_MEASURE command parameters
265 *
266 * @handle: handle of the VM to process
267 * @address: physical address containing the measurement blob
268 * @len: len of measurement blob
269 */
270struct sev_data_launch_measure {
271 u32 handle; /* In */
272 u32 reserved;
273 u64 address; /* In */
274 u32 len; /* In/Out */
275} __packed;
276
277/**
278 * struct sev_data_launch_secret - LAUNCH_SECRET command parameters
279 *
280 * @handle: handle of the VM to process
281 * @hdr_address: physical address containing the packet header
282 * @hdr_len: len of packet header
283 * @guest_address: system physical address of guest memory region
284 * @guest_len: len of guest_paddr
285 * @trans_address: physical address of transport memory buffer
286 * @trans_len: len of transport memory buffer
287 */
288struct sev_data_launch_secret {
289 u32 handle; /* In */
290 u32 reserved1;
291 u64 hdr_address; /* In */
292 u32 hdr_len; /* In */
293 u32 reserved2;
294 u64 guest_address; /* In */
295 u32 guest_len; /* In */
296 u32 reserved3;
297 u64 trans_address; /* In */
298 u32 trans_len; /* In */
299} __packed;
300
301/**
302 * struct sev_data_launch_finish - LAUNCH_FINISH command parameters
303 *
304 * @handle: handle of the VM to process
305 */
306struct sev_data_launch_finish {
307 u32 handle; /* In */
308} __packed;
309
310/**
311 * struct sev_data_send_start - SEND_START command parameters
312 *
313 * @handle: handle of the VM to process
314 * @policy: policy information for the VM
315 * @pdh_cert_address: physical address containing PDH certificate
316 * @pdh_cert_len: len of PDH certificate
317 * @plat_certs_address: physical address containing platform certificate
318 * @plat_certs_len: len of platform certificate
319 * @amd_certs_address: physical address containing AMD certificate
320 * @amd_certs_len: len of AMD certificate
321 * @session_address: physical address containing Session data
322 * @session_len: len of session data
323 */
324struct sev_data_send_start {
325 u32 handle; /* In */
326 u32 policy; /* Out */
327 u64 pdh_cert_address; /* In */
328 u32 pdh_cert_len; /* In */
329 u32 reserved1;
330 u64 plat_cert_address; /* In */
331 u32 plat_cert_len; /* In */
332 u32 reserved2;
333 u64 amd_cert_address; /* In */
334 u32 amd_cert_len; /* In */
335 u32 reserved3;
336 u64 session_address; /* In */
337 u32 session_len; /* In/Out */
338} __packed;
339
340/**
341 * struct sev_data_send_update - SEND_UPDATE_DATA command
342 *
343 * @handle: handle of the VM to process
344 * @hdr_address: physical address containing packet header
345 * @hdr_len: len of packet header
346 * @guest_address: physical address of guest memory region to send
347 * @guest_len: len of guest memory region to send
348 * @trans_address: physical address of host memory region
349 * @trans_len: len of host memory region
350 */
351struct sev_data_send_update_data {
352 u32 handle; /* In */
353 u32 reserved1;
354 u64 hdr_address; /* In */
355 u32 hdr_len; /* In/Out */
356 u32 reserved2;
357 u64 guest_address; /* In */
358 u32 guest_len; /* In */
359 u32 reserved3;
360 u64 trans_address; /* In */
361 u32 trans_len; /* In */
362} __packed;
363
364/**
365 * struct sev_data_send_update - SEND_UPDATE_VMSA command
366 *
367 * @handle: handle of the VM to process
368 * @hdr_address: physical address containing packet header
369 * @hdr_len: len of packet header
370 * @guest_address: physical address of guest memory region to send
371 * @guest_len: len of guest memory region to send
372 * @trans_address: physical address of host memory region
373 * @trans_len: len of host memory region
374 */
375struct sev_data_send_update_vmsa {
376 u32 handle; /* In */
377 u64 hdr_address; /* In */
378 u32 hdr_len; /* In/Out */
379 u32 reserved2;
380 u64 guest_address; /* In */
381 u32 guest_len; /* In */
382 u32 reserved3;
383 u64 trans_address; /* In */
384 u32 trans_len; /* In */
385} __packed;
386
387/**
388 * struct sev_data_send_finish - SEND_FINISH command parameters
389 *
390 * @handle: handle of the VM to process
391 */
392struct sev_data_send_finish {
393 u32 handle; /* In */
394} __packed;
395
396/**
397 * struct sev_data_receive_start - RECEIVE_START command parameters
398 *
399 * @handle: handle of the VM to perform receive operation
400 * @pdh_cert_address: system physical address containing PDH certificate blob
401 * @pdh_cert_len: len of PDH certificate blob
402 * @session_address: system physical address containing session blob
403 * @session_len: len of session blob
404 */
405struct sev_data_receive_start {
406 u32 handle; /* In/Out */
407 u32 policy; /* In */
408 u64 pdh_cert_address; /* In */
409 u32 pdh_cert_len; /* In */
410 u32 reserved1;
411 u64 session_address; /* In */
412 u32 session_len; /* In */
413} __packed;
414
415/**
416 * struct sev_data_receive_update_data - RECEIVE_UPDATE_DATA command parameters
417 *
418 * @handle: handle of the VM to update
419 * @hdr_address: physical address containing packet header blob
420 * @hdr_len: len of packet header
421 * @guest_address: system physical address of guest memory region
422 * @guest_len: len of guest memory region
423 * @trans_address: system physical address of transport buffer
424 * @trans_len: len of transport buffer
425 */
426struct sev_data_receive_update_data {
427 u32 handle; /* In */
428 u32 reserved1;
429 u64 hdr_address; /* In */
430 u32 hdr_len; /* In */
431 u32 reserved2;
432 u64 guest_address; /* In */
433 u32 guest_len; /* In */
434 u32 reserved3;
435 u64 trans_address; /* In */
436 u32 trans_len; /* In */
437} __packed;
438
439/**
440 * struct sev_data_receive_update_vmsa - RECEIVE_UPDATE_VMSA command parameters
441 *
442 * @handle: handle of the VM to update
443 * @hdr_address: physical address containing packet header blob
444 * @hdr_len: len of packet header
445 * @guest_address: system physical address of guest memory region
446 * @guest_len: len of guest memory region
447 * @trans_address: system physical address of transport buffer
448 * @trans_len: len of transport buffer
449 */
450struct sev_data_receive_update_vmsa {
451 u32 handle; /* In */
452 u32 reserved1;
453 u64 hdr_address; /* In */
454 u32 hdr_len; /* In */
455 u32 reserved2;
456 u64 guest_address; /* In */
457 u32 guest_len; /* In */
458 u32 reserved3;
459 u64 trans_address; /* In */
460 u32 trans_len; /* In */
461} __packed;
462
463/**
464 * struct sev_data_receive_finish - RECEIVE_FINISH command parameters
465 *
466 * @handle: handle of the VM to finish
467 */
468struct sev_data_receive_finish {
469 u32 handle; /* In */
470} __packed;
471
472/**
473 * struct sev_data_dbg - DBG_ENCRYPT/DBG_DECRYPT command parameters
474 *
475 * @handle: handle of the VM to perform debug operation
476 * @src_addr: source address of data to operate on
477 * @dst_addr: destination address of data to operate on
478 * @len: len of data to operate on
479 */
480struct sev_data_dbg {
481 u32 handle; /* In */
482 u32 reserved;
483 u64 src_addr; /* In */
484 u64 dst_addr; /* In */
485 u32 len; /* In */
486} __packed;
487
488#ifdef CONFIG_CRYPTO_DEV_SP_PSP
489
490/**
491 * sev_platform_init - perform SEV INIT command
492 *
493 * @error: SEV command return code
494 *
495 * Returns:
496 * 0 if the SEV successfully processed the command
497 * -%ENODEV if the SEV device is not available
498 * -%ENOTSUPP if the SEV does not support SEV
499 * -%ETIMEDOUT if the SEV command timed out
500 * -%EIO if the SEV returned a non-zero return code
501 */
502int sev_platform_init(int *error);
503
504/**
505 * sev_platform_status - perform SEV PLATFORM_STATUS command
506 *
507 * @status: sev_user_data_status structure to be processed
508 * @error: SEV command return code
509 *
510 * Returns:
511 * 0 if the SEV successfully processed the command
512 * -%ENODEV if the SEV device is not available
513 * -%ENOTSUPP if the SEV does not support SEV
514 * -%ETIMEDOUT if the SEV command timed out
515 * -%EIO if the SEV returned a non-zero return code
516 */
517int sev_platform_status(struct sev_user_data_status *status, int *error);
518
519/**
520 * sev_issue_cmd_external_user - issue SEV command by other driver with a file
521 * handle.
522 *
523 * This function can be used by other drivers to issue a SEV command on
524 * behalf of userspace. The caller must pass a valid SEV file descriptor
525 * so that we know that it has access to SEV device.
526 *
527 * @filep - SEV device file pointer
528 * @cmd - command to issue
529 * @data - command buffer
530 * @error: SEV command return code
531 *
532 * Returns:
533 * 0 if the SEV successfully processed the command
534 * -%ENODEV if the SEV device is not available
535 * -%ENOTSUPP if the SEV does not support SEV
536 * -%ETIMEDOUT if the SEV command timed out
537 * -%EIO if the SEV returned a non-zero return code
538 * -%EINVAL if the SEV file descriptor is not valid
539 */
540int sev_issue_cmd_external_user(struct file *filep, unsigned int id,
541 void *data, int *error);
542
543/**
544 * sev_guest_deactivate - perform SEV DEACTIVATE command
545 *
546 * @deactivate: sev_data_deactivate structure to be processed
547 * @sev_ret: sev command return code
548 *
549 * Returns:
550 * 0 if the sev successfully processed the command
551 * -%ENODEV if the sev device is not available
552 * -%ENOTSUPP if the sev does not support SEV
553 * -%ETIMEDOUT if the sev command timed out
554 * -%EIO if the sev returned a non-zero return code
555 */
556int sev_guest_deactivate(struct sev_data_deactivate *data, int *error);
557
558/**
559 * sev_guest_activate - perform SEV ACTIVATE command
560 *
561 * @activate: sev_data_activate structure to be processed
562 * @sev_ret: sev command return code
563 *
564 * Returns:
565 * 0 if the sev successfully processed the command
566 * -%ENODEV if the sev device is not available
567 * -%ENOTSUPP if the sev does not support SEV
568 * -%ETIMEDOUT if the sev command timed out
569 * -%EIO if the sev returned a non-zero return code
570 */
571int sev_guest_activate(struct sev_data_activate *data, int *error);
572
573/**
574 * sev_guest_df_flush - perform SEV DF_FLUSH command
575 *
576 * @sev_ret: sev command return code
577 *
578 * Returns:
579 * 0 if the sev successfully processed the command
580 * -%ENODEV if the sev device is not available
581 * -%ENOTSUPP if the sev does not support SEV
582 * -%ETIMEDOUT if the sev command timed out
583 * -%EIO if the sev returned a non-zero return code
584 */
585int sev_guest_df_flush(int *error);
586
587/**
588 * sev_guest_decommission - perform SEV DECOMMISSION command
589 *
590 * @decommission: sev_data_decommission structure to be processed
591 * @sev_ret: sev command return code
592 *
593 * Returns:
594 * 0 if the sev successfully processed the command
595 * -%ENODEV if the sev device is not available
596 * -%ENOTSUPP if the sev does not support SEV
597 * -%ETIMEDOUT if the sev command timed out
598 * -%EIO if the sev returned a non-zero return code
599 */
600int sev_guest_decommission(struct sev_data_decommission *data, int *error);
601
602void *psp_copy_user_blob(u64 __user uaddr, u32 len);
603
604#else /* !CONFIG_CRYPTO_DEV_SP_PSP */
605
606static inline int
607sev_platform_status(struct sev_user_data_status *status, int *error) { return -ENODEV; }
608
609static inline int sev_platform_init(int *error) { return -ENODEV; }
610
611static inline int
612sev_guest_deactivate(struct sev_data_deactivate *data, int *error) { return -ENODEV; }
613
614static inline int
615sev_guest_decommission(struct sev_data_decommission *data, int *error) { return -ENODEV; }
616
617static inline int
618sev_guest_activate(struct sev_data_activate *data, int *error) { return -ENODEV; }
619
620static inline int sev_guest_df_flush(int *error) { return -ENODEV; }
621
622static inline int
623sev_issue_cmd_external_user(struct file *filep, unsigned int id, void *data, int *error) { return -ENODEV; }
624
625static inline void *psp_copy_user_blob(u64 __user uaddr, u32 len) { return ERR_PTR(-EINVAL); }
626
627#endif /* CONFIG_CRYPTO_DEV_SP_PSP */
628
629#endif /* __PSP_SEV_H__ */
630