From patchwork Fri Jun 2 13:51:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 101251 Delivered-To: patch@linaro.org Received: by 10.182.202.35 with SMTP id kf3csp204800obc; Fri, 2 Jun 2017 06:54:48 -0700 (PDT) X-Received: by 10.99.109.129 with SMTP id i123mr7270782pgc.103.1496411688285; Fri, 02 Jun 2017 06:54:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496411688; cv=none; d=google.com; s=arc-20160816; b=KLwrOR8EwtFI3mAgK7SaQLpaDoFgjzlur9tfSXhxYqJXMGrGep3dCXVC3QpvLgOlSS TVhBNBfPuj610L0/YLVwZpgUY25yNll7xZv3RUaDUUG5h6SeheTJd6VcgVesQo1tziUE 9EZXJL0Ur4k6M3W8ET67ToCTrK/hfixnMkcic/EQNeZc+RYk3tLGTcF/xKX0r1aTZQgc VSqfJZYP9DAOvI+5xevZhscZUM3j38WbGjqJOY3IDsKgIRcCugkXjpeardyzu3AHbY2W 9bpjB3C5fdj3XA+dV6U38dsWrhdLF5u0baP9TmapCkWkukHyTzFmgflWSQ9Lve6IY7cy iZEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=baG0akEVxT7GSMq4qIZKElqQqgM3hP1fxGluFdFhTlM=; b=hW3r0uPcJNU3836pZk5TzWZZD0l8kSERkYiLW8fa+/Vv3uD3qRysxJqHQ8NklKmUZd r4IyuevGyFag12nbenZUnwXxSmvH6A4Dv+3hrYnwjAPgjsaU65d0i8vqE/IAQdSf2AF3 gtQW5MpTZgxljKWzLUO+qBGvxya+KAfQP3zUJQlOSLVL6UsD1DiDQR/IZZ32J+kCmPJ9 dYUsF68N3/xLPvsO8TGixCX64wq+chcw/tAcCEiTmyPJlbej9Uqqo3YThQGDF/g55Ntm q3raOwN3Em8PcZB2tsj3LPA89giL1SCUbqyz4QCetc8Qn2OoRIon3JcZgHgDwoJL9//y CBBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s80si23734996pfi.388.2017.06.02.06.54.48; Fri, 02 Jun 2017 06:54:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751425AbdFBNyr (ORCPT + 2 others); Fri, 2 Jun 2017 09:54:47 -0400 Received: from mail-wm0-f54.google.com ([74.125.82.54]:36947 "EHLO mail-wm0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751263AbdFBNyp (ORCPT ); Fri, 2 Jun 2017 09:54:45 -0400 Received: by mail-wm0-f54.google.com with SMTP id d127so27560081wmf.0 for ; Fri, 02 Jun 2017 06:54:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7OLj7Up4KJ5hHvntdum+L4A4rVuiVL1LxI7wkpXr2PU=; b=MoAYfnGbautzlZEy4CYgX0aRICYUxllZXweBTdOLWF+BClxzJkdZ38popxXOtyafFT 0cxJTpXpZIP9+DcbYR/e3cilsoH+awlaWBJp6wqvnmW5ihyAwNrPupi7rV5PDFd6Froo kl+bbV7rVK+8i+vce4M75ubDK79l+f8k8ENHo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7OLj7Up4KJ5hHvntdum+L4A4rVuiVL1LxI7wkpXr2PU=; b=SHAtstYvrpOALM+dWW4dNP+P8/BEv8MmHIpfH57y9bY7DmPsULbxn4/f5Wv8LIy7tg hoNVrPVI3vmK6tM1cfzysDGOL9GF7ZrSHsV5BERdA361ocazYN0eFrbgJ7ZdX5oJ1H3k vwiHWBjLwuakNos6Drk44pqrwh54fbu/Uwi+JyJDhuUn+GVZKGZjspruwxYVqtPM1q1H 16w+StllVmi7cvtBf+2a+PhUa4bNPpu5uA0r03Tlz8dtI5o+7kQPnK8GuTlZWsmEboA/ wHIIjN7sBmddjcT/rvguAd9hDxVeFhQUl7aKo4BiE3z9+eSdZ4VFUtAL3olJxZFyZGbQ jRcw== X-Gm-Message-State: AODbwcApu5PH0mJdCDjpIClAi8h4LWmX7A8NF1GFxOtddn+C/NAf8yNg c8j1m4oCxW/zXIirK4hccQ== X-Received: by 10.80.149.209 with SMTP id x17mr6047493eda.175.1496411683361; Fri, 02 Jun 2017 06:54:43 -0700 (PDT) Received: from localhost.localdomain ([105.151.155.95]) by smtp.gmail.com with ESMTPSA id g48sm9756076edc.8.2017.06.02.06.54.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Jun 2017 06:54:42 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Andy Lutomirski , Ard Biesheuvel , linux-kernel@vger.kernel.org, Borislav Petkov , Andy Lutomirski , Matt Fleming Subject: [PATCH 01/13] x86/efi: Clean up efi CR3 save/restore Date: Fri, 2 Jun 2017 13:51:55 +0000 Message-Id: <20170602135207.21708-2-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170602135207.21708-1-ard.biesheuvel@linaro.org> References: <20170602135207.21708-1-ard.biesheuvel@linaro.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Andy Lutomirski efi_call_phys_prolog() used to return a "pgd_t *" that meant one of three different things depending on kernel and system configuration. Clean it up so it uses a union and is more explicit about what's going on. Signed-off-by: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Andy Lutomirski Cc: Ingo Molnar Signed-off-by: Matt Fleming Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/efi.h | 17 +++++++++++++++-- arch/x86/platform/efi/efi.c | 6 +++--- arch/x86/platform/efi/efi_32.c | 12 ++++++------ arch/x86/platform/efi/efi_64.c | 22 ++++++++++++---------- 4 files changed, 36 insertions(+), 21 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 2f77bcefe6b4..6d74cc3802e6 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -111,11 +111,24 @@ extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size, #endif /* CONFIG_X86_32 */ +union efi_saved_pgd { + /* + * If !EFI_OLD_MEMMAP or we're 32-bit, this is a verbatim saved CR3 + * value. + */ + unsigned long cr3; + +#ifdef CONFIG_X86_64 + /* If EFI_OLD_MEMMAP, this is a kmalloced copy of the pgd. */ + pgd_t *pgd; +#endif +}; + extern struct efi_scratch efi_scratch; extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable); extern int __init efi_memblock_x86_reserve_range(void); -extern pgd_t * __init efi_call_phys_prolog(void); -extern void __init efi_call_phys_epilog(pgd_t *save_pgd); +extern union efi_saved_pgd __init efi_call_phys_prolog(void); +extern void __init efi_call_phys_epilog(union efi_saved_pgd saved_pgd); extern void __init efi_print_memmap(void); extern void __init efi_memory_uc(u64 addr, unsigned long size); extern void __init efi_map_region(efi_memory_desc_t *md); diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 7e76a4d8304b..dc2da5e2c7e4 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -82,9 +82,9 @@ static efi_status_t __init phys_efi_set_virtual_address_map( { efi_status_t status; unsigned long flags; - pgd_t *save_pgd; + union efi_saved_pgd saved_pgd; - save_pgd = efi_call_phys_prolog(); + saved_pgd = efi_call_phys_prolog(); /* Disable interrupts around EFI calls: */ local_irq_save(flags); @@ -93,7 +93,7 @@ static efi_status_t __init phys_efi_set_virtual_address_map( descriptor_version, virtual_map); local_irq_restore(flags); - efi_call_phys_epilog(save_pgd); + efi_call_phys_epilog(saved_pgd); return status; } diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index 3481268da3d0..403a987d06c7 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -58,13 +58,13 @@ void __init efi_map_region(efi_memory_desc_t *md) void __init efi_map_region_fixed(efi_memory_desc_t *md) {} void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} -pgd_t * __init efi_call_phys_prolog(void) +union efi_saved_pgd __init efi_call_phys_prolog(void) { struct desc_ptr gdt_descr; - pgd_t *save_pgd; + union efi_saved_pgd saved_pgd; /* Current pgd is swapper_pg_dir, we'll restore it later: */ - save_pgd = swapper_pg_dir; + saved_pgd.cr3 = __pa(swapper_pg_dir); load_cr3(initial_page_table); __flush_tlb_all(); @@ -72,10 +72,10 @@ pgd_t * __init efi_call_phys_prolog(void) gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); - return save_pgd; + return saved_pgd; } -void __init efi_call_phys_epilog(pgd_t *save_pgd) +void __init efi_call_phys_epilog(union efi_saved_pgd saved_pgd) { struct desc_ptr gdt_descr; @@ -83,7 +83,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); - load_cr3(save_pgd); + write_cr3(saved_pgd.cr3); __flush_tlb_all(); } diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index c488625c9712..6fbf6c47e603 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -69,16 +69,16 @@ static void __init early_code_mapping_set_exec(int executable) } } -pgd_t * __init efi_call_phys_prolog(void) +union efi_saved_pgd __init efi_call_phys_prolog(void) { unsigned long vaddress; - pgd_t *save_pgd; + union efi_saved_pgd saved_pgd; int pgd; int n_pgds; if (!efi_enabled(EFI_OLD_MEMMAP)) { - save_pgd = (pgd_t *)read_cr3(); + saved_pgd.cr3 = read_cr3(); write_cr3((unsigned long)efi_scratch.efi_pgt); goto out; } @@ -86,20 +86,21 @@ pgd_t * __init efi_call_phys_prolog(void) early_code_mapping_set_exec(1); n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); - save_pgd = kmalloc_array(n_pgds, sizeof(*save_pgd), GFP_KERNEL); + saved_pgd.pgd = kmalloc_array(n_pgds, sizeof(*saved_pgd.pgd), + GFP_KERNEL); for (pgd = 0; pgd < n_pgds; pgd++) { - save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE); + saved_pgd.pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE); vaddress = (unsigned long)__va(pgd * PGDIR_SIZE); set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); } out: __flush_tlb_all(); - return save_pgd; + return saved_pgd; } -void __init efi_call_phys_epilog(pgd_t *save_pgd) +void __init efi_call_phys_epilog(union efi_saved_pgd saved_pgd) { /* * After the lock is released, the original page table is restored. @@ -108,7 +109,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) int nr_pgds; if (!efi_enabled(EFI_OLD_MEMMAP)) { - write_cr3((unsigned long)save_pgd); + write_cr3(saved_pgd.cr3); __flush_tlb_all(); return; } @@ -116,9 +117,10 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); for (pgd_idx = 0; pgd_idx < nr_pgds; pgd_idx++) - set_pgd(pgd_offset_k(pgd_idx * PGDIR_SIZE), save_pgd[pgd_idx]); + set_pgd(pgd_offset_k(pgd_idx * PGDIR_SIZE), + saved_pgd.pgd[pgd_idx]); - kfree(save_pgd); + kfree(saved_pgd.pgd); __flush_tlb_all(); early_code_mapping_set_exec(0);