After completion of SEND_START, but before SEND_FINISH, the source VMM can issue the SEND_CANCEL command to stop a migration. This is necessary so that a cancelled migration can restart with a new target later.
Unified · Split
| @@ -356,6 +356,15 @@ issued by the hypervisor to delete the encryption context. · 355 unmodified lines | |||
| 356 | 356 | ||
| 357 | Returns: 0 on success, -negative on error | 357 | Returns: 0 on success, -negative on error |
| 358 | 358 | ||
| 359 | 14. KVM_SEV_SEND_CANCEL | ||
| 360 | ------------------------ | ||
| 361 | |||
| 362 | After completion of SEND_START, but before SEND_FINISH, the source VMM can issue the | ||
| 363 | SEND_CANCEL command to stop a migration. This is necessary so that a cancelled | ||
| 364 | migration can restart with a new target later. | ||
| 365 | |||
| 366 | Returns: 0 on success, -negative on error | ||
| 367 | |||
| 359 | References | 368 | References |
| 360 | ========== | 369 | ========== |
| 361 | 370 | ||
| @@ -1377,6 +1377,26 @@ static int sev_send_finish(struct kvm *kvm, struct kvm_sev_cmd *argp) · 1376 unmodified lines | |||
| 1377 | return ret; | 1377 | return ret; |
| 1378 | } | 1378 | } |
| 1379 | 1379 | ||
| 1380 | static int sev_send_cancel(struct kvm *kvm, struct kvm_sev_cmd *argp) | ||
| 1381 | { | ||
| 1382 | struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; | ||
| 1383 | struct sev_data_send_cancel *data; | ||
| 1384 | int ret; | ||
| 1385 | |||
| 1386 | if (!sev_guest(kvm)) | ||
| 1387 | return -ENOTTY; | ||
| 1388 | |||
| 1389 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
| 1390 | if (!data) | ||
| 1391 | return -ENOMEM; | ||
| 1392 | |||
| 1393 | data->handle = sev->handle; | ||
| 1394 | ret = sev_issue_cmd(kvm, SEV_CMD_SEND_CANCEL, data, &argp->error); | ||
| 1395 | |||
| 1396 | kfree(data); | ||
| 1397 | return ret; | ||
| 1398 | } | ||
| 1399 | |||
| 1380 | int svm_mem_enc_op(struct kvm *kvm, void __user *argp) | 1400 | int svm_mem_enc_op(struct kvm *kvm, void __user *argp) |
| 1381 | { | 1401 | { |
| 1382 | struct kvm_sev_cmd sev_cmd; | 1402 | struct kvm_sev_cmd sev_cmd; |
| @@ -1448,6 +1468,9 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp) · 65 unmodified lines | |||
| 1448 | case KVM_SEV_SEND_FINISH: | 1468 | case KVM_SEV_SEND_FINISH: |
| 1449 | r = sev_send_finish(kvm, &sev_cmd); | 1469 | r = sev_send_finish(kvm, &sev_cmd); |
| 1450 | break; | 1470 | break; |
| 1471 | case KVM_SEV_SEND_CANCEL: | ||
| 1472 | r = sev_send_cancel(kvm, &sev_cmd); | ||
| 1473 | break; | ||
| 1451 | default: | 1474 | default: |
| 1452 | r = -EINVAL; | 1475 | r = -EINVAL; |
| 1453 | goto out; | 1476 | goto out; |
| @@ -129,6 +129,7 @@ static int sev_cmd_buffer_len(int cmd) · 128 unmodified lines | |||
| 129 | case SEV_CMD_DOWNLOAD_FIRMWARE: return sizeof(struct sev_data_download_firmware); | 129 | case SEV_CMD_DOWNLOAD_FIRMWARE: return sizeof(struct sev_data_download_firmware); |
| 130 | case SEV_CMD_GET_ID: return sizeof(struct sev_data_get_id); | 130 | case SEV_CMD_GET_ID: return sizeof(struct sev_data_get_id); |
| 131 | case SEV_CMD_ATTESTATION_REPORT: return sizeof(struct sev_data_attestation_report); | 131 | case SEV_CMD_ATTESTATION_REPORT: return sizeof(struct sev_data_attestation_report); |
| 132 | case SEV_CMD_SEND_CANCEL: return sizeof(struct sev_data_send_cancel); | ||
| 132 | default: return 0; | 133 | default: return 0; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| @@ -73,6 +73,7 @@ enum sev_cmd { · 72 unmodified lines | |||
| 73 | SEV_CMD_SEND_UPDATE_DATA = 0x041, | 73 | SEV_CMD_SEND_UPDATE_DATA = 0x041, |
| 74 | SEV_CMD_SEND_UPDATE_VMSA = 0x042, | 74 | SEV_CMD_SEND_UPDATE_VMSA = 0x042, |
| 75 | SEV_CMD_SEND_FINISH = 0x043, | 75 | SEV_CMD_SEND_FINISH = 0x043, |
| 76 | SEV_CMD_SEND_CANCEL = 0x044, | ||
| 76 | 77 | ||
| 77 | /* Guest migration commands (incoming) */ | 78 | /* Guest migration commands (incoming) */ |
| 78 | SEV_CMD_RECEIVE_START = 0x050, | 79 | SEV_CMD_RECEIVE_START = 0x050, |
| @@ -392,6 +393,15 @@ struct sev_data_send_finish { · 313 unmodified lines | |||
| 392 | u32 handle; /* In */ | 393 | u32 handle; /* In */ |
| 393 | } __packed; | 394 | } __packed; |
| 394 | 395 | ||
| 396 | /** | ||
| 397 | * struct sev_data_send_cancel - SEND_CANCEL command parameters | ||
| 398 | * | ||
| 399 | * @handle: handle of the VM to process | ||
| 400 | */ | ||
| 401 | struct sev_data_send_cancel { | ||
| 402 | u32 handle; /* In */ | ||
| 403 | } __packed; | ||
| 404 | |||
| 395 | /** | 405 | /** |
| 396 | * struct sev_data_receive_start - RECEIVE_START command parameters | 406 | * struct sev_data_receive_start - RECEIVE_START command parameters |
| 397 | * | 407 | * |
| @@ -1674,6 +1674,8 @@ enum sev_cmd_id { · 1673 unmodified lines | |||
| 1674 | KVM_SEV_CERT_EXPORT, | 1674 | KVM_SEV_CERT_EXPORT, |
| 1675 | /* Attestation report */ | 1675 | /* Attestation report */ |
| 1676 | KVM_SEV_GET_ATTESTATION_REPORT, | 1676 | KVM_SEV_GET_ATTESTATION_REPORT, |
| 1677 | /* Guest Migration Extension */ | ||
| 1678 | KVM_SEV_SEND_CANCEL, | ||
| 1677 | 1679 | ||
| 1678 | KVM_SEV_NR_MAX, | 1680 | KVM_SEV_NR_MAX, |
| 1679 | }; | 1681 | }; |