1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * AMD Secure Encrypted Virtualization (SEV) driver interface
5 * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
7 * Author: Brijesh Singh <brijesh.singh@amd.com>
9 * SEV API spec is available at https://developer.amd.com/sev
15 #include <uapi/linux/psp-sev.h>
18 #include <linux/mem_encrypt.h>
20 #define __psp_pa(x) __sme_pa(x)
22 #define __psp_pa(x) __pa(x)
25 #define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */
31 SEV_STATE_UNINIT = 0x0,
33 SEV_STATE_WORKING = 0x2,
39 * SEV platform and guest management commands
42 /* platform commands */
44 SEV_CMD_SHUTDOWN = 0x002,
45 SEV_CMD_FACTORY_RESET = 0x003,
46 SEV_CMD_PLATFORM_STATUS = 0x004,
47 SEV_CMD_PEK_GEN = 0x005,
48 SEV_CMD_PEK_CSR = 0x006,
49 SEV_CMD_PEK_CERT_IMPORT = 0x007,
50 SEV_CMD_PDH_CERT_EXPORT = 0x008,
51 SEV_CMD_PDH_GEN = 0x009,
52 SEV_CMD_DF_FLUSH = 0x00A,
53 SEV_CMD_DOWNLOAD_FIRMWARE = 0x00B,
54 SEV_CMD_GET_ID = 0x00C,
57 SEV_CMD_DECOMMISSION = 0x020,
58 SEV_CMD_ACTIVATE = 0x021,
59 SEV_CMD_DEACTIVATE = 0x022,
60 SEV_CMD_GUEST_STATUS = 0x023,
62 /* Guest launch commands */
63 SEV_CMD_LAUNCH_START = 0x030,
64 SEV_CMD_LAUNCH_UPDATE_DATA = 0x031,
65 SEV_CMD_LAUNCH_UPDATE_VMSA = 0x032,
66 SEV_CMD_LAUNCH_MEASURE = 0x033,
67 SEV_CMD_LAUNCH_UPDATE_SECRET = 0x034,
68 SEV_CMD_LAUNCH_FINISH = 0x035,
69 SEV_CMD_ATTESTATION_REPORT = 0x036,
71 /* Guest migration commands (outgoing) */
72 SEV_CMD_SEND_START = 0x040,
73 SEV_CMD_SEND_UPDATE_DATA = 0x041,
74 SEV_CMD_SEND_UPDATE_VMSA = 0x042,
75 SEV_CMD_SEND_FINISH = 0x043,
76 SEV_CMD_SEND_CANCEL = 0x044,
78 /* Guest migration commands (incoming) */
79 SEV_CMD_RECEIVE_START = 0x050,
80 SEV_CMD_RECEIVE_UPDATE_DATA = 0x051,
81 SEV_CMD_RECEIVE_UPDATE_VMSA = 0x052,
82 SEV_CMD_RECEIVE_FINISH = 0x053,
84 /* Guest debug commands */
85 SEV_CMD_DBG_DECRYPT = 0x060,
86 SEV_CMD_DBG_ENCRYPT = 0x061,
92 * struct sev_data_init - INIT command parameters
94 * @flags: processing flags
95 * @tmr_address: system physical address used for SEV-ES
96 * @tmr_len: len of tmr_address
98 struct sev_data_init {
100 u32 reserved; /* In */
101 u64 tmr_address; /* In */
102 u32 tmr_len; /* In */
105 #define SEV_INIT_FLAGS_SEV_ES 0x01
108 * struct sev_data_pek_csr - PEK_CSR command parameters
110 * @address: PEK certificate chain
111 * @len: len of certificate
113 struct sev_data_pek_csr {
114 u64 address; /* In */
115 u32 len; /* In/Out */
119 * struct sev_data_cert_import - PEK_CERT_IMPORT command parameters
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
126 struct 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 */
135 * struct sev_data_download_firmware - DOWNLOAD_FIRMWARE command parameters
137 * @address: physical address of firmware image
138 * @len: len of the firmware image
140 struct sev_data_download_firmware {
141 u64 address; /* In */
146 * struct sev_data_get_id - GET_ID command parameters
148 * @address: physical address of region to place unique CPU ID(s)
149 * @len: len of the region
151 struct sev_data_get_id {
152 u64 address; /* In */
153 u32 len; /* In/Out */
156 * struct sev_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
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
163 struct 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 */
172 * struct sev_data_decommission - DECOMMISSION command parameters
174 * @handle: handle of the VM to decommission
176 struct sev_data_decommission {
181 * struct sev_data_activate - ACTIVATE command parameters
183 * @handle: handle of the VM to activate
184 * @asid: asid assigned to the VM
186 struct sev_data_activate {
192 * struct sev_data_deactivate - DEACTIVATE command parameters
194 * @handle: handle of the VM to deactivate
196 struct sev_data_deactivate {
201 * struct sev_data_guest_status - SEV GUEST_STATUS command parameters
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
208 struct sev_data_guest_status {
210 u32 policy; /* Out */
216 * struct sev_data_launch_start - LAUNCH_START command parameters
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
225 struct sev_data_launch_start {
226 u32 handle; /* In/Out */
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 */
236 * struct sev_data_launch_update_data - LAUNCH_UPDATE_DATA command parameter
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
242 struct sev_data_launch_update_data {
245 u64 address; /* In */
250 * struct sev_data_launch_update_vmsa - LAUNCH_UPDATE_VMSA command
252 * @handle: handle of the VM
253 * @address: physical address of memory region to encrypt
254 * @len: len of memory region to encrypt
256 struct sev_data_launch_update_vmsa {
259 u64 address; /* In */
264 * struct sev_data_launch_measure - LAUNCH_MEASURE command parameters
266 * @handle: handle of the VM to process
267 * @address: physical address containing the measurement blob
268 * @len: len of measurement blob
270 struct sev_data_launch_measure {
273 u64 address; /* In */
274 u32 len; /* In/Out */
278 * struct sev_data_launch_secret - LAUNCH_SECRET command parameters
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
288 struct sev_data_launch_secret {
291 u64 hdr_address; /* In */
292 u32 hdr_len; /* In */
294 u64 guest_address; /* In */
295 u32 guest_len; /* In */
297 u64 trans_address; /* In */
298 u32 trans_len; /* In */
302 * struct sev_data_launch_finish - LAUNCH_FINISH command parameters
304 * @handle: handle of the VM to process
306 struct sev_data_launch_finish {
311 * struct sev_data_send_start - SEND_START command parameters
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
324 struct sev_data_send_start {
326 u32 policy; /* Out */
327 u64 pdh_cert_address; /* In */
328 u32 pdh_cert_len; /* In */
330 u64 plat_certs_address; /* In */
331 u32 plat_certs_len; /* In */
333 u64 amd_certs_address; /* In */
334 u32 amd_certs_len; /* In */
336 u64 session_address; /* In */
337 u32 session_len; /* In/Out */
341 * struct sev_data_send_update - SEND_UPDATE_DATA command
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
351 struct sev_data_send_update_data {
354 u64 hdr_address; /* In */
355 u32 hdr_len; /* In/Out */
357 u64 guest_address; /* In */
358 u32 guest_len; /* In */
360 u64 trans_address; /* In */
361 u32 trans_len; /* In */
365 * struct sev_data_send_update - SEND_UPDATE_VMSA command
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
375 struct sev_data_send_update_vmsa {
377 u64 hdr_address; /* In */
378 u32 hdr_len; /* In/Out */
380 u64 guest_address; /* In */
381 u32 guest_len; /* In */
383 u64 trans_address; /* In */
384 u32 trans_len; /* In */
388 * struct sev_data_send_finish - SEND_FINISH command parameters
390 * @handle: handle of the VM to process
392 struct sev_data_send_finish {
397 * struct sev_data_send_cancel - SEND_CANCEL command parameters
399 * @handle: handle of the VM to process
401 struct sev_data_send_cancel {
406 * struct sev_data_receive_start - RECEIVE_START command parameters
408 * @handle: handle of the VM to perform receive operation
409 * @pdh_cert_address: system physical address containing PDH certificate blob
410 * @pdh_cert_len: len of PDH certificate blob
411 * @session_address: system physical address containing session blob
412 * @session_len: len of session blob
414 struct sev_data_receive_start {
415 u32 handle; /* In/Out */
417 u64 pdh_cert_address; /* In */
418 u32 pdh_cert_len; /* In */
420 u64 session_address; /* In */
421 u32 session_len; /* In */
425 * struct sev_data_receive_update_data - RECEIVE_UPDATE_DATA command parameters
427 * @handle: handle of the VM to update
428 * @hdr_address: physical address containing packet header blob
429 * @hdr_len: len of packet header
430 * @guest_address: system physical address of guest memory region
431 * @guest_len: len of guest memory region
432 * @trans_address: system physical address of transport buffer
433 * @trans_len: len of transport buffer
435 struct sev_data_receive_update_data {
438 u64 hdr_address; /* In */
439 u32 hdr_len; /* In */
441 u64 guest_address; /* In */
442 u32 guest_len; /* In */
444 u64 trans_address; /* In */
445 u32 trans_len; /* In */
449 * struct sev_data_receive_update_vmsa - RECEIVE_UPDATE_VMSA command parameters
451 * @handle: handle of the VM to update
452 * @hdr_address: physical address containing packet header blob
453 * @hdr_len: len of packet header
454 * @guest_address: system physical address of guest memory region
455 * @guest_len: len of guest memory region
456 * @trans_address: system physical address of transport buffer
457 * @trans_len: len of transport buffer
459 struct sev_data_receive_update_vmsa {
462 u64 hdr_address; /* In */
463 u32 hdr_len; /* In */
465 u64 guest_address; /* In */
466 u32 guest_len; /* In */
468 u64 trans_address; /* In */
469 u32 trans_len; /* In */
473 * struct sev_data_receive_finish - RECEIVE_FINISH command parameters
475 * @handle: handle of the VM to finish
477 struct sev_data_receive_finish {
482 * struct sev_data_dbg - DBG_ENCRYPT/DBG_DECRYPT command parameters
484 * @handle: handle of the VM to perform debug operation
485 * @src_addr: source address of data to operate on
486 * @dst_addr: destination address of data to operate on
487 * @len: len of data to operate on
489 struct sev_data_dbg {
492 u64 src_addr; /* In */
493 u64 dst_addr; /* In */
498 * struct sev_data_attestation_report - SEV_ATTESTATION_REPORT command parameters
500 * @handle: handle of the VM
501 * @mnonce: a random nonce that will be included in the report.
502 * @address: physical address where the report will be copied.
503 * @len: length of the physical buffer.
505 struct sev_data_attestation_report {
508 u64 address; /* In */
509 u8 mnonce[16]; /* In */
510 u32 len; /* In/Out */
513 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
516 * sev_platform_init - perform SEV INIT command
518 * @error: SEV command return code
521 * 0 if the SEV successfully processed the command
522 * -%ENODEV if the SEV device is not available
523 * -%ENOTSUPP if the SEV does not support SEV
524 * -%ETIMEDOUT if the SEV command timed out
525 * -%EIO if the SEV returned a non-zero return code
527 int sev_platform_init(int *error);
530 * sev_platform_status - perform SEV PLATFORM_STATUS command
532 * @status: sev_user_data_status structure to be processed
533 * @error: SEV command return code
536 * 0 if the SEV successfully processed the command
537 * -%ENODEV if the SEV device is not available
538 * -%ENOTSUPP if the SEV does not support SEV
539 * -%ETIMEDOUT if the SEV command timed out
540 * -%EIO if the SEV returned a non-zero return code
542 int sev_platform_status(struct sev_user_data_status *status, int *error);
545 * sev_issue_cmd_external_user - issue SEV command by other driver with a file
548 * This function can be used by other drivers to issue a SEV command on
549 * behalf of userspace. The caller must pass a valid SEV file descriptor
550 * so that we know that it has access to SEV device.
552 * @filep - SEV device file pointer
553 * @cmd - command to issue
554 * @data - command buffer
555 * @error: SEV command return code
558 * 0 if the SEV successfully processed the command
559 * -%ENODEV if the SEV device is not available
560 * -%ENOTSUPP if the SEV does not support SEV
561 * -%ETIMEDOUT if the SEV command timed out
562 * -%EIO if the SEV returned a non-zero return code
563 * -%EINVAL if the SEV file descriptor is not valid
565 int sev_issue_cmd_external_user(struct file *filep, unsigned int id,
566 void *data, int *error);
569 * sev_guest_deactivate - perform SEV DEACTIVATE command
571 * @deactivate: sev_data_deactivate structure to be processed
572 * @sev_ret: sev command return code
575 * 0 if the sev successfully processed the command
576 * -%ENODEV if the sev device is not available
577 * -%ENOTSUPP if the sev does not support SEV
578 * -%ETIMEDOUT if the sev command timed out
579 * -%EIO if the sev returned a non-zero return code
581 int sev_guest_deactivate(struct sev_data_deactivate *data, int *error);
584 * sev_guest_activate - perform SEV ACTIVATE command
586 * @activate: sev_data_activate structure to be processed
587 * @sev_ret: sev command return code
590 * 0 if the sev successfully processed the command
591 * -%ENODEV if the sev device is not available
592 * -%ENOTSUPP if the sev does not support SEV
593 * -%ETIMEDOUT if the sev command timed out
594 * -%EIO if the sev returned a non-zero return code
596 int sev_guest_activate(struct sev_data_activate *data, int *error);
599 * sev_guest_df_flush - perform SEV DF_FLUSH command
601 * @sev_ret: sev command return code
604 * 0 if the sev successfully processed the command
605 * -%ENODEV if the sev device is not available
606 * -%ENOTSUPP if the sev does not support SEV
607 * -%ETIMEDOUT if the sev command timed out
608 * -%EIO if the sev returned a non-zero return code
610 int sev_guest_df_flush(int *error);
613 * sev_guest_decommission - perform SEV DECOMMISSION command
615 * @decommission: sev_data_decommission structure to be processed
616 * @sev_ret: sev command return code
619 * 0 if the sev successfully processed the command
620 * -%ENODEV if the sev device is not available
621 * -%ENOTSUPP if the sev does not support SEV
622 * -%ETIMEDOUT if the sev command timed out
623 * -%EIO if the sev returned a non-zero return code
625 int sev_guest_decommission(struct sev_data_decommission *data, int *error);
627 void *psp_copy_user_blob(u64 uaddr, u32 len);
629 #else /* !CONFIG_CRYPTO_DEV_SP_PSP */
632 sev_platform_status(struct sev_user_data_status *status, int *error) { return -ENODEV; }
634 static inline int sev_platform_init(int *error) { return -ENODEV; }
637 sev_guest_deactivate(struct sev_data_deactivate *data, int *error) { return -ENODEV; }
640 sev_guest_decommission(struct sev_data_decommission *data, int *error) { return -ENODEV; }
643 sev_guest_activate(struct sev_data_activate *data, int *error) { return -ENODEV; }
645 static inline int sev_guest_df_flush(int *error) { return -ENODEV; }
648 sev_issue_cmd_external_user(struct file *filep, unsigned int id, void *data, int *error) { return -ENODEV; }
650 static inline void *psp_copy_user_blob(u64 __user uaddr, u32 len) { return ERR_PTR(-EINVAL); }
652 #endif /* CONFIG_CRYPTO_DEV_SP_PSP */
654 #endif /* __PSP_SEV_H__ */