2021-09-14 21:10:49

by Sean Christopherson

[permalink] [raw]
Subject: [PATCH 0/2] KVM: SEV: RECEIVE_UPDATE_DATA bug fixes

Patch 1 pins the target of RECEIVE_UPDATE_DATA for write instead of read.
The SEV API clearly states that the PSP writes guest memory, which makes
sense given that the guest is receiving data.

Patch 2 adds a CLFLUSH of the guest memory as there is no requirement
that the page already be in an encrypted state before RECEIVE_UPDATE_DATA,
i.e. the cache may have dirty, unencrypted data.

On my end, these patches are compile-tested only as I don't have a
userspace VMM that supports SEV live migration, nor are there tests for
any of this stuff.

Masahiro Kozuka (1):
KVM: SEV: Flush cache on non-coherent systems before
RECEIVE_UPDATE_DATA

Sean Christopherson (1):
KVM: SEV: Pin guest memory for write for RECEIVE_UPDATE_DATA

arch/x86/kvm/svm/sev.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

--
2.33.0.309.g3052b89438-goog


2021-09-14 21:12:23

by Sean Christopherson

[permalink] [raw]
Subject: [PATCH 1/2] KVM: SEV: Pin guest memory for write for RECEIVE_UPDATE_DATA

Require the target guest page to be writable when pinning memory for
RECEIVE_UPDATE_DATA. Per the SEV API, the PSP writes to guest memory:

The result is then encrypted with GCTX.VEK and written to the memory
pointed to by GUEST_PADDR field.

Fixes: 15fb7de1a7f5 ("KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_DATA command")
Cc: [email protected]
Cc: Peter Gonda <[email protected]>
Cc: Marc Orr <[email protected]>
Cc: Tom Lendacky <[email protected]>
Cc: Brijesh Singh <[email protected]>
Signed-off-by: Sean Christopherson <[email protected]>
---
arch/x86/kvm/svm/sev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 75e0b21ad07c..95228ba3cd8f 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -1464,7 +1464,7 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)

/* Pin guest memory */
guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
- PAGE_SIZE, &n, 0);
+ PAGE_SIZE, &n, 1);
if (IS_ERR(guest_page)) {
ret = PTR_ERR(guest_page);
goto e_free_trans;
--
2.33.0.309.g3052b89438-goog

2021-09-14 21:12:32

by Sean Christopherson

[permalink] [raw]
Subject: [PATCH 2/2] KVM: SEV: Flush cache on non-coherent systems before RECEIVE_UPDATE_DATA

From: Masahiro Kozuka <[email protected]>

Flush the destination page before invoking RECEIVE_UPDATE_DATA, as the
PSP encrypts the data with the guest's key when writing to guest memory.
If the target memory was not previously encrypted, the cache may contain
dirty, unecrypted data that will persist on non-coherent systems.

Fixes: 15fb7de1a7f5 ("KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_DATA command")
Cc: [email protected]
Cc: Peter Gonda <[email protected]>
Cc: Marc Orr <[email protected]>
Cc: Tom Lendacky <[email protected]>
Cc: Brijesh Singh <[email protected]>
Signed-off-by: Masahiro Kozuka <[email protected]>
[sean: converted bug report to changelog]
Signed-off-by: Sean Christopherson <[email protected]>
---
arch/x86/kvm/svm/sev.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 95228ba3cd8f..f5edc67b261b 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -1470,6 +1470,13 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
goto e_free_trans;
}

+ /*
+ * Flush (on non-coherent CPUs) before RECEIVE_UPDATE_DATA, the PSP
+ * encrypts the written data with the guest's key, and the cache may
+ * contain dirty, unencrypted data.
+ */
+ sev_clflush_pages(guest_page, n);
+
/* The RECEIVE_UPDATE_DATA command requires C-bit to be always set. */
data.guest_address = (page_to_pfn(guest_page[0]) << PAGE_SHIFT) + offset;
data.guest_address |= sev_me_mask;
--
2.33.0.309.g3052b89438-goog

2021-09-14 22:07:15

by Peter Gonda

[permalink] [raw]
Subject: Re: [PATCH 1/2] KVM: SEV: Pin guest memory for write for RECEIVE_UPDATE_DATA

On Tue, Sep 14, 2021 at 3:09 PM Sean Christopherson <[email protected]> wrote:
>
> Require the target guest page to be writable when pinning memory for
> RECEIVE_UPDATE_DATA. Per the SEV API, the PSP writes to guest memory:
>
> The result is then encrypted with GCTX.VEK and written to the memory
> pointed to by GUEST_PADDR field.
>
> Fixes: 15fb7de1a7f5 ("KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_DATA command")
> Cc: [email protected]
> Cc: Peter Gonda <[email protected]>
> Cc: Marc Orr <[email protected]>
> Cc: Tom Lendacky <[email protected]>
> Cc: Brijesh Singh <[email protected]>
> Signed-off-by: Sean Christopherson <[email protected]>

Reviewed-by: Peter Gonda <[email protected]>

> ---
> arch/x86/kvm/svm/sev.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 75e0b21ad07c..95228ba3cd8f 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -1464,7 +1464,7 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
>
> /* Pin guest memory */
> guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
> - PAGE_SIZE, &n, 0);
> + PAGE_SIZE, &n, 1);
> if (IS_ERR(guest_page)) {
> ret = PTR_ERR(guest_page);
> goto e_free_trans;

Not sure how common this is but adding a comment like this could help
with readability:
+ PAGE_SIZE, &n, /* write= */ 1);


> --
> 2.33.0.309.g3052b89438-goog
>

2021-09-14 22:17:50

by Brijesh Singh

[permalink] [raw]
Subject: Re: [PATCH 1/2] KVM: SEV: Pin guest memory for write for RECEIVE_UPDATE_DATA



On 9/14/21 4:09 PM, Sean Christopherson wrote:
> Require the target guest page to be writable when pinning memory for
> RECEIVE_UPDATE_DATA. Per the SEV API, the PSP writes to guest memory:
>
> The result is then encrypted with GCTX.VEK and written to the memory
> pointed to by GUEST_PADDR field.
>
> Fixes: 15fb7de1a7f5 ("KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_DATA command")
> Cc: [email protected]
> Cc: Peter Gonda <[email protected]>
> Cc: Marc Orr <[email protected]>
> Cc: Tom Lendacky <[email protected]>
> Cc: Brijesh Singh <[email protected]>
> Signed-off-by: Sean Christopherson <[email protected]>

Reviewed-by: Brijesh Singh <[email protected]>

thanks

2021-09-21 18:48:44

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH 1/2] KVM: SEV: Pin guest memory for write for RECEIVE_UPDATE_DATA

On 14/09/21 23:09, Sean Christopherson wrote:
> Require the target guest page to be writable when pinning memory for
> RECEIVE_UPDATE_DATA. Per the SEV API, the PSP writes to guest memory:
>
> The result is then encrypted with GCTX.VEK and written to the memory
> pointed to by GUEST_PADDR field.
>
> Fixes: 15fb7de1a7f5 ("KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_DATA command")
> Cc: [email protected]
> Cc: Peter Gonda <[email protected]>
> Cc: Marc Orr <[email protected]>
> Cc: Tom Lendacky <[email protected]>
> Cc: Brijesh Singh <[email protected]>
> Signed-off-by: Sean Christopherson <[email protected]>
> ---
> arch/x86/kvm/svm/sev.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 75e0b21ad07c..95228ba3cd8f 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -1464,7 +1464,7 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
>
> /* Pin guest memory */
> guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
> - PAGE_SIZE, &n, 0);
> + PAGE_SIZE, &n, 1);
> if (IS_ERR(guest_page)) {
> ret = PTR_ERR(guest_page);
> goto e_free_trans;
>

Queued both, thanks.

Paolo

2021-10-20 23:01:00

by Kalra, Ashish

[permalink] [raw]
Subject: [PATCH 2/2] KVM: SEV: Flush cache on non-coherent systems before RECEIVE_UPDATE_DATA

From: Sean Christopherson <[email protected]>

Hello Paolo,

I am adding a SEV migration test as part of the KVM SEV selftests.

And while testing SEV migration with this selftest, i observed
cache coherency issues causing migration test failures, so really
need this patch to be added.

Tested-by: Ashish Kalra <[email protected]>

2021-10-21 17:06:14

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH 2/2] KVM: SEV: Flush cache on non-coherent systems before RECEIVE_UPDATE_DATA

On 21/10/21 00:58, Ashish Kalra wrote:
> From: Sean Christopherson <[email protected]>
>
> Hello Paolo,
>
> I am adding a SEV migration test as part of the KVM SEV selftests.
>
> And while testing SEV migration with this selftest, i observed
> cache coherency issues causing migration test failures, so really
> need this patch to be added.
>
> Tested-by: Ashish Kalra <[email protected]>
>

Queued for 5.15, thanks.

Paolo