From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io0-f197.google.com (mail-io0-f197.google.com [209.85.223.197]) by kanga.kvack.org (Postfix) with ESMTP id 869486B0253 for ; Fri, 3 Nov 2017 11:12:28 -0400 (EDT) Received: by mail-io0-f197.google.com with SMTP id m16so8978658iod.11 for ; Fri, 03 Nov 2017 08:12:28 -0700 (PDT) Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id h203sor3128093iof.196.2017.11.03.08.12.26 for (Google Transport Security); Fri, 03 Nov 2017 08:12:26 -0700 (PDT) Received: from mail-io0-f177.google.com (mail-io0-f177.google.com. [209.85.223.177]) by smtp.gmail.com with ESMTPSA id 92sm2748113iol.8.2017.11.03.08.12.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Nov 2017 08:12:24 -0700 (PDT) Received: by mail-io0-f177.google.com with SMTP id e89so6895649ioi.11 for ; Fri, 03 Nov 2017 08:12:24 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: From: Tomeu Vizoso Date: Fri, 3 Nov 2017 16:12:03 +0100 Message-ID: Subject: Re: [PATCH v10 20/38] x86, mpparse: Use memremap to map the mpf and mpc data Content-Type: text/plain; charset="UTF-8" Sender: owner-linux-mm@kvack.org List-ID: To: Tom Lendacky Cc: x86@kernel.org, "linux-kernel@vger.kernel.org" , linux-arch@vger.kernel.org, linux-efi@vger.kernel.org, "linux-doc@vger.kernel.org" , linux-mm@kvack.org, kvm@vger.kernel.org, kasan-dev@googlegroups.com, =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= , Arnd Bergmann , Jonathan Corbet , Matt Fleming , Konrad Rzeszutek Wilk , Andrey Ryabinin , Ingo Molnar , Borislav Petkov , Andy Lutomirski , "H. Peter Anvin" , Paolo Bonzini , Alexander Potapenko , Thomas Gleixner , Dmitry Vyukov , Rik van Riel , Larry Woodman , Dave Young , Toshimitsu Kani , "Michael S. Tsirkin" , Brijesh Singh , Guenter Roeck , Zach Reizner , Dylan Reid On 17 July 2017 at 23:10, Tom Lendacky wrote: > The SMP MP-table is built by UEFI and placed in memory in a decrypted > state. These tables are accessed using a mix of early_memremap(), > early_memunmap(), phys_to_virt() and virt_to_phys(). Change all accesses > to use early_memremap()/early_memunmap(). This allows for proper setting > of the encryption mask so that the data can be successfully accessed when > SME is active. > > Reviewed-by: Borislav Petkov > Signed-off-by: Tom Lendacky > --- > arch/x86/kernel/mpparse.c | 98 +++++++++++++++++++++++++++++++++-------------- > 1 file changed, 70 insertions(+), 28 deletions(-) Hi there, today I played a bit with crosvm [0] and noticed that 4.14-rc7 doesn't boot. git-bisect pointed to this patch, and reverting it indeed gets things working again. Anybody has an idea of why this could be? Thanks, Tomeu [0] https://chromium.googlesource.com/chromiumos/platform/crosvm > > diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c > index fd37f39..5cbb317 100644 > --- a/arch/x86/kernel/mpparse.c > +++ b/arch/x86/kernel/mpparse.c > @@ -429,7 +429,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) > } > } > > -static struct mpf_intel *mpf_found; > +static unsigned long mpf_base; > > static unsigned long __init get_mpc_size(unsigned long physptr) > { > @@ -451,6 +451,7 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) > > size = get_mpc_size(mpf->physptr); > mpc = early_memremap(mpf->physptr, size); > + > /* > * Read the physical hardware table. Anything here will > * override the defaults. > @@ -497,12 +498,12 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) > */ > void __init default_get_smp_config(unsigned int early) > { > - struct mpf_intel *mpf = mpf_found; > + struct mpf_intel *mpf; > > if (!smp_found_config) > return; > > - if (!mpf) > + if (!mpf_base) > return; > > if (acpi_lapic && early) > @@ -515,6 +516,12 @@ void __init default_get_smp_config(unsigned int early) > if (acpi_lapic && acpi_ioapic) > return; > > + mpf = early_memremap(mpf_base, sizeof(*mpf)); > + if (!mpf) { > + pr_err("MPTABLE: error mapping MP table\n"); > + return; > + } > + > pr_info("Intel MultiProcessor Specification v1.%d\n", > mpf->specification); > #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) > @@ -529,7 +536,7 @@ void __init default_get_smp_config(unsigned int early) > /* > * Now see if we need to read further. > */ > - if (mpf->feature1 != 0) { > + if (mpf->feature1) { > if (early) { > /* > * local APIC has default address > @@ -542,8 +549,10 @@ void __init default_get_smp_config(unsigned int early) > construct_default_ISA_mptable(mpf->feature1); > > } else if (mpf->physptr) { > - if (check_physptr(mpf, early)) > + if (check_physptr(mpf, early)) { > + early_memunmap(mpf, sizeof(*mpf)); > return; > + } > } else > BUG(); > > @@ -552,6 +561,8 @@ void __init default_get_smp_config(unsigned int early) > /* > * Only use the first configuration found. > */ > + > + early_memunmap(mpf, sizeof(*mpf)); > } > > static void __init smp_reserve_memory(struct mpf_intel *mpf) > @@ -561,15 +572,16 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf) > > static int __init smp_scan_config(unsigned long base, unsigned long length) > { > - unsigned int *bp = phys_to_virt(base); > + unsigned int *bp; > struct mpf_intel *mpf; > - unsigned long mem; > + int ret = 0; > > apic_printk(APIC_VERBOSE, "Scan for SMP in [mem %#010lx-%#010lx]\n", > base, base + length - 1); > BUILD_BUG_ON(sizeof(*mpf) != 16); > > while (length > 0) { > + bp = early_memremap(base, length); > mpf = (struct mpf_intel *)bp; > if ((*bp == SMP_MAGIC_IDENT) && > (mpf->length == 1) && > @@ -579,24 +591,26 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) > #ifdef CONFIG_X86_LOCAL_APIC > smp_found_config = 1; > #endif > - mpf_found = mpf; > + mpf_base = base; > > - pr_info("found SMP MP-table at [mem %#010llx-%#010llx] mapped at [%p]\n", > - (unsigned long long) virt_to_phys(mpf), > - (unsigned long long) virt_to_phys(mpf) + > - sizeof(*mpf) - 1, mpf); > + pr_info("found SMP MP-table at [mem %#010lx-%#010lx] mapped at [%p]\n", > + base, base + sizeof(*mpf) - 1, mpf); > > - mem = virt_to_phys(mpf); > - memblock_reserve(mem, sizeof(*mpf)); > + memblock_reserve(base, sizeof(*mpf)); > if (mpf->physptr) > smp_reserve_memory(mpf); > > - return 1; > + ret = 1; > } > - bp += 4; > + early_memunmap(bp, length); > + > + if (ret) > + break; > + > + base += 16; > length -= 16; > } > - return 0; > + return ret; > } > > void __init default_find_smp_config(void) > @@ -838,29 +852,40 @@ static int __init update_mp_table(void) > char oem[10]; > struct mpf_intel *mpf; > struct mpc_table *mpc, *mpc_new; > + unsigned long size; > > if (!enable_update_mptable) > return 0; > > - mpf = mpf_found; > - if (!mpf) > + if (!mpf_base) > + return 0; > + > + mpf = early_memremap(mpf_base, sizeof(*mpf)); > + if (!mpf) { > + pr_err("MPTABLE: mpf early_memremap() failed\n"); > return 0; > + } > > /* > * Now see if we need to go further. > */ > - if (mpf->feature1 != 0) > - return 0; > + if (mpf->feature1) > + goto do_unmap_mpf; > > if (!mpf->physptr) > - return 0; > + goto do_unmap_mpf; > > - mpc = phys_to_virt(mpf->physptr); > + size = get_mpc_size(mpf->physptr); > + mpc = early_memremap(mpf->physptr, size); > + if (!mpc) { > + pr_err("MPTABLE: mpc early_memremap() failed\n"); > + goto do_unmap_mpf; > + } > > if (!smp_check_mpc(mpc, oem, str)) > - return 0; > + goto do_unmap_mpc; > > - pr_info("mpf: %llx\n", (u64)virt_to_phys(mpf)); > + pr_info("mpf: %llx\n", (u64)mpf_base); > pr_info("physptr: %x\n", mpf->physptr); > > if (mpc_new_phys && mpc->length > mpc_new_length) { > @@ -878,21 +903,32 @@ static int __init update_mp_table(void) > new = mpf_checksum((unsigned char *)mpc, mpc->length); > if (old == new) { > pr_info("mpc is readonly, please try alloc_mptable instead\n"); > - return 0; > + goto do_unmap_mpc; > } > pr_info("use in-position replacing\n"); > } else { > + mpc_new = early_memremap(mpc_new_phys, mpc_new_length); > + if (!mpc_new) { > + pr_err("MPTABLE: new mpc early_memremap() failed\n"); > + goto do_unmap_mpc; > + } > mpf->physptr = mpc_new_phys; > - mpc_new = phys_to_virt(mpc_new_phys); > memcpy(mpc_new, mpc, mpc->length); > + early_memunmap(mpc, size); > mpc = mpc_new; > + size = mpc_new_length; > /* check if we can modify that */ > if (mpc_new_phys - mpf->physptr) { > struct mpf_intel *mpf_new; > /* steal 16 bytes from [0, 1k) */ > + mpf_new = early_memremap(0x400 - 16, sizeof(*mpf_new)); > + if (!mpf_new) { > + pr_err("MPTABLE: new mpf early_memremap() failed\n"); > + goto do_unmap_mpc; > + } > pr_info("mpf new: %x\n", 0x400 - 16); > - mpf_new = phys_to_virt(0x400 - 16); > memcpy(mpf_new, mpf, 16); > + early_memunmap(mpf, sizeof(*mpf)); > mpf = mpf_new; > mpf->physptr = mpc_new_phys; > } > @@ -909,6 +945,12 @@ static int __init update_mp_table(void) > */ > replace_intsrc_all(mpc, mpc_new_phys, mpc_new_length); > > +do_unmap_mpc: > + early_memunmap(mpc, size); > + > +do_unmap_mpf: > + early_memunmap(mpf, sizeof(*mpf)); > + > return 0; > } > > -- > 1.9.1 > -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org