mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Singh, Brijesh" <brijesh.singh@amd.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: "Singh, Brijesh" <brijesh.singh@amd.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"x86@kernel.org" <x86@kernel.org>,
	Dave Hansen <dave.hansen@intel.com>,
	Dan Williams <dan.j.williams@intel.com>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
	Andy Lutomirski <luto@kernel.org>, Borislav Petkov <bp@alien8.de>,
	"H . Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	"Lendacky, Thomas" <Thomas.Lendacky@amd.com>
Subject: Re: [PATCH] x86: mm: Do not use set_{pud,pmd}_safe when splitting the large page
Date: Tue, 9 Apr 2019 19:09:54 +0000	[thread overview]
Message-ID: <5511d82d-4443-bd13-a3a5-c1b5a72ce0e9@amd.com> (raw)
In-Reply-To: <20190409093935.GH14281@hirez.programming.kicks-ass.net>



On 4/9/19 4:39 AM, Peter Zijlstra wrote:
> On Tue, Apr 09, 2019 at 10:40:31AM +0200, Peter Zijlstra wrote:
>> On Mon, Apr 08, 2019 at 07:11:21PM +0000, Singh, Brijesh wrote:
>>> The following commit 0a9fe8ca844d ("x86/mm: Validate kernel_physical_mapping_init()
>>> PTE population") triggers the below warning in the SEV guest.
>>>
>>> WARNING: CPU: 0 PID: 0 at arch/x86/include/asm/pgalloc.h:87 phys_pmd_init+0x30d/0x386
>>> Call Trace:
>>>   kernel_physical_mapping_init+0xce/0x259
>>>   early_set_memory_enc_dec+0x10f/0x160
>>>   kvm_smp_prepare_boot_cpu+0x71/0x9d
>>>   start_kernel+0x1c9/0x50b
>>>   secondary_startup_64+0xa4/0xb0
>>>
>>> The SEV guest calls kernel_physical_mapping_init() to clear the encryption
>>> mask from an existing mapping. While clearing the encryption mask
>>> kernel_physical_mapping_init() splits the large pages into the smaller.
>>> To split the page, the kernel_physical_mapping_init() allocates a new page
>>> and updates the existing entry. The set_{pud,pmd}_safe triggers warning
>>> when updating the entry with page in the present state. We should use the
>>> set_{pud,pmd} when updating an existing entry with the new entry.
>>>
>>> Updating an entry will also requires a TLB flush. Currently the caller
>>> (early_set_memory_enc_dec()) is taking care of issuing the TLB flushes.
>>
>> I'm not entirely sure I like this, this means all users of
>> kernel_physical_mapping_init() now need to be aware and careful.
>>
>> That said; the alternative is adding an argument to the function and
>> propagating it through the callchain and dynamically switching between
>> _safe and not. Which doesn't sound ideal either.
>>
>> Anybody else got clever ideas?
> 
> The more I think about it, I think that is in fact the right thing to
> do.
> 
> Rename kernel_physical_mapping_init() to __& and add that flag, thread
> it down to all the set_{pud,pmd.pte}() thingies. Then add:
> 
> unsigned long kernel_physical_mapping_init(unsigned long paddr_start, unsigned
> 		long paddr_end, unsigned long page_size_mask)
> {
> 	return __kernel_physical_mapping_init(paddr_start, paddr_end, page_size_mask, true);
> }
> 
> unsigned long kernel_physical_mapping_change(unsigned long paddr_start, unsigned
> 		long paddr_end, unsigned long page_size_mask)
> {
> 	unsigned long last;
> 
> 	last = __kernel_physical_mapping_init(paddr_start, paddr_end, page_size_mask, false);
> 
> 	__flush_tlb_all();
> 
> 	return last;
> }
> 
> Or something along those lines.


thanks for the comment. So regarding changing all the set_{pud,pmd,pte}
thingies, I can go in one of the two options below, please let me know
which is preferred.

1) Update all the functions to check for the flag and use the safe vs
non-safe variants accordingly. Something similar to this:

    if (use_safe)
       set_pmd_safe(...)
    else
       set_pmd(..)

    ....
    if (use_safe)
       pmd_populate_kernel_safe(...)
    else
       pmd_populate(...)

There are multiple places where we need to add the above check.

2) Define new __& variants of set_{pud,pmd,pte} and populate_{pud,..}
and update the callers to use the __&. Something like this:

#define DEFINE_POPULATE(fname, type1, type2, safe)              \
static void inline __##fname(struct mm_struct *mm,              \
                 type1##_t *arg1, type2##_t *arg2, bool safe)    \
{								\
	if (safe)						\
		fname##_safe(mm, arg1, arg2);			\
	else
		fname(mm, arg1, arg2);				\
}

DEFINE_POPULATE(p4d_populate, p4d, pud, safe)
DEFINE_POPULATE(pgd_populate, pgd, p4d, safe)
DEFINE_POPULATE(pud_populate, pud, pmd, safe)
DEFINE_POPULATE(pmd_populate_kernel, pmd, pte, safe)

I prefer #2 because it still keeps the code readable and minimize the
changes in the patch file.

thanks

      parent reply	other threads:[~2019-04-09 19:10 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-08 19:11 Singh, Brijesh
2019-04-09  8:40 ` Peter Zijlstra
2019-04-09  9:39   ` Peter Zijlstra
2019-04-09 10:20     ` Borislav Petkov
2019-04-09 19:09     ` Singh, Brijesh [this message]

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=5511d82d-4443-bd13-a3a5-c1b5a72ce0e9@amd.com \
    --to=brijesh.singh@amd.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=bp@alien8.de \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=hpa@zytor.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®