Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp1232373yba; Tue, 2 Apr 2019 05:11:06 -0700 (PDT) X-Google-Smtp-Source: APXvYqwsYw7zyaw1oCZ2nLVo82YRnDW3mpo2lyTqSYarfBi08IMgK8F2vfvW71vyHO0ae8lvUpUZ X-Received: by 2002:a17:902:248:: with SMTP id 66mr71057366plc.286.1554207066263; Tue, 02 Apr 2019 05:11:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554207066; cv=none; d=google.com; s=arc-20160816; b=wOzjZeSeUTssw6bOH8gX6LquH3pzP9JhvUPOf/LcmlDdNQLZXm8hj19HCdeq5OS9Q6 dMfPwn4wv5WNhiQ4aqVPY71A1cSwQONdATtGLl8PgD2OnWdwGLmQnLLuCo9O/2mn739W o//6+2yT2xwuiVI+dbX2gMpo7lomnISJB4cNAb9pZ4jk+nHxM4W+fLi8yHagzVSYpHwA CdCIo96kyyHRy2AXvLHBHvRTDT8fAQoYtq9OyjGp8iSBrhJceQ1BvRhb3a59JVP0Hnrl fK57/mxebRgW32EqNw1LnmXeaggEA0euddMcG5GlLcy2WU9P/XRkRCWRADnUT5k3eTND MHig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=9+tsLH0HPRKToP57pUXRrE8IgJT0qvaZcfNLjxEnTU0=; b=mp7MWN+nO+01wCtoIqiKblZAiiuKggE5XJD8YwDTfONveb5PHyFDg6a0Lvo3S9K8yI hGcT+GeQUxN/Sv08LlaL2bTNpySRvnTUdv1yXp/UOoBiFYDEtBszuoJOCf+k4SuLJ0yW iZJWuRN6sx5btcooMPIcdknEOwHZjUH+mIixvn0Q+eGe0CpQOJBtY8a1KpXyCdCnXvlp C3zTi0jsF0nvFs0uhUtqToz5hhnCuyb1uW6W7ev9wYkV/tRd5konWTvYnWcBeNfwsUut MBOMGYBp35B573YGgodhLlyN6v537KFGSgClct1I+ts/N4DIFpJSmJ0guSvMi3RXCKTt AFZw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c71si5473733pfb.138.2019.04.02.05.10.50; Tue, 02 Apr 2019 05:11:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730833AbfDBMD1 (ORCPT + 99 others); Tue, 2 Apr 2019 08:03:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56510 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726903AbfDBMD1 (ORCPT ); Tue, 2 Apr 2019 08:03:27 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6DFDB5F72C; Tue, 2 Apr 2019 12:03:27 +0000 (UTC) Received: from dhcp-128-65.nay.redhat.com (ovpn-12-98.pek2.redhat.com [10.72.12.98]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9AD0A60BEC; Tue, 2 Apr 2019 12:03:23 +0000 (UTC) Date: Tue, 2 Apr 2019 20:03:19 +0800 From: Dave Young To: Junichi Nomura Cc: Borislav Petkov , "bhe@redhat.com" , "fanc.fnst@cn.fujitsu.com" , "kasong@redhat.com" , "x86@kernel.org" , "kexec@lists.infradead.org" , "linux-kernel@vger.kernel.org" Subject: Re: [PATCH v2] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel Message-ID: <20190402120319.GA7605@dhcp-128-65.nay.redhat.com> References: <20190325122302.GC13160@dhcp-128-65.nay.redhat.com> <20190325123229.GL12016@zn.tnic> <20190325231000.GA9184@jeru.linux.bs1.fc.nec.co.jp> <20190326135714.GG1867@zn.tnic> <20190327014852.GA3659@MiWiFi-R3L-srv> <73322ba9-e436-68db-7863-afd31607d969@ce.jp.nec.com> <20190328064343.GA1877@MiWiFi-R3L-srv> <20190328074337.GA9470@jeru.linux.bs1.fc.nec.co.jp> <20190328155256.GP22720@zn.tnic> <20190401000837.GA5170@jeru.linux.bs1.fc.nec.co.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190401000837.GA5170@jeru.linux.bs1.fc.nec.co.jp> User-Agent: Mutt/1.11.3 (2019-02-01) X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 02 Apr 2019 12:03:27 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 04/01/19 at 12:08am, Junichi Nomura wrote: > Commit 3a63f70bf4c3a ("x86/boot: Early parse RSDP and save it in > boot_params") broke kexec boot on EFI systems. efi_get_rsdp_addr() > in the early parsing code tries to search RSDP from EFI table but > that will crash because the table address is virtual when the kernel > was booted by kexec. > > In the case of kexec, physical address of EFI tables is provided > via efi_setup_data in boot_params, which is set up by kexec(1). > > Factor out the table parsing code and use different pointers depending > on whether the kernel is booted by kexec or not. > > Fixes: 3a63f70bf4c3a ("x86/boot: Early parse RSDP and save it in boot_params") > Signed-off-by: Jun'ichi Nomura > Acked-by: Baoquan He > Cc: Chao Fan > Cc: Borislav Petkov > Cc: Dave Young > > -- > v2: Added comments above __efi_get_rsdp_addr() and kexec_get_rsdp_addr() > > diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c > --- a/arch/x86/boot/compressed/acpi.c > +++ b/arch/x86/boot/compressed/acpi.c > @@ -44,17 +44,112 @@ static acpi_physical_address get_acpi_rsdp(void) > return addr; > } > > -/* Search EFI system tables for RSDP. */ > -static acpi_physical_address efi_get_rsdp_addr(void) > +#ifdef CONFIG_EFI > +static unsigned long efi_get_kexec_setup_data_addr(void) > +{ > + struct setup_data *data; > + u64 pa_data; > + > + pa_data = boot_params->hdr.setup_data; > + while (pa_data) { > + data = (struct setup_data *) pa_data; > + if (data->type == SETUP_EFI) > + return pa_data + sizeof(struct setup_data); > + pa_data = data->next; > + } > + return 0; > +} > + > +/* > + * Search EFI system tables for RSDP. If both ACPI_20_TABLE_GUID and > + * ACPI_TABLE_GUID are found, take the former, which has more features. > + */ > +static acpi_physical_address > +__efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables, > + bool efi_64) > { > acpi_physical_address rsdp_addr = 0; > + int i; > + > + /* Get EFI tables from systab. */ > + for (i = 0; i < nr_tables; i++) { > + acpi_physical_address table; > + efi_guid_t guid; > + > + if (efi_64) { > + efi_config_table_64_t *tbl = (efi_config_table_64_t *) config_tables + i; > + > + guid = tbl->guid; > + table = tbl->table; > + > + if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) { > + debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n"); > + return 0; > + } > + } else { > + efi_config_table_32_t *tbl = (efi_config_table_32_t *) config_tables + i; > > + guid = tbl->guid; > + table = tbl->table; > + } > + > + if (!(efi_guidcmp(guid, ACPI_TABLE_GUID))) > + rsdp_addr = table; > + else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID))) > + return table; > + } > + > + return rsdp_addr; > +} > +#endif > + > +/* > + * EFI/kexec support is only added for 64bit. So we don't have to > + * care 32bit case. > + */ > +static acpi_physical_address kexec_get_rsdp_addr(void) > +{ > #ifdef CONFIG_EFI > - unsigned long systab, systab_tables, config_tables; > + efi_system_table_64_t *systab; > + struct efi_setup_data *esd; > + struct efi_info *ei; > + char *sig; > + > + esd = (struct efi_setup_data *) efi_get_kexec_setup_data_addr(); > + if (!esd) > + return 0; > + > + if (!esd->tables) { > + debug_putstr("Wrong kexec SETUP_EFI data.\n"); > + return 0; > + } > + > + ei = &boot_params->efi_info; > + sig = (char *)&ei->efi_loader_signature; > + if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) { > + debug_putstr("Wrong kexec EFI loader signature.\n"); > + return 0; > + } > + > + /* Get systab from boot params. */ > + systab = (efi_system_table_64_t *) (ei->efi_systab | ((__u64)ei->efi_systab_hi << 32)); > + if (!systab) > + error("EFI system table not found in kexec boot_params."); > + > + return __efi_get_rsdp_addr((unsigned long) esd->tables, > + systab->nr_tables, true); > +#else > + return 0; > +#endif > +} > + > +static acpi_physical_address efi_get_rsdp_addr(void) > +{ > +#ifdef CONFIG_EFI > + unsigned long systab, config_tables; > unsigned int nr_tables; > struct efi_info *ei; > bool efi_64; > - int size, i; > char *sig; > > ei = &boot_params->efi_info; > @@ -88,49 +183,20 @@ static acpi_physical_address efi_get_rsdp_addr(void) > > config_tables = stbl->tables; > nr_tables = stbl->nr_tables; > - size = sizeof(efi_config_table_64_t); > } else { > efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab; > > config_tables = stbl->tables; > nr_tables = stbl->nr_tables; > - size = sizeof(efi_config_table_32_t); > } > > if (!config_tables) > error("EFI config tables not found."); > > - /* Get EFI tables from systab. */ > - for (i = 0; i < nr_tables; i++) { > - acpi_physical_address table; > - efi_guid_t guid; > - > - config_tables += size; > - > - if (efi_64) { > - efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables; > - > - guid = tbl->guid; > - table = tbl->table; > - > - if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) { > - debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n"); > - return 0; > - } > - } else { > - efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables; > - > - guid = tbl->guid; > - table = tbl->table; > - } > - > - if (!(efi_guidcmp(guid, ACPI_TABLE_GUID))) > - rsdp_addr = table; > - else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID))) > - return table; > - } > + return __efi_get_rsdp_addr(config_tables, nr_tables, efi_64); > +#else > + return 0; > #endif > - return rsdp_addr; > } > > static u8 compute_checksum(u8 *buffer, u32 length) > @@ -221,6 +287,9 @@ acpi_physical_address get_rsdp_addr(void) > pa = boot_params->acpi_rsdp_addr; > > if (!pa) > + pa = kexec_get_rsdp_addr(); > + > + if (!pa) > pa = efi_get_rsdp_addr(); > > if (!pa) I failed to kexec reboot on my laptop, kernel panics too quick, I'm not sure this is caused by your patch though. Actually there are something probably i915 changes break kexec, the above test is with "nomodeset" which should work. Let me do more testing and update here tomorrow. Thanks Dave