linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 03/30] arm64: KVM: HYP mode idmap support
Date: Tue, 26 Mar 2013 17:00:58 +0000	[thread overview]
Message-ID: <1364317285-20937-4-git-send-email-marc.zyngier@arm.com> (raw)
In-Reply-To: <1364317285-20937-1-git-send-email-marc.zyngier@arm.com>

Add the necessary infrastructure for identity-mapped HYP page
tables. Idmap-ed code must be in the ".hyp.idmap.text" linker
section.

The rest of the HYP ends up in ".hyp.text".

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/vmlinux.lds.S |  10 +++
 arch/arm64/kvm/idmap.c          | 141 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/idmap.h          |   8 +++
 3 files changed, 159 insertions(+)
 create mode 100644 arch/arm64/kvm/idmap.c
 create mode 100644 arch/arm64/kvm/idmap.h

diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 3fae2be..51b87c3 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -17,6 +17,15 @@ ENTRY(stext)
 
 jiffies = jiffies_64;
 
+#define HYPERVISOR_TEXT					\
+	ALIGN_FUNCTION();				\
+	VMLINUX_SYMBOL(__hyp_idmap_text_start) = .;	\
+	*(.hyp.idmap.text)				\
+	VMLINUX_SYMBOL(__hyp_idmap_text_end) = .;	\
+	VMLINUX_SYMBOL(__hyp_text_start) = .;		\
+	*(.hyp.text)					\
+	VMLINUX_SYMBOL(__hyp_text_end) = .;
+
 SECTIONS
 {
 	/*
@@ -49,6 +58,7 @@ SECTIONS
 			TEXT_TEXT
 			SCHED_TEXT
 			LOCK_TEXT
+			HYPERVISOR_TEXT
 			*(.fixup)
 			*(.gnu.warning)
 		. = ALIGN(16);
diff --git a/arch/arm64/kvm/idmap.c b/arch/arm64/kvm/idmap.c
new file mode 100644
index 0000000..68a55d4
--- /dev/null
+++ b/arch/arm64/kvm/idmap.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2012 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <asm/cputype.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/virt.h>
+
+#include "idmap.h"
+
+pgd_t *hyp_pgd;
+
+/*
+ * We always use a 2-level mapping for hyp-idmap:
+ * - Section mapped for 4kB pages
+ * - Page mapped for 64kB pages
+ */
+#ifdef CONFIG_ARM64_64K_PAGES
+static void idmap_add_pte(pmd_t *pmd, unsigned long addr, unsigned long end)
+{
+	struct page *page;
+	pte_t *pte;
+	unsigned long next;
+
+	if (pmd_none(*pmd)) {
+		pte = pte_alloc_one_kernel(NULL, addr);
+		if (!pte) {
+			pr_warning("Failed to allocate identity pte.\n");
+			return;
+		}
+		pmd_populate_kernel(NULL, pmd, pte);
+	}
+
+	pte = pte_offset_kernel(pmd, addr);
+
+	do {
+		page = phys_to_page(addr);
+		next = (addr & PAGE_MASK) + PAGE_SIZE;
+		set_pte(pte, mk_pte(page, PAGE_HYP));
+	} while (pte++, addr = next, addr < end);
+}
+#else
+#define HYP_SECT_PROT	(PMD_TYPE_SECT | PMD_SECT_AF | \
+			 PMD_ATTRINDX(MT_NORMAL) | PMD_HYP)
+
+/*
+ * For 4kB pages, we use a section to perform the identity mapping,
+ * hence the direct call to __pmd_populate().
+ */
+static void idmap_add_pte(pmd_t *pmd, unsigned long addr, unsigned long end)
+{
+	__pmd_populate(pmd, addr & PMD_MASK, HYP_SECT_PROT);
+}
+#endif
+
+static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end)
+{
+	pmd_t *pmd;
+	unsigned long next;
+
+	if (pud_none_or_clear_bad(pud)) {
+		pmd = pmd_alloc_one(NULL, addr);
+		if (!pmd) {
+			pr_warning("Failed to allocate identity pmd.\n");
+			return;
+		}
+		pud_populate(NULL, pud, pmd);
+	}
+
+	pmd = pmd_offset(pud, addr);
+
+	do {
+		next = pmd_addr_end(addr, end);
+		idmap_add_pte(pmd, addr, next);
+	} while (pmd++, addr = next, addr != end);
+}
+
+static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+	pud_t *pud = pud_offset(pgd, addr);
+	unsigned long next;
+
+	do {
+		next = pud_addr_end(addr, end);
+		idmap_add_pmd(pud, addr, next);
+	} while (pud++, addr = next, addr != end);
+}
+
+extern char  __hyp_idmap_text_start[], __hyp_idmap_text_end[];
+
+static int __init hyp_idmap_setup(void)
+{
+	unsigned long addr, end;
+	unsigned long next;
+	pgd_t *pgd;
+
+	if (!is_hyp_mode_available()) {
+		hyp_pgd = NULL;
+		return 0;
+	}
+
+	hyp_pgd = pgd_alloc(NULL);
+	if (!hyp_pgd)
+		return -ENOMEM;
+
+	addr = virt_to_phys(__hyp_idmap_text_start);
+	end = virt_to_phys(__hyp_idmap_text_end);
+
+	pr_info("Setting up static HYP identity map for 0x%lx - 0x%lx\n",
+		addr, end);
+
+	pgd = hyp_pgd + pgd_index(addr);
+	do {
+		next = pgd_addr_end(addr, end);
+		idmap_add_pud(pgd, addr, next);
+	} while (pgd++, addr = next, addr != end);
+
+	dsb();
+
+	return 0;
+}
+early_initcall(hyp_idmap_setup);
diff --git a/arch/arm64/kvm/idmap.h b/arch/arm64/kvm/idmap.h
new file mode 100644
index 0000000..fcb130f
--- /dev/null
+++ b/arch/arm64/kvm/idmap.h
@@ -0,0 +1,8 @@
+#ifndef __KVM_IDMAP_H
+#define __KVM_IDMAP_H
+
+#include <asm/pgtable.h>
+
+extern pgd_t *hyp_pgd;
+
+#endif	/* __KVM_IDMAP_H */
-- 
1.8.1.4

  parent reply	other threads:[~2013-03-26 17:00 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-26 17:00 [PATCH v2 00/30] Port of KVM to arm64 Marc Zyngier
2013-03-26 17:00 ` [PATCH v2 01/30] arm64: add explicit symbols to ESR_EL1 decoding Marc Zyngier
2013-03-27 13:51   ` Catalin Marinas
2013-03-27 14:05     ` Marc Zyngier
2013-03-26 17:00 ` [PATCH v2 02/30] arm64: KVM: define HYP and Stage-2 translation page flags Marc Zyngier
2013-03-27 14:11   ` Catalin Marinas
2013-03-27 14:20     ` Marc Zyngier
2013-03-26 17:00 ` Marc Zyngier [this message]
2013-03-26 17:00 ` [PATCH v2 04/30] arm64: KVM: EL2 register definitions Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 05/30] arm64: KVM: system register definitions for 64bit guests Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 06/30] arm64: KVM: Basic ESR_EL2 helpers and vcpu register access Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 07/30] arm64: KVM: fault injection into a guest Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 08/30] arm64: KVM: architecture specific MMU backend Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 09/30] arm64: KVM: user space interface Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 10/30] arm64: KVM: system register handling Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 11/30] arm64: KVM: CPU specific system registers handling Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 12/30] arm64: KVM: virtual CPU reset Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 13/30] arm64: KVM: kvm_arch and kvm_vcpu_arch definitions Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 14/30] arm64: KVM: MMIO access backend Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 15/30] arm64: KVM: guest one-reg interface Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 16/30] arm64: KVM: hypervisor initialization code Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 17/30] arm64: KVM: HYP mode world switch implementation Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 18/30] arm64: KVM: Exit handling Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 19/30] arm64: KVM: Plug the VGIC Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 20/30] arm64: KVM: Plug the arch timer Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 21/30] arm64: KVM: PSCI implementation Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 22/30] arm64: KVM: Build system integration Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 23/30] arm64: KVM: define 32bit specific registers Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 24/30] arm64: KVM: 32bit GP register access Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 25/30] arm64: KVM: 32bit conditional execution emulation Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 26/30] arm64: KVM: 32bit handling of coprocessor traps Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 27/30] arm64: KVM: CPU specific 32bit coprocessor access Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 28/30] arm64: KVM: 32bit specific register world switch Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 29/30] arm64: KVM: 32bit guest fault injection Marc Zyngier
2013-03-26 17:01 ` [PATCH v2 30/30] arm64: KVM: enable initialization of a 32bit vcpu Marc Zyngier
2013-03-29 14:57 ` [PATCH v2 00/30] Port of KVM to arm64 Christopher Covington
2013-03-29 18:37   ` Marc Zyngier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1364317285-20937-4-git-send-email-marc.zyngier@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).