Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2178489imu; Thu, 29 Nov 2018 00:18:29 -0800 (PST) X-Google-Smtp-Source: AFSGD/V/myMGsbUb+mMftUAsxM/dT7UZ4X7Sxw3f7YyoaGTVOC2d9iTeXIq8oA5xAfuqtKoEMnAa X-Received: by 2002:a65:610d:: with SMTP id z13mr416539pgu.427.1543479509779; Thu, 29 Nov 2018 00:18:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543479509; cv=none; d=google.com; s=arc-20160816; b=qIENV4YcD24D/qYe+NzljrqstQPLavlLhoweiLXjDVgHXoMiYFBn/bjvQ4uXttN0Ms b8RiK+cQ8s/13atwP8axnSFse1eBVcCGcXIe60CS8S7uc8wU6eazxQhm4MZzPqQpbaa+ XYLiNWC+dHkIAa21hfg8O0UMRj+yL04zxXutTowBGkkqv9Du0s4bhwOas6eLmJwqmHJZ mF4AiAlPuA19xQ6dxwIjDZzIvgTFHqCdJDeP0wuEvudgt6essA3vpkZ13DOSfvBr7i9f nbkjSlMZcTY6CeV23VAIBBopqFnrMzsticF9OyQpPJzPLP+wKG0M7dbOynescPCD4/UZ gN8g== 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=9pRzmNdXOo7pS7PtWsjy3UIwRaNsrjAI0hm54+Ri4fM=; b=NkzJyUP85o5zUuFuRo/imJGcWcBLB8FU4Wp5bdMsU6M6M0GUE3/UNrvEJEKSUlCs/L ouhfIC9yvktcL6WAkc56dJUpw1SuZPR/lwMBFRuA2ubSY6PY7gdONxfDhbmYUHcZgr1p inREoGhwPOgvyIpsqFstVYOJP7p3AGKZ2jM7+NfQ9tBefCykJt4o35QQrvvdzMkRiZ+a RU32dKSc7B53QXe1OGskWJwSb9YZa087CEbhA5ec5sHlL5kIQxc+IpTyfMdQjOFuKS+7 R0L89EWJlAl51uLunBw/mZlduAbkrvLdRZ372RcoI4dsfBS3Sd7zCZmfDKFSq7rdJiM0 krIg== 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 z123si1459230pfb.104.2018.11.29.00.18.15; Thu, 29 Nov 2018 00:18:29 -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 S1727861AbeK2TVc (ORCPT + 99 others); Thu, 29 Nov 2018 14:21:32 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:27144 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727490AbeK2TVb (ORCPT ); Thu, 29 Nov 2018 14:21:31 -0500 X-IronPort-AV: E=Sophos;i="5.56,293,1539619200"; d="scan'208";a="48821857" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 29 Nov 2018 16:16:57 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id CA0A84B6ED56; Thu, 29 Nov 2018 16:16:56 +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; Thu, 29 Nov 2018 16:17:02 +0800 From: Chao Fan To: , , , , , , , , CC: , , Subject: [PATCH v12 3/5] x86/boot: Add bios_get_rsdp_addr() to search RSDP in memory Date: Thu, 29 Nov 2018 16:16:29 +0800 Message-ID: <20181129081631.11139-4-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181129081631.11139-1-fanc.fnst@cn.fujitsu.com> References: <20181129081631.11139-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: CA0A84B6ED56.A8FAE 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 To fix the conflict between KASLR and memory-hotremove, memory information in SRAT table is necessary. So RSDP and SRAT table should be parsed. When booting form KEXEC/EFI/BIOS, the methods to compute RSDP pointer 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/acpitb.c | 85 +++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/arch/x86/boot/compressed/acpitb.c b/arch/x86/boot/compressed/acpitb.c index c43546648638..82d27c4b8978 100644 --- a/arch/x86/boot/compressed/acpitb.c +++ b/arch/x86/boot/compressed/acpitb.c @@ -110,3 +110,88 @@ static acpi_physical_address efi_get_rsdp_addr(void) return rsdp_addr; #endif } + +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; +} + +/* Used to search RSDP physical 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; + *(u32 *)(void *)&address = *(u16 *)(void *)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 (acpi_physical_address)address; + } + } + + table_ptr = (u8 *)ACPI_HI_RSDP_WINDOW_BASE; + rsdp = scan_mem_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + + /* Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ + if (rsdp) { + address = (u32)(ACPI_HI_RSDP_WINDOW_BASE + + ACPI_PTR_DIFF(rsdp, table_ptr)); + return (acpi_physical_address)address; + } +} -- 2.19.1