From patchwork Fri Jun 3 15:03:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 847392 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.3) with ESMTP id p53F3ghQ028473 for ; Fri, 3 Jun 2011 15:03:42 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754856Ab1FCPDj (ORCPT ); Fri, 3 Jun 2011 11:03:39 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:37774 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753657Ab1FCPDj (ORCPT ); Fri, 3 Jun 2011 11:03:39 -0400 Received: by wya21 with SMTP id 21so1457214wya.19 for ; Fri, 03 Jun 2011 08:03:37 -0700 (PDT) Received: by 10.216.232.208 with SMTP id n58mr7367749weq.56.1307113417712; Fri, 03 Jun 2011 08:03:37 -0700 (PDT) Received: from [127.0.0.1] (host198-39-dynamic.245-95-r.retail.telecomitalia.it [95.245.39.198]) by mx.google.com with ESMTPS id k70sm893270weq.30.2011.06.03.08.03.35 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 03 Jun 2011 08:03:36 -0700 (PDT) Subject: [PATCH v3 2/8] ARM: KVM: Hypervisor identity mapping To: catalin.marinas@arm.com, android-virt@lists.cs.columbia.edu From: Christoffer Dall Cc: s.raho@virtualopensystems.com, a.motakis@virtualopensystems.com, c.dall@virtualopensystems.com, kvm@vger.kernel.org, a.costa@virtualopensystems.com Date: Fri, 03 Jun 2011 17:03:28 +0200 Message-ID: <20110603150327.17011.94205.stgit@ubuntu> In-Reply-To: <20110603150318.17011.82777.stgit@ubuntu> References: <20110603150318.17011.82777.stgit@ubuntu> User-Agent: StGit/0.15 MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 03 Jun 2011 15:03:43 +0000 (UTC) Adds support in the identity mapping feature that allows KVM to setup identity mapping for the Hyp mode with the AP[1] bit set as required by the specification and also supports freeing created sub pmd's after finished use. --- arch/arm/include/asm/pgtable-3level-hwdef.h | 1 + arch/arm/include/asm/pgtable.h | 5 +++ arch/arm/mm/idmap.c | 47 ++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 1 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/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h index 6c0fb9b..9142208 100644 --- a/arch/arm/include/asm/pgtable-3level-hwdef.h +++ b/arch/arm/include/asm/pgtable-3level-hwdef.h @@ -48,6 +48,7 @@ #endif #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/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 110f6f4..56081c0 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -403,6 +403,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) void identity_mapping_add(pgd_t *, unsigned long, unsigned long); void identity_mapping_del(pgd_t *, unsigned long, unsigned long); +#ifdef CONFIG_KVM +void hyp_identity_mapping_add(pgd_t *, unsigned long, unsigned long); +void hyp_identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end); +#endif + #endif /* !__ASSEMBLY__ */ #endif /* CONFIG_MMU */ diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 834b803..66125d5 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -33,11 +33,16 @@ static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, flush_pmd_entry(pmd); } -void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) +static void __identity_mapping_add(pgd_t *pgd, unsigned long addr, + unsigned long end, bool hyp_mapping) { unsigned long prot, next; prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; + + if (hyp_mapping) + prot |= PMD_SECT_AP1; + if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) prot |= PMD_BIT4; @@ -47,6 +52,12 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) } while (addr = next, addr < end); } +void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) +{ + __identity_mapping_add(pgd, addr, end, false); +} + + #ifdef CONFIG_SMP static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end) { @@ -69,6 +80,40 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) } #endif +#ifdef CONFIG_KVM +void hyp_identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) +{ + __identity_mapping_add(pgd, addr, end, true); +} + +static void hyp_idmap_del_pmd(pgd_t *pgd, unsigned long addr) +{ + pmd_t *pmd; + + pmd = pmd_offset(pgd, addr); + pmd_free(NULL, pmd); +} + +/* + * This version actually frees the underlying pmds for all pgds in range and + * clear the pgds themselves afterwards. + */ +void hyp_identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) +{ + unsigned long next; + pgd_t *next_pgd; + + do { + next = pgd_addr_end(addr, end); + next_pgd = pgd + pgd_index(addr); + if (!pgd_none_or_clear_bad(next_pgd)) { + hyp_idmap_del_pmd(next_pgd, addr); + pgd_clear(next_pgd); + } + } while (addr = next, addr < end); +} +#endif + /* * In order to soft-boot, we need to insert a 1:1 mapping in place of * the user-mode pages. This will then ensure that we have predictable