[snip]

>> +
>> +static int __init hyp_init_static_idmap(void)
>> +{
>> +     hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
>> +     if (!hyp_pgd)
>> +             return -ENOMEM;
>> +
>> +     hyp_idmap_setup();
>> +
>> +     return 0;
>> +}
>> +early_initcall(hyp_init_static_idmap);
>> +#endif
>
> I'd rather the alloc/free functions for the hyp pgd were somewhere else,
> like they are for standard pgds. Then we can just call them here without
> having to encode knowledge of PGD size etc in the mapping code.
>
this used to be the case, but Marc changed it iirc., so just cc'ing
him. The following is an attempt at what you're looking for if I
understand you correctly:

diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h
index a1ab8d6..36708ba 100644
--- a/arch/arm/include/asm/idmap.h
+++ b/arch/arm/include/asm/idmap.h
@@ -12,10 +12,8 @@ extern pgd_t *idmap_pgd;
 void setup_mm_for_reboot(void);

 #ifdef CONFIG_ARM_VIRT_EXT
-extern pgd_t *hyp_pgd;
-
-void hyp_idmap_teardown(void);
-void hyp_idmap_setup(void);
+void hyp_idmap_teardown(pgd_t *hyp_pgd);
+void hyp_idmap_setup(pgd_t *hyp_pgd);
 #endif

 #endif /* __ASM_IDMAP_H */
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index c3f90b0..ecfaaf0 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -43,4 +43,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu,
struct kvm_run *run);

 void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);

+unsigned long kvm_mmu_get_httbr(void);
+int kvm_mmu_init(void);
+void kvm_mmu_exit(void);
 #endif /* __ARM_KVM_MMU_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 7e11280..d64ce2a 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -35,7 +35,6 @@
 #include <asm/ptrace.h>
 #include <asm/mman.h>
 #include <asm/cputype.h>
-#include <asm/idmap.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 #include <asm/virt.h>
@@ -887,7 +886,7 @@ static void cpu_init_hyp_mode(void *vector)
        /* Switch from the HYP stub to our own HYP init vector */
        __hyp_set_vectors((unsigned long)vector);

-       pgd_ptr = virt_to_phys(hyp_pgd);
+       pgd_ptr = kvm_mmu_get_httbr();
        stack_page = __get_cpu_var(kvm_arm_hyp_stack_page);
        hyp_stack_ptr = stack_page + PAGE_SIZE;
        vector_ptr = (unsigned long)__kvm_hyp_vector;
@@ -918,6 +917,13 @@ static int init_hyp_mode(void)
        int err = 0;

        /*
+        * Allocate Hyp PGD and setup Hyp identity mapping
+        */
+       err = kvm_mmu_init();
+       if (err)
+               return err;
+
+       /*
         * It is probably enough to obtain the default on one
         * CPU. It's unlikely to be different on the others.
         */
@@ -954,7 +960,7 @@ static int init_hyp_mode(void)
        /*
         * Unmap the identity mapping
         */
-       hyp_idmap_teardown();
+       kvm_mmu_exit();

        /*
         * Map the Hyp-code called directly from the host
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 9499d4d..a35a8a9 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -34,6 +34,7 @@
 #include "trace.h"

 static DEFINE_MUTEX(kvm_hyp_pgd_mutex);
+static pgd_t *hyp_pgd;

 static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
                                  int min, int max)
@@ -994,3 +995,23 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu)
 {
        mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
 }
+
+unsigned long kvm_mmu_get_httbr(void)
+{
+       return virt_to_phys(hyp_pgd);
+}
+
+int kvm_mmu_init(void)
+{
+       hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
+       if (!hyp_pgd)
+               return -ENOMEM;
+
+       hyp_idmap_setup(hyp_pgd);
+       return 0;
+}
+
+void kvm_mmu_exit(void)
+{
+       hyp_idmap_teardown(hyp_pgd);
+}
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index f0ab339..ea7430e 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -102,9 +102,6 @@ static int __init init_static_idmap(void)
 early_initcall(init_static_idmap);

 #if defined(CONFIG_ARM_VIRT_EXT) && defined(CONFIG_ARM_LPAE)
-pgd_t *hyp_pgd;
-EXPORT_SYMBOL_GPL(hyp_pgd);
-
 static void hyp_idmap_del_pmd(pgd_t *pgd, unsigned long addr)
 {
        pud_t *pud;
@@ -123,7 +120,7 @@ extern char  __hyp_idmap_text_start[],
__hyp_idmap_text_end[];
  * This version actually frees the underlying pmds for all pgds in range and
  * clear the pgds themselves afterwards.
  */
-void hyp_idmap_teardown(void)
+void hyp_idmap_teardown(pgd_t *hyp_pgd)
 {
        unsigned long addr, end;
        unsigned long next;
@@ -141,27 +138,12 @@ void hyp_idmap_teardown(void)
 }
 EXPORT_SYMBOL_GPL(hyp_idmap_teardown);

-void hyp_idmap_setup(void)
+void hyp_idmap_setup(pgd_t *hyp_pgd)
 {
        identity_mapping_add(hyp_pgd, __hyp_idmap_text_start,
                             __hyp_idmap_text_end, PMD_SECT_AP1);
 }
 EXPORT_SYMBOL_GPL(hyp_idmap_setup);
-
-static int __init hyp_init_static_idmap(void)
-{
-       if (!is_hyp_mode_available())
-               return 0;
-
-       hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
-       if (!hyp_pgd)
-               return -ENOMEM;
-
-       hyp_idmap_setup();
-
-       return 0;
-}
-early_initcall(hyp_init_static_idmap);
 #endif

 /*
--
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

Reply via email to