[Android-virt] [PATCH 6/6] ARM: KVM: Make kvm_hyp_pgd and kvm_hyp_pgd_mutex static

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

 



On Mon, May 14, 2012 at 4:05 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> There is very little reason for kvm_hyp_pgd and kvm_hyp_pgd_mutex
> to be accessed outside of mmu.c, and kvm_hyp_pgd is passed as an
> argument to most functions.
>
> Instead, define a set of function to access it, and make it private.
>
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
> ?arch/arm/include/asm/kvm_mmu.h | ? 11 +++++----
> ?arch/arm/kvm/arm.c ? ? ? ? ? ? | ? 38 ++++++++++++++++--------------------
> ?arch/arm/kvm/mmu.c ? ? ? ? ? ? | ? 42 ++++++++++++++++++++++++++++-----------
> ?3 files changed, 53 insertions(+), 38 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
> index 71d6df4..4569756 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -27,12 +27,13 @@
> ?#define PTRS_PER_PGD2 ?512
> ?#define PGD2_ORDER ? ? get_order(PTRS_PER_PGD2 * sizeof(pgd_t))
>
> -extern pgd_t *kvm_hyp_pgd;
> -extern struct mutex kvm_hyp_pgd_mutex;
> +int create_hyp_mappings(void *from, void *to);
> +int create_hyp_io_mappings(void *from, void *to, phys_addr_t);
> +void free_hyp_pmds(void);
>
> -int create_hyp_mappings(pgd_t *hyp_pgd, void *from, void *to);
> -int create_hyp_io_mappings(pgd_t *hyp_pgd, void *from, void *to, phys_addr_t);
> -void free_hyp_pmds(pgd_t *hyp_pgd);
> +int kvm_hyp_pgd_alloc(void);
> +pgd_t *kvm_hyp_pgd_get(void);
> +void kvm_hyp_pgd_free(void);
>
> ?int kvm_alloc_stage2_pgd(struct kvm *kvm);
> ?void kvm_free_stage2_pgd(struct kvm *kvm);
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 317ec19..a73c613 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -111,7 +111,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> ? ? ? ? ? ? ? ?goto out_fail_alloc;
> ? ? ? ?mutex_init(&kvm->arch.pgd_mutex);
>
> - ? ? ? ret = create_hyp_mappings(kvm_hyp_pgd, kvm, kvm + 1);
> + ? ? ? ret = create_hyp_mappings(kvm, kvm + 1);
> ? ? ? ?if (ret)
> ? ? ? ? ? ? ? ?goto out_free_stage2_pgd;
>
> @@ -210,7 +210,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
> ? ? ? ?if (err)
> ? ? ? ? ? ? ? ?goto free_vcpu;
>
> - ? ? ? err = create_hyp_mappings(kvm_hyp_pgd, vcpu, vcpu + 1);
> + ? ? ? err = create_hyp_mappings(vcpu, vcpu + 1);
> ? ? ? ?if (err)
> ? ? ? ? ? ? ? ?goto free_vcpu;
>
> @@ -627,7 +627,7 @@ static void cpu_init_hyp_mode(void *vector)
>
> ? ? ? ?cpu_set_vector(vector);
>
> - ? ? ? pgd_ptr = virt_to_phys(kvm_hyp_pgd);
> + ? ? ? pgd_ptr = virt_to_phys(kvm_hyp_pgd_get());
> ? ? ? ?stack_page = __get_cpu_var(kvm_arm_hyp_stack_page);
> ? ? ? ?hyp_stack_ptr = stack_page + PAGE_SIZE;
>
> @@ -672,11 +672,9 @@ static int init_hyp_mode(void)
> ? ? ? ?/*
> ? ? ? ? * Allocate Hyp level-1 page table
> ? ? ? ? */
> - ? ? ? kvm_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
> - ? ? ? if (!kvm_hyp_pgd) {
> - ? ? ? ? ? ? ? err = -ENOMEM;
> + ? ? ? err = kvm_hyp_pgd_alloc();
> + ? ? ? if (err)
> ? ? ? ? ? ? ? ?goto out_free_stack_pages;
> - ? ? ? }
>
> ? ? ? ?init_phys_addr = virt_to_phys(__kvm_hyp_init);
> ? ? ? ?init_end_phys_addr = virt_to_phys(__kvm_hyp_init_end);
> @@ -685,8 +683,9 @@ static int init_hyp_mode(void)
> ? ? ? ?/*
> ? ? ? ? * Create identity mapping for the init code.
> ? ? ? ? */
> - ? ? ? hyp_idmap_add(kvm_hyp_pgd, (unsigned long)init_phys_addr,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(unsigned long)init_end_phys_addr);
> + ? ? ? hyp_idmap_add(kvm_hyp_pgd_get(),
> + ? ? ? ? ? ? ? ? ? ? (unsigned long)init_phys_addr,
> + ? ? ? ? ? ? ? ? ? ? (unsigned long)init_end_phys_addr);
>
> ? ? ? ?/*
> ? ? ? ? * Execute the init code on each CPU.
> @@ -703,14 +702,14 @@ static int init_hyp_mode(void)
> ? ? ? ?/*
> ? ? ? ? * Unmap the identity mapping
> ? ? ? ? */
> - ? ? ? hyp_idmap_del(kvm_hyp_pgd, (unsigned long)init_phys_addr,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(unsigned long)init_end_phys_addr);
> + ? ? ? hyp_idmap_del(kvm_hyp_pgd_get(),
> + ? ? ? ? ? ? ? ? ? ? (unsigned long)init_phys_addr,
> + ? ? ? ? ? ? ? ? ? ? (unsigned long)init_end_phys_addr);
>
> ? ? ? ?/*
> ? ? ? ? * Map the Hyp-code called directly from the host
> ? ? ? ? */
> - ? ? ? err = create_hyp_mappings(kvm_hyp_pgd,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? __kvm_hyp_code_start, __kvm_hyp_code_end);
> + ? ? ? err = create_hyp_mappings(__kvm_hyp_code_start, __kvm_hyp_code_end);
> ? ? ? ?if (err) {
> ? ? ? ? ? ? ? ?kvm_err("Cannot map world-switch code\n");
> ? ? ? ? ? ? ? ?goto out_free_mappings;
> @@ -721,8 +720,7 @@ static int init_hyp_mode(void)
> ? ? ? ? */
> ? ? ? ?for_each_possible_cpu(cpu) {
> ? ? ? ? ? ? ? ?char *stack_page = (char *)per_cpu(kvm_arm_hyp_stack_page, cpu);
> - ? ? ? ? ? ? ? err = create_hyp_mappings(kvm_hyp_pgd,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? stack_page, stack_page + PAGE_SIZE);
> + ? ? ? ? ? ? ? err = create_hyp_mappings(stack_page, stack_page + PAGE_SIZE);
>
> ? ? ? ? ? ? ? ?if (err) {
> ? ? ? ? ? ? ? ? ? ? ? ?kvm_err("Cannot map hyp stack\n");
> @@ -739,12 +737,11 @@ static int init_hyp_mode(void)
>
> ? ? ? ?return 0;
> ?out_free_mappings:
> - ? ? ? free_hyp_pmds(kvm_hyp_pgd);
> - ? ? ? kfree(kvm_hyp_pgd);
> + ? ? ? free_hyp_pmds();
> + ? ? ? kvm_hyp_pgd_free();
> ?out_free_stack_pages:
> ? ? ? ?for_each_possible_cpu(cpu)
> ? ? ? ? ? ? ? ?free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
> - ? ? ? kvm_hyp_pgd = NULL;
> ? ? ? ?return err;
> ?}
>
> @@ -778,11 +775,10 @@ void kvm_arch_exit(void)
> ?{
> ? ? ? ?int cpu;
>
> - ? ? ? free_hyp_pmds(kvm_hyp_pgd);
> + ? ? ? free_hyp_pmds();
> ? ? ? ?for_each_possible_cpu(cpu)
> ? ? ? ? ? ? ? ?free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
> - ? ? ? kfree(kvm_hyp_pgd);
> - ? ? ? kvm_hyp_pgd = NULL;
> + ? ? ? kvm_hyp_pgd_free();
> ?}
>
> ?static int arm_init(void)
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index 36bccaa..8d8530f 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -26,8 +26,8 @@
>
> ?#include "trace.h"
>
> -pgd_t *kvm_hyp_pgd;
> -DEFINE_MUTEX(kvm_hyp_pgd_mutex);
> +static pgd_t *kvm_hyp_pgd;
> +static DEFINE_MUTEX(kvm_hyp_pgd_mutex);
>
> ?static void free_ptes(pmd_t *pmd, unsigned long addr)
> ?{
> @@ -45,12 +45,11 @@ static void free_ptes(pmd_t *pmd, unsigned long addr)
>
> ?/**
> ?* free_hyp_pmds - free a Hyp-mode level-2 tables and child level-3 tables
> - * @hypd_pgd: ?The Hyp-mode page table pointer
> ?*
> ?* Assumes this is a page table used strictly in Hyp-mode and therefore contains
> ?* only mappings in the kernel memory area, which is above PAGE_OFFSET.
> ?*/
> -void free_hyp_pmds(pgd_t *hyp_pgd)
> +void free_hyp_pmds(void)
> ?{
> ? ? ? ?pgd_t *pgd;
> ? ? ? ?pud_t *pud;
> @@ -59,7 +58,7 @@ void free_hyp_pmds(pgd_t *hyp_pgd)
>
> ? ? ? ?mutex_lock(&kvm_hyp_pgd_mutex);
> ? ? ? ?for (addr = PAGE_OFFSET; addr != 0; addr += PGDIR_SIZE) {
> - ? ? ? ? ? ? ? pgd = hyp_pgd + pgd_index(addr);
> + ? ? ? ? ? ? ? pgd = kvm_hyp_pgd + pgd_index(addr);
> ? ? ? ? ? ? ? ?pud = pud_offset(pgd, addr);
>
> ? ? ? ? ? ? ? ?BUG_ON(pud_bad(*pud));
> @@ -141,7 +140,6 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
>
> ?/**
> ?* create_hyp_mappings - map a kernel virtual address range in Hyp mode
> - * @hyp_pgd: ? The allocated hypervisor level-1 table
> ?* @from: ? ? ?The virtual kernel start address of the range
> ?* @to: ? ? ? ? ? ? ? ?The virtual kernel end address of the range (exclusive)
> ?*
> @@ -150,7 +148,7 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
> ?*
> ?* Note: Wrapping around zero in the "to" address is not supported.
> ?*/
> -static int __create_hyp_mappings(pgd_t *hyp_pgd, void *from, void *to,
> +static int __create_hyp_mappings(void *from, void *to,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? hyp_pte_map_fn_t map_fn,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned long *pfn_base)
> ?{
> @@ -168,7 +166,7 @@ static int __create_hyp_mappings(pgd_t *hyp_pgd, void *from, void *to,
>
> ? ? ? ?mutex_lock(&kvm_hyp_pgd_mutex);
> ? ? ? ?for (addr = start; addr < end; addr = next) {
> - ? ? ? ? ? ? ? pgd = hyp_pgd + pgd_index(addr);
> + ? ? ? ? ? ? ? pgd = kvm_hyp_pgd + pgd_index(addr);
> ? ? ? ? ? ? ? ?pud = pud_offset(pgd, addr);
>
> ? ? ? ? ? ? ? ?if (pud_none_or_clear_bad(pud)) {
> @@ -191,15 +189,15 @@ out:
> ? ? ? ?return err;
> ?}
>
> -int create_hyp_mappings(pgd_t *hyp_pgd, void *from, void *to)
> +int create_hyp_mappings(void *from, void *to)
> ?{
> - ? ? ? return __create_hyp_mappings(hyp_pgd, from, to, create_hyp_pte_mappings, NULL);
> + ? ? ? return __create_hyp_mappings(from, to, create_hyp_pte_mappings, NULL);
> ?}
>
> -int create_hyp_io_mappings(pgd_t *hyp_pgd, void *from, void *to, phys_addr_t addr)
> +int create_hyp_io_mappings(void *from, void *to, phys_addr_t addr)
> ?{
> ? ? ? ?unsigned long pfn = __phys_to_pfn(addr);
> - ? ? ? return __create_hyp_mappings(hyp_pgd, from, to, create_hyp_pte_io_mappings, &pfn);
> + ? ? ? return __create_hyp_mappings(from, to, create_hyp_pte_io_mappings, &pfn);
> ?}
>
> ?/**
> @@ -701,3 +699,23 @@ int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
>
> ? ? ? ?return 0;
> ?}
> +
> +int kvm_hyp_pgd_alloc(void)
> +{
> + ? ? ? kvm_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
> + ? ? ? if (!kvm_hyp_pgd)
> + ? ? ? ? ? ? ? return -ENOMEM;
> +
> + ? ? ? return 0;
> +}
> +
> +pgd_t *kvm_hyp_pgd_get(void)
> +{
> + ? ? ? return kvm_hyp_pgd;
> +}
> +
> +void kvm_hyp_pgd_free(void)
> +{
> + ? ? ? kfree(kvm_hyp_pgd);
> + ? ? ? kvm_hyp_pgd = NULL;
> +}
> --
> 1.7.7.1
>
Looks good to me.

Thanks,
-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