Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3118007imu; Sun, 6 Jan 2019 19:26:18 -0800 (PST) X-Google-Smtp-Source: ALg8bN6glPdzQ/ZmH+/t+bSe2HX17iHUswk2fLLmaRNDq0gm1i3La/KWqzg0HT1LmcsHngTHDfur X-Received: by 2002:a65:4b82:: with SMTP id t2mr9584778pgq.189.1546831578246; Sun, 06 Jan 2019 19:26:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546831578; cv=none; d=google.com; s=arc-20160816; b=FE6BuQsPXMQa/pTncrxjt8Ju63lXbQoMIi1bvOHLhuhRiPDQb+ZaqdKvtHxjwS54et yO9/swKNOi6CL+JFnxpStZJqed+m+UtnOWAPaoEumunwfwxPRnIYYO07cGQeW6oMEima WOeJtASyeRMaPmUT/ukW9kA6mtYKvYpqBTB8MButDEd0kq/+K/ZWCOXmATB5U0EM/iOn B07m42KWKFbKYZB9uv7H49WCuOgV8DXJ+/ULG4fMO3EWqi07kR75DZeEIsGxoRI59/jp AvJc3dFT0DQX75vAm4PPrS8/TFmNTXPgkPsso8JHpgBMwQsEAcR7eCsCvLTkpeMbLwh+ +o5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=/fCysNhubq90Vo68I7pjiI53kQ5F92aFWEWj5S4VPbs=; b=C/DEGbXMNRO8OdFqznDM6Yy8mMPJGbe2fJ1BjalPGM9CTUiVWJXnqqaZCj2Jsih/F9 195BCnBmSxR/Jt+kQkx2p/WhdEJlKLvk8U3H8NMjwhDaOS7x6Gj6qr6bb2EBNZCjmWRJ yGlBcyHt+c02BE+JclvMdlJtTTgSVCUOFd3wrTYLnhXESTMcVBcXkcVt2A9Rph6RNi72 1mkosIA5l9zJBA8JViR1qsIK8oMTb9I74jlhNMAHc8XqFOylVYkxy01fZSAn98UMfL5x qxT6UKp+eA6oXvH/nm98CeEYI+Ay/MbhYM0tOugYrwIyuKiZDozOCt9nb4ME3lu3+oQr d++w== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u21si60856504pgg.463.2019.01.06.19.26.03; Sun, 06 Jan 2019 19:26:18 -0800 (PST) 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726500AbfAGDYH (ORCPT + 99 others); Sun, 6 Jan 2019 22:24:07 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:54897 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726371AbfAGDXs (ORCPT ); Sun, 6 Jan 2019 22:23:48 -0500 X-IronPort-AV: E=Sophos;i="5.56,449,1539619200"; d="scan'208";a="51438964" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 07 Jan 2019 11:23:45 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 441D04B7EC72; Mon, 7 Jan 2019 11:23:40 +0800 (CST) Received: from localhost.local (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 7 Jan 2019 11:23:45 +0800 From: Chao Fan To: , , , , , , , , CC: , , Subject: [PATCH v15 4/6] x86/boot: Introduce bios_get_rsdp_addr() to search RSDP in memory Date: Mon, 7 Jan 2019 11:22:41 +0800 Message-ID: <20190107032243.25324-5-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107032243.25324-1-fanc.fnst@cn.fujitsu.com> References: <20190107032243.25324-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: 441D04B7EC72.A634B X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com X-Spam-Status: No Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Memory information in SRAT table is necessary to fix the conflict between KASLR and memory-hotremove. So RSDP and SRAT should be parsed. When booting form KEXEC/EFI/BIOS, the methods to compute RSDP are different. When booting from BIOS, there is no variable who can point to RSDP directly, so scan memory for the RSDP and verify RSDP by signature and checksum. Signed-off-by: Chao Fan --- arch/x86/boot/compressed/acpi.c | 86 +++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c index f74c5d033d79..e9dd84f459ed 100644 --- a/arch/x86/boot/compressed/acpi.c +++ b/arch/x86/boot/compressed/acpi.c @@ -111,3 +111,89 @@ static acpi_physical_address efi_get_rsdp_addr(void) #endif return rsdp_addr; } + +static u8 compute_checksum(u8 *buffer, u32 length) +{ + u8 *end = buffer + length; + u8 sum = 0; + + while (buffer < end) + sum += *(buffer++); + + return sum; +} + +/* Search a block of memory for the RSDP signature. */ +static u8 *scan_mem_for_rsdp(u8 *start, u32 length) +{ + struct acpi_table_rsdp *rsdp; + u8 *address; + u8 *end; + + end = start + length; + + /* Search from given start address for the requested length */ + for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) { + /* + * Both RSDP signature and checksum must be correct. + * Note: Sometimes there exists more than one RSDP in memory; + * the valid RSDP has a valid checksum, all others have an + * invalid checksum. + */ + rsdp = (struct acpi_table_rsdp *)address; + + /* BAD Signature */ + if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) + continue; + + /* Check the standard checksum */ + if (compute_checksum((u8 *)rsdp, ACPI_RSDP_CHECKSUM_LENGTH)) + continue; + + /* Check extended checksum if table version >= 2 */ + if ((rsdp->revision >= 2) && + (compute_checksum((u8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH))) + continue; + + /* Signature and checksum valid, we have found a real RSDP */ + return address; + } + return NULL; +} + +/* Search RSDP address, based on acpi_find_root_pointer(). */ +static acpi_physical_address bios_get_rsdp_addr(void) +{ + u8 *table_ptr; + u32 address; + u8 *rsdp; + + /* Get the location of the Extended BIOS Data Area (EBDA) */ + table_ptr = (u8 *)ACPI_EBDA_PTR_LOCATION; + address = *(u16 *)table_ptr; + address <<= 4; + table_ptr = (u8 *)(long)address; + + /* + * Search EBDA paragraphs (EBDA is required to be a minimum of + * 1K length) + */ + if (address > 0x400) { + rsdp = scan_mem_for_rsdp(table_ptr, ACPI_EBDA_WINDOW_SIZE); + if (rsdp) { + address += (u32)ACPI_PTR_DIFF(rsdp, table_ptr); + return address; + } + } + + /* Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ + table_ptr = (u8 *)ACPI_HI_RSDP_WINDOW_BASE; + rsdp = scan_mem_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + + if (rsdp) { + address = (u32)(ACPI_HI_RSDP_WINDOW_BASE + + ACPI_PTR_DIFF(rsdp, table_ptr)); + return address; + } + return 0; +} -- 2.20.1