From patchwork Tue Jan 8 18:38:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 1947101 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 4CF383FED4 for ; Tue, 8 Jan 2013 18:38:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756940Ab3AHSiw (ORCPT ); Tue, 8 Jan 2013 13:38:52 -0500 Received: from mail-vb0-f48.google.com ([209.85.212.48]:55496 "EHLO mail-vb0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756933Ab3AHSiv (ORCPT ); Tue, 8 Jan 2013 13:38:51 -0500 Received: by mail-vb0-f48.google.com with SMTP id fc21so717244vbb.7 for ; Tue, 08 Jan 2013 10:38:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:subject:to:from:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-type :content-transfer-encoding:x-gm-message-state; bh=1/9LW5fddgH37F3Dm4LMGHOfOeQ7wFczGvdvlz9ru58=; b=ImXqbC1tMYBYKz3yF7wx+8hP7vVRgIFXZNh9y1WJioVlO/L4gz6080Dv6zgCFBT6kJ kfxE/DWdpznESrJQApjwLCBYuk+tNHJxjhnniOAxvQM3YA2+NiX7D2noLof2jjMAiDFo fiYITN3q+j7sucN7yjrhW86N+UFjFLuSkMngFtqQJVywiKdTGcxI2ZYFp0gj2Gkocum4 Q5Sa6BRzg3J4I1eVBf75H8V+NzdpN9z1PKsuq1lBTyEPoR8m/G67N9x42fwMT8yBabqA yjYEXxwrZntnNNwj2snxiH9PTw2ajsVmpFigE4faC61KG85s3KoUBBOlr4lyvLQ/YIo8 ABgg== X-Received: by 10.52.67.45 with SMTP id k13mr79710170vdt.9.1357670330747; Tue, 08 Jan 2013 10:38:50 -0800 (PST) Received: from [127.0.1.1] (pool-72-80-83-148.nycmny.fios.verizon.net. [72.80.83.148]) by mx.google.com with ESMTPS id w4sm44852733vdj.21.2013.01.08.10.38.49 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 08 Jan 2013 10:38:50 -0800 (PST) Subject: [PATCH v5 02/14] ARM: Section based HYP idmap To: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu From: Christoffer Dall Cc: Marc Zyngier , Marcelo Tosatti , Will Deacon Date: Tue, 08 Jan 2013 13:38:48 -0500 Message-ID: <20130108183848.46302.77369.stgit@ubuntu> In-Reply-To: <20130108183811.46302.58543.stgit@ubuntu> References: <20130108183811.46302.58543.stgit@ubuntu> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQnBO/LDUZ/IeBELHI4A5wP47CUCgcA5zqr4EAI6FVleb0xLvQbFu3k5XnjGQ5SItb17Z6ZH Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a method (hyp_idmap_setup) to populate a hyp pgd with an identity mapping of the code contained in the .hyp.idmap.text section. Offer a method to drop this identity mapping through hyp_idmap_teardown. Make all the above depend on CONFIG_ARM_VIRT_EXT and CONFIG_ARM_LPAE. Cc: Will Deacon Reviewed-by: Marcelo Tosatti Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm/include/asm/idmap.h | 1 + arch/arm/include/asm/pgtable-3level-hwdef.h | 1 + arch/arm/kernel/vmlinux.lds.S | 6 +++ arch/arm/mm/idmap.c | 54 ++++++++++++++++++++++----- 4 files changed, 50 insertions(+), 12 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe kvm" 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/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h index bf863ed..1a66f907 100644 --- a/arch/arm/include/asm/idmap.h +++ b/arch/arm/include/asm/idmap.h @@ -8,6 +8,7 @@ #define __idmap __section(.idmap.text) noinline notrace extern pgd_t *idmap_pgd; +extern pgd_t *hyp_pgd; void setup_mm_for_reboot(void); diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h index d795282..a2d404e 100644 --- a/arch/arm/include/asm/pgtable-3level-hwdef.h +++ b/arch/arm/include/asm/pgtable-3level-hwdef.h @@ -44,6 +44,7 @@ #define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) #define PMD_SECT_AP_WRITE (_AT(pmdval_t, 0)) #define PMD_SECT_AP_READ (_AT(pmdval_t, 0)) +#define PMD_SECT_AP1 (_AT(pmdval_t, 1) << 6) #define PMD_SECT_TEX(x) (_AT(pmdval_t, 0)) /* diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 11c1785..b571484 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -19,7 +19,11 @@ ALIGN_FUNCTION(); \ VMLINUX_SYMBOL(__idmap_text_start) = .; \ *(.idmap.text) \ - VMLINUX_SYMBOL(__idmap_text_end) = .; + VMLINUX_SYMBOL(__idmap_text_end) = .; \ + ALIGN_FUNCTION(); \ + VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ + *(.hyp.idmap.text) \ + VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; #ifdef CONFIG_HOTPLUG_CPU #define ARM_CPU_DISCARD(x) diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 99db769..d9213a5 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -1,4 +1,6 @@ +#include #include +#include #include #include @@ -6,6 +8,7 @@ #include #include #include +#include pgd_t *idmap_pgd; @@ -59,11 +62,20 @@ static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end, } while (pud++, addr = next, addr != end); } -static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) +static void identity_mapping_add(pgd_t *pgd, const char *text_start, + const char *text_end, unsigned long prot) { - unsigned long prot, next; + unsigned long addr, end; + unsigned long next; + + addr = virt_to_phys(text_start); + end = virt_to_phys(text_end); + + pr_info("Setting up static %sidentity map for 0x%llx - 0x%llx\n", + prot ? "HYP " : "", + (long long)addr, (long long)end); + prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; - prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) prot |= PMD_BIT4; @@ -74,28 +86,48 @@ static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long e } while (pgd++, addr = next, addr != end); } +#ifdef CONFIG_ARM_VIRT_EXT +pgd_t *hyp_pgd; + +extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; + +static int __init init_static_idmap_hyp(void) +{ + hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); + if (!hyp_pgd) + return -ENOMEM; + + identity_mapping_add(hyp_pgd, __hyp_idmap_text_start, + __hyp_idmap_text_end, PMD_SECT_AP1); + + return 0; +} +#else +static int __init init_static_idmap_hyp(void) +{ + return 0; +} +#endif + extern char __idmap_text_start[], __idmap_text_end[]; static int __init init_static_idmap(void) { - phys_addr_t idmap_start, idmap_end; + int ret; idmap_pgd = pgd_alloc(&init_mm); if (!idmap_pgd) return -ENOMEM; - /* Add an identity mapping for the physical address of the section. */ - idmap_start = virt_to_phys((void *)__idmap_text_start); - idmap_end = virt_to_phys((void *)__idmap_text_end); + identity_mapping_add(idmap_pgd, __idmap_text_start, + __idmap_text_end, 0); - pr_info("Setting up static identity map for 0x%llx - 0x%llx\n", - (long long)idmap_start, (long long)idmap_end); - identity_mapping_add(idmap_pgd, idmap_start, idmap_end); + ret = init_static_idmap_hyp(); /* Flush L1 for the hardware to see this page table content */ flush_cache_louis(); - return 0; + return ret; } early_initcall(init_static_idmap);