[Android-virt] [PATCH v2] ARM: KVM: Move HYP idmap to be section based

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[snip]

>>
>>  static int exit_hyp_mode(void)
>>  {
>> -       phys_addr_t exit_phys_addr, exit_end_phys_addr;
>> +       phys_addr_t exit_phys_addr;
>>         int cpu;
>>
>>         exit_phys_addr = virt_to_phys(__kvm_hyp_exit);
>> -       exit_end_phys_addr = virt_to_phys(__kvm_hyp_exit_end);
>>         BUG_ON(exit_phys_addr & 0x1f);
>>
>>         /*
>> -        * Create identity mapping for the exit code.
>> -        */
>> -       hyp_idmap_add(kvm_hyp_pgd_get(),
>> -                     (unsigned long)exit_phys_addr,
>> -                     (unsigned long)exit_end_phys_addr);
>> -
>> -       /*
>>          * Execute the exit code on each CPU.
>>          *
>>          * Note: The stack is not mapped yet, so don't do anything else than
>
> this exit code will now fail because we called hyp_idmap_teardown()
> above, right?
>
> so I guess we could not call the teardown() function, but then we may
> have a conflict if the physical RAM base happens to overlap with the
> kernel address for Hyp code?
>
> Seems like we will have to make the hyp_init_static_idmap exported to
> support this.
>
> I'm thinking otherwise maybe we want the generic code to only manage
> the idmap-Hyp page table and then let callers provide its own hyp_pgd
> to work on. But this requires being able to switch between the two
> which requires a reserved virtual address range mapped the same in
> both page tables right?
>
> Other suggestions? (drop KVM module support, sad???)
>

I applied with the following fixup to kvm-a15-v9-stage.

diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h
index 61c034e..a1ab8d6 100644
--- a/arch/arm/include/asm/idmap.h
+++ b/arch/arm/include/asm/idmap.h
@@ -15,6 +15,7 @@ void setup_mm_for_reboot(void);
 extern pgd_t *hyp_pgd;

 void hyp_idmap_teardown(void);
+void hyp_idmap_setup(void);
 #endif

 #endif	/* __ASM_IDMAP_H */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index bcb512e..62cc23c 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -821,6 +821,13 @@ static int exit_hyp_mode(void)
 	phys_addr_t exit_phys_addr;
 	int cpu;

+	/*
+	 * TODO: flush Hyp TLB in case idmap code overlaps.
+	 * Note that we should do this in the monitor code when switching the
+	 * HVBAR, but this is going  away and should be rather done in the Hyp
+	 * mode change of HVBAR.
+	 */
+	hyp_idmap_setup();
 	exit_phys_addr = virt_to_phys(__kvm_hyp_exit);
 	BUG_ON(exit_phys_addr & 0x1f);

diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 6f7ed62..4db26cb 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -139,6 +139,7 @@ __do_hyp_exit:

 	isb
 	mcr	p15, 4, sp, c1, c0, 0	@ HSCR
+	mcr	p15, 4, r0, c8, c7, 0   @ Flush Hyp TLB, r0 ignored
 	isb
 	eret

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index a244aee..cbd5793 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -69,6 +69,7 @@ void free_hyp_pmds(void)
 		pmd = pmd_offset(pud, addr);
 		free_ptes(pmd, addr);
 		pmd_free(NULL, pmd);
+		pud_clear(pud);
 	}
 	mutex_unlock(&kvm_hyp_pgd_mutex);
 }
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 60557e3..7a944af 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -102,6 +102,7 @@ early_initcall(init_static_idmap);

 #ifdef CONFIG_ARM_VIRT_EXT
 pgd_t *hyp_pgd;
+EXPORT_SYMBOL_GPL(hyp_pgd);

 static void hyp_idmap_del_pmd(pgd_t *pgd, unsigned long addr)
 {
@@ -139,14 +140,20 @@ void hyp_idmap_teardown(void)
 }
 EXPORT_SYMBOL_GPL(hyp_idmap_teardown);

+void hyp_idmap_setup(void)
+{
+	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)
 {
 	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);
+	hyp_idmap_setup();

 	return 0;
 }


-Christoffer


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux