diff mbox series

KVM: SVM: Add support for KVM_SEV_SEND_CANCEL command

Message ID 20210402014438.1721086-1-srutherford@google.com (mailing list archive)
State New, archived
Headers show
Series KVM: SVM: Add support for KVM_SEV_SEND_CANCEL command | expand

Commit Message

Steve Rutherford April 2, 2021, 1:44 a.m. UTC
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.

Signed-off-by: Steve Rutherford <srutherford@google.com>
---
 .../virt/kvm/amd-memory-encryption.rst        |  9 +++++++
 arch/x86/kvm/svm/sev.c                        | 24 +++++++++++++++++++
 include/linux/psp-sev.h                       | 10 ++++++++
 include/uapi/linux/kvm.h                      |  2 ++
 4 files changed, 45 insertions(+)

Comments

Nathan Tempelman April 8, 2021, 10:02 p.m. UTC | #1
On Thu, Apr 1, 2021 at 6:45 PM Steve Rutherford <srutherford@google.com> wrote:
>
> 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.
>
> Signed-off-by: Steve Rutherford <srutherford@google.com>
> ---
>  .../virt/kvm/amd-memory-encryption.rst        |  9 +++++++
>  arch/x86/kvm/svm/sev.c                        | 24 +++++++++++++++++++
>  include/linux/psp-sev.h                       | 10 ++++++++
>  include/uapi/linux/kvm.h                      |  2 ++
>  4 files changed, 45 insertions(+)
>
> diff --git a/Documentation/virt/kvm/amd-memory-encryption.rst b/Documentation/virt/kvm/amd-memory-encryption.rst
> index 469a6308765b1..9e018a3eec03b 100644
> --- a/Documentation/virt/kvm/amd-memory-encryption.rst
> +++ b/Documentation/virt/kvm/amd-memory-encryption.rst
> @@ -284,6 +284,15 @@ Returns: 0 on success, -negative on error
>                  __u32 len;
>          };
>
> +16. KVM_SEV_SEND_CANCEL
> +------------------------
> +
> +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.
> +
> +Returns: 0 on success, -negative on error
> +
>  References
>  ==========
>
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 83e00e5245136..88e72102cb900 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -1110,6 +1110,27 @@ static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp)
>         return ret;
>  }
>
> +static int sev_send_cancel(struct kvm *kvm, struct kvm_sev_cmd *argp)
> +{
> +       struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
> +       struct sev_data_send_cancel *data;
> +       int ret;
> +
> +       if (!sev_guest(kvm))
> +               return -ENOTTY;
> +
> +       data = kzalloc(sizeof(*data), GFP_KERNEL);
> +       if (!data)
> +               return -ENOMEM;
> +
> +       data->handle = sev->handle;
> +       ret = sev_issue_cmd(kvm, SEV_CMD_SEND_CANCEL, data, &argp->error);
> +
> +       kfree(data);
> +       return ret;
> +}
> +
> +
>  int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
>  {
>         struct kvm_sev_cmd sev_cmd;
> @@ -1163,6 +1184,9 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
>         case KVM_SEV_GET_ATTESTATION_REPORT:
>                 r = sev_get_attestation_report(kvm, &sev_cmd);
>                 break;
> +       case KVM_SEV_SEND_CANCEL:
> +               r = sev_send_cancel(kvm, &sev_cmd);
> +               break;
>         default:
>                 r = -EINVAL;
>                 goto out;
> diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
> index b801ead1e2bb5..74f2babffc574 100644
> --- a/include/linux/psp-sev.h
> +++ b/include/linux/psp-sev.h
> @@ -73,6 +73,7 @@ enum sev_cmd {
>         SEV_CMD_SEND_UPDATE_DATA        = 0x041,
>         SEV_CMD_SEND_UPDATE_VMSA        = 0x042,
>         SEV_CMD_SEND_FINISH             = 0x043,
> +       SEV_CMD_SEND_CANCEL             = 0x044,
>
>         /* Guest migration commands (incoming) */
>         SEV_CMD_RECEIVE_START           = 0x050,
> @@ -392,6 +393,15 @@ struct sev_data_send_finish {
>         u32 handle;                             /* In */
>  } __packed;
>
> +/**
> + * struct sev_data_send_cancel - SEND_CANCEL command parameters
> + *
> + * @handle: handle of the VM to process
> + */
> +struct sev_data_send_cancel {
> +       u32 handle;                             /* In */
> +} __packed;
> +
>  /**
>   * struct sev_data_receive_start - RECEIVE_START command parameters
>   *
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index f6afee209620d..707469b6b7072 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1671,6 +1671,8 @@ enum sev_cmd_id {
>         KVM_SEV_CERT_EXPORT,
>         /* Attestation report */
>         KVM_SEV_GET_ATTESTATION_REPORT,
> +       /* Guest Migration Extension */
> +       KVM_SEV_SEND_CANCEL,
>
>         KVM_SEV_NR_MAX,
>  };
> --
> 2.31.0.208.g409f899ff0-goog
>

Reviewed-by: Nathan Tempelman <natet@google.com>
Brijesh Singh April 8, 2021, 10:27 p.m. UTC | #2
On 4/1/21 8:44 PM, Steve Rutherford wrote:
> 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.
>
> Signed-off-by: Steve Rutherford <srutherford@google.com>
> ---
>  .../virt/kvm/amd-memory-encryption.rst        |  9 +++++++
>  arch/x86/kvm/svm/sev.c                        | 24 +++++++++++++++++++
>  include/linux/psp-sev.h                       | 10 ++++++++
>  include/uapi/linux/kvm.h                      |  2 ++
>  4 files changed, 45 insertions(+)


Can we add a new case statement in sev_cmd_buffer_len()
[drivers/crypto/ccp/sev-dev.c] for this command ? I understand that the
command just contains the handle. I have found dyndbg very helpful. If
the command is not added in the sev_cmd_buffer_len() then we don't dump
the command buffer.

With that fixed.

Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Steve Rutherford April 9, 2021, 12:49 a.m. UTC | #3
On Thu, Apr 8, 2021 at 3:27 PM Brijesh Singh <brijesh.singh@amd.com> wrote:
>
>
> On 4/1/21 8:44 PM, Steve Rutherford wrote:
> > 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.
> >
> > Signed-off-by: Steve Rutherford <srutherford@google.com>
> > ---
> >  .../virt/kvm/amd-memory-encryption.rst        |  9 +++++++
> >  arch/x86/kvm/svm/sev.c                        | 24 +++++++++++++++++++
> >  include/linux/psp-sev.h                       | 10 ++++++++
> >  include/uapi/linux/kvm.h                      |  2 ++
> >  4 files changed, 45 insertions(+)
>
>
> Can we add a new case statement in sev_cmd_buffer_len()
> [drivers/crypto/ccp/sev-dev.c] for this command ? I understand that the
> command just contains the handle. I have found dyndbg very helpful. If
> the command is not added in the sev_cmd_buffer_len() then we don't dump
> the command buffer.
>
> With that fixed.
>
> Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>

Nice catch, will follow-up shortly.


Steve
diff mbox series

Patch

diff --git a/Documentation/virt/kvm/amd-memory-encryption.rst b/Documentation/virt/kvm/amd-memory-encryption.rst
index 469a6308765b1..9e018a3eec03b 100644
--- a/Documentation/virt/kvm/amd-memory-encryption.rst
+++ b/Documentation/virt/kvm/amd-memory-encryption.rst
@@ -284,6 +284,15 @@  Returns: 0 on success, -negative on error
                 __u32 len;
         };
 
+16. KVM_SEV_SEND_CANCEL
+------------------------
+
+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.
+
+Returns: 0 on success, -negative on error
+
 References
 ==========
 
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 83e00e5245136..88e72102cb900 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -1110,6 +1110,27 @@  static int sev_get_attestation_report(struct kvm *kvm, struct kvm_sev_cmd *argp)
 	return ret;
 }
 
+static int sev_send_cancel(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
+	struct sev_data_send_cancel *data;
+	int ret;
+
+	if (!sev_guest(kvm))
+		return -ENOTTY;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->handle = sev->handle;
+	ret = sev_issue_cmd(kvm, SEV_CMD_SEND_CANCEL, data, &argp->error);
+
+	kfree(data);
+	return ret;
+}
+
+
 int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
 {
 	struct kvm_sev_cmd sev_cmd;
@@ -1163,6 +1184,9 @@  int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
 	case KVM_SEV_GET_ATTESTATION_REPORT:
 		r = sev_get_attestation_report(kvm, &sev_cmd);
 		break;
+	case KVM_SEV_SEND_CANCEL:
+		r = sev_send_cancel(kvm, &sev_cmd);
+		break;
 	default:
 		r = -EINVAL;
 		goto out;
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index b801ead1e2bb5..74f2babffc574 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -73,6 +73,7 @@  enum sev_cmd {
 	SEV_CMD_SEND_UPDATE_DATA	= 0x041,
 	SEV_CMD_SEND_UPDATE_VMSA	= 0x042,
 	SEV_CMD_SEND_FINISH		= 0x043,
+	SEV_CMD_SEND_CANCEL		= 0x044,
 
 	/* Guest migration commands (incoming) */
 	SEV_CMD_RECEIVE_START		= 0x050,
@@ -392,6 +393,15 @@  struct sev_data_send_finish {
 	u32 handle;				/* In */
 } __packed;
 
+/**
+ * struct sev_data_send_cancel - SEND_CANCEL command parameters
+ *
+ * @handle: handle of the VM to process
+ */
+struct sev_data_send_cancel {
+	u32 handle;				/* In */
+} __packed;
+
 /**
  * struct sev_data_receive_start - RECEIVE_START command parameters
  *
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index f6afee209620d..707469b6b7072 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1671,6 +1671,8 @@  enum sev_cmd_id {
 	KVM_SEV_CERT_EXPORT,
 	/* Attestation report */
 	KVM_SEV_GET_ATTESTATION_REPORT,
+	/* Guest Migration Extension */
+	KVM_SEV_SEND_CANCEL,
 
 	KVM_SEV_NR_MAX,
 };