All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tom Lendacky <thomas.lendacky@amd.com>
To: Steve Rutherford <srutherford@google.com>
Cc: Borislav Petkov <bp@alien8.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Wanpeng Li <wanpengli@tencent.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	Ingo Molnar <mingo@redhat.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	x86@kernel.org, "H . Peter Anvin" <hpa@zytor.com>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	David.Kaplan@amd.com, jacobhxu@google.com,
	patelsvishal@google.com, bhillier@google.com
Subject: Re: [PATCH] x86/sev: Make early_set_memory_decrypted() calls page aligned
Date: Mon, 21 Aug 2023 13:53:54 -0500	[thread overview]
Message-ID: <2a391d50-d474-eec5-76ea-e5dc5590609c@amd.com> (raw)
In-Reply-To: <CABayD+cw3s1UDSN7oR4gWfRT4-snWEqOgAN-y4rzOpe-8D=KdA@mail.gmail.com>

On 8/21/23 13:15, Steve Rutherford wrote:
> On Mon, Aug 21, 2023 at 6:10 AM Tom Lendacky <thomas.lendacky@amd.com> wrote:
>>
>> On 8/18/23 18:34, Steve Rutherford wrote:
>>> early_set_memory_decrypted() assumes its parameters are page aligned.
>>> Non-page aligned calls result in additional pages being marked as
>>> decrypted via the encryption status hypercall, which results in
>>> consistent corruption of pages during live migration. Live
>>> migration requires accurate encryption status information to avoid
>>> migrating pages from the wrong perspective.
>>
>> Hmmm... I'm not sure this is the proper fix. The code is actually doing
>> the right thing from a encyrption/decryption point of view by checking the
>> c-bit for the PTE associated with the virtual address and the size
>> (possibly crossing page boundaries).
>>
>> I think the problem is on the call to early_set_mem_enc_dec_hypercall()
>> where it doesn't take into account the possible crossing of page
>> boundaries and so can under-count the number of pages, right?
> 
> Right now, if you request decryption of e.g. a non-page aligned 0x40
> byte structure, it rounds the 0x40 bytes up to one page, and then
> hypercalls to mark both the page it's on and the subsequent page as
> decrypted (since the rounding stretches the structure onto the next
> page spuriously). The arithmetic in the combination of
> early_set_memory_enc_dec() and early_set_mem_enc_dec_hypercall() are
> correct if they are called with page aligned vaddrs (non-page-aligned
> sizes are fine iiuc).

Ah, right, correct. It is still related to how the page count is 
calculated for the hypercall, though, right? The encryption/decryption 
operations function properly.

If another caller of early_set_memory_decrypted() gets added, it would 
need to know to do the same thing. So I just wonder if this wouldn't be 
better fixed in early_set_memory_enc_dec() by using a page aligned address 
and proper number of pages when calling early_set_mem_enc_dec_hypercall() 
or in early_set_mem_enc_dec_hypercall() where it would take a size 
argument instead of a page count and does the proper work to get a page 
aligned address and proper page count.

Also, if it is the hypercall that is causing the issue, should the Fixes 
tag be 064ce6c550a0 ("mm: x86: Invoke hypercall when page encryption 
status is changed") since the problem is around the hypercall.

Thanks,
Tom

> 
> Thanks,
> Steve
>>
>> Thanks,
>> Tom
>>
>>>
>>> Fixes: 4716276184ec ("X86/KVM: Decrypt shared per-cpu variables when SEV is active")
>>> Signed-off-by: Steve Rutherford <srutherford@google.com>
>>> ---
>>>    arch/x86/kernel/kvm.c | 14 +++++++++++++-
>>>    1 file changed, 13 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
>>> index 6a36db4f79fd..a0c072d3103c 100644
>>> --- a/arch/x86/kernel/kvm.c
>>> +++ b/arch/x86/kernel/kvm.c
>>> @@ -419,7 +419,14 @@ static u64 kvm_steal_clock(int cpu)
>>>
>>>    static inline void __set_percpu_decrypted(void *ptr, unsigned long size)
>>>    {
>>> -     early_set_memory_decrypted((unsigned long) ptr, size);
>>> +     /*
>>> +      * early_set_memory_decrypted() requires page aligned parameters, but
>>> +      * this function needs to handle ptrs offset into a page.
>>> +      */
>>> +     unsigned long start = PAGE_ALIGN_DOWN((unsigned long) ptr);
>>> +     unsigned long end = (unsigned long) ptr + size;
>>> +
>>> +     early_set_memory_decrypted(start, end - start);
>>>    }
>>>
>>>    /*
>>> @@ -438,6 +445,11 @@ static void __init sev_map_percpu_data(void)
>>>                return;
>>>
>>>        for_each_possible_cpu(cpu) {
>>> +             /*
>>> +              * Calling __set_percpu_decrypted() for each per-cpu variable is
>>> +              * inefficent, since it may decrypt the same page multiple times.
>>> +              * That said, it avoids the need for more complicated logic.
>>> +              */
>>>                __set_percpu_decrypted(&per_cpu(apf_reason, cpu), sizeof(apf_reason));
>>>                __set_percpu_decrypted(&per_cpu(steal_time, cpu), sizeof(steal_time));
>>>                __set_percpu_decrypted(&per_cpu(kvm_apic_eoi, cpu), sizeof(kvm_apic_eoi));

  reply	other threads:[~2023-08-21 18:56 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-18 23:34 [PATCH] x86/sev: Make early_set_memory_decrypted() calls page aligned Steve Rutherford
2023-08-21  6:44 ` Gupta, Pankaj
2023-08-21 13:10 ` Tom Lendacky
2023-08-21 18:15   ` Steve Rutherford
2023-08-21 18:53     ` Tom Lendacky [this message]
2023-08-21 19:25       ` Steve Rutherford
2023-08-21 20:24         ` Tom Lendacky
2023-08-21 22:53           ` Steve Rutherford
2023-09-15 11:59 ` Ingo Molnar
2023-09-15 18:44   ` Steve Rutherford
2023-09-16  9:19     ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2a391d50-d474-eec5-76ea-e5dc5590609c@amd.com \
    --to=thomas.lendacky@amd.com \
    --cc=David.Kaplan@amd.com \
    --cc=bhillier@google.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=jacobhxu@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=patelsvishal@google.com \
    --cc=pbonzini@redhat.com \
    --cc=srutherford@google.com \
    --cc=tglx@linutronix.de \
    --cc=vkuznets@redhat.com \
    --cc=wanpengli@tencent.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.