Re: [PATCH v6 03/12] ARM: KVM: Hypervisor identity mapping

2012-02-23 Thread Rusty Russell
On Thu, 23 Feb 2012 02:32:33 -0500, Christoffer Dall 
c.d...@virtualopensystems.com wrote:
 diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
 index 9c75ec4..c0adab0 100644
 --- a/arch/arm/kvm/guest.c
 +++ b/arch/arm/kvm/guest.c
 @@ -24,7 +24,6 @@
  #include asm/kvm_asm.h
  #include asm/kvm_emulate.h
  
 -
  struct kvm_stats_debugfs_item debugfs_entries[] = {
   { NULL }
  };

Cheers,
Rusty.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 03/12] ARM: KVM: Hypervisor identity mapping

2012-02-22 Thread Christoffer Dall
From: Christoffer Dall c.d...@virtualopensystems.com

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.

These two functions:
 - hyp_idmap_add(pgd, addr, end);
 - hyp_idmap_del(pgd, addr, end);
are essentially calls to the same function as the non-hyp versions but
with a different argument value. KVM calls these functions to setup
and teardown the identity mapping used to initialize the hypervisor.

Note, the hyp-version of the _del function actually frees the pmd's
pointed to by the pgd as opposed to the non-hyp version which just
clears them.

Signed-off-by: Christoffer Dall c.d...@virtualopensystems.com
---
 arch/arm/include/asm/pgtable-3level-hwdef.h |1 +
 arch/arm/include/asm/pgtable.h  |5 +++
 arch/arm/kvm/guest.c|1 -
 arch/arm/mm/idmap.c |   47 +--
 4 files changed, 49 insertions(+), 5 deletions(-)

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/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index f66626d..c7bd809 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -310,6 +310,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 #define pgtable_cache_init() do { } while (0)
 
+#ifdef CONFIG_KVM_ARM_HOST
+void hyp_idmap_add(pgd_t *, unsigned long, unsigned long);
+void hyp_idmap_del(pgd_t *pgd, unsigned long addr, unsigned long end);
+#endif
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* CONFIG_MMU */
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index 9c75ec4..c0adab0 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -24,7 +24,6 @@
 #include asm/kvm_asm.h
 #include asm/kvm_emulate.h
 
-
 struct kvm_stats_debugfs_item debugfs_entries[] = {
{ NULL }
 };
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index feacf4c..35902d7 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -1,3 +1,4 @@
+#include linux/module.h
 #include linux/kernel.h
 
 #include asm/cputype.h
@@ -58,11 +59,13 @@ 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, unsigned long addr,
+unsigned long end, unsigned long prot)
 {
-   unsigned long prot, next;
+   unsigned long next;
+
+   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;
 
@@ -89,12 +92,48 @@ static int __init init_static_idmap(void)
 
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);
+   identity_mapping_add(idmap_pgd, idmap_start, idmap_end, 0);
 
return 0;
 }
 early_initcall(init_static_idmap);
 
+#ifdef CONFIG_KVM_ARM_HOST
+void hyp_idmap_add(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+   identity_mapping_add(pgd, addr, end, PMD_SECT_AP1);
+}
+EXPORT_SYMBOL_GPL(hyp_idmap_add);
+
+static void hyp_idmap_del_pmd(pgd_t *pgd, unsigned long addr)
+{
+   pud_t *pud;
+   pmd_t *pmd;
+
+   pud = pud_offset(pgd, addr);
+   pmd = pmd_offset(pud, addr);
+   pmd_free(NULL, pmd);
+   pud_clear(pud);
+}
+
+/*
+ * This version actually frees the underlying pmds for all pgds in range and
+ * clear the pgds themselves afterwards.
+ */
+void hyp_idmap_del(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+   unsigned long next;
+
+   pgd += pgd_index(addr);
+   do {
+   next = pgd_addr_end(addr, end);
+   if (!pgd_none_or_clear_bad(pgd))
+   hyp_idmap_del_pmd(pgd, addr);
+   } while (pgd++, addr = next, addr  end);
+}
+EXPORT_SYMBOL_GPL(hyp_idmap_del);
+#endif
+
 /*
  * In order to soft-boot, we need to switch to a 1:1 mapping for the
  * cpu_reset functions. This will then ensure that we have predictable

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info