Re: [PATCH 3/4] ARM: KVM: Add support for IO mapping at the HYP level

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

 



On Thu, Jul 5, 2012 at 5:04 PM, Marc Zyngier <marc.zyngier@xxxxxxx> wrote:
> Moving to the VGIC implies giving access to some ioremapped
> devices (the VGIC virtual interface control registers) to the
> hypervisor.
>
> Define create_hyp_io_mappings() as the IO aware sibling of
> create_hyp_mappings(), and extend the mapping functions
> to support a pte mapping backend.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx>
> ---
>  arch/arm/include/asm/kvm_mmu.h |    1 +
>  arch/arm/kvm/mmu.c             |   76 ++++++++++++++++++++++++++++++----------
>  2 files changed, 58 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
> index 7ccd259..422ec45 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -30,6 +30,7 @@
>  #define PGD2_ORDER     get_order(PTRS_PER_PGD2 * sizeof(pgd_t))
>
>  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 kvm_alloc_stage2_pgd(struct kvm *kvm);
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index 33d34ea..c37afd0 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -18,6 +18,7 @@
>
>  #include <linux/mman.h>
>  #include <linux/kvm_host.h>
> +#include <linux/io.h>
>  #include <trace/events/kvm.h>
>  #include <asm/idmap.h>
>  #include <asm/pgalloc.h>
> @@ -25,6 +26,7 @@
>  #include <asm/kvm_mmu.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
> +#include <asm/mach/map.h>
>
>  #include "trace.h"
>
> @@ -74,24 +76,43 @@ void free_hyp_pmds(void)
>         mutex_unlock(&kvm_hyp_pgd_mutex);
>  }
>
> +/*
> + * Create a HYP pte mapping.
> + *
> + * If pfn_base is NULL, we map kernel pages into HYP with the virtual
> + * address. Otherwise, this is considered an I/O mapping and we map
> + * the physical region starting at *pfn_base to [start, end[.
> + */
>  static void create_hyp_pte_mappings(pmd_t *pmd, unsigned long start,
> -                                               unsigned long end)
> +                                   unsigned long end, unsigned long *pfn_base)
>  {
>         pte_t *pte;
> -       struct page *page;
>         unsigned long addr;
> +       pgprot_t prot;
> +
> +       if (pfn_base)
> +               prot = __pgprot(get_mem_type_prot_pte(MT_DEVICE) | L_PTE_USER);
> +       else
> +               prot = PAGE_HYP;
>
>         for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) {
>                 pte = pte_offset_kernel(pmd, addr);
> -               BUG_ON(!virt_addr_valid(addr));
> -               page = virt_to_page(addr);
> +               if (pfn_base) {
> +                       BUG_ON(pfn_valid(*pfn_base));
> +                       set_pte_ext(pte, pfn_pte(*pfn_base, prot), 0);
> +                       (*pfn_base)++;
> +               } else {
> +                       struct page *page;
> +                       BUG_ON(!virt_addr_valid(addr));
> +                       page = virt_to_page(addr);
> +                       set_pte_ext(pte, mk_pte(page, prot), 0);
> +               }
>
> -               set_pte_ext(pte, mk_pte(page, PAGE_HYP), 0);
>         }
>  }
>
>  static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
> -                                              unsigned long end)
> +                                  unsigned long end, unsigned long *pfn_base)
>  {
>         pmd_t *pmd;
>         pte_t *pte;
> @@ -112,23 +133,13 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
>                 }
>
>                 next = pmd_addr_end(addr, end);
> -               create_hyp_pte_mappings(pmd, addr, next);
> +               create_hyp_pte_mappings(pmd, addr, next, pfn_base);
>         }
>
>         return 0;
>  }
>
> -/**
> - * create_hyp_mappings - map a kernel virtual address range in Hyp mode
> - * @from:      The virtual kernel start address of the range
> - * @to:                The virtual kernel end address of the range (exclusive)
> - *
> - * The same virtual address as the kernel virtual address is also used in
> - * Hyp-mode mapping to the same underlying physical pages.
> - *
> - * Note: Wrapping around zero in the "to" address is not supported.
> - */
> -int create_hyp_mappings(void *from, void *to)
> +static int __create_hyp_mappings(void *from, void *to, unsigned long *pfn_base)
>  {
>         unsigned long start = (unsigned long)from;
>         unsigned long end = (unsigned long)to;
> @@ -158,7 +169,7 @@ int create_hyp_mappings(void *from, void *to)
>                 }
>
>                 next = pgd_addr_end(addr, end);
> -               err = create_hyp_pmd_mappings(pud, addr, next);
> +               err = create_hyp_pmd_mappings(pud, addr, next, pfn_base);
>                 if (err)
>                         goto out;
>         }
> @@ -168,6 +179,33 @@ out:
>  }
>
>  /**
> + * create_hyp_mappings - map a kernel virtual address range in Hyp mode
> + * @from:      The virtual kernel start address of the range
> + * @to:                The virtual kernel end address of the range (exclusive)
> + *
> + * The same virtual address as the kernel virtual address is also used in
> + * Hyp-mode mapping to the same underlying physical pages.
> + *
> + * Note: Wrapping around zero in the "to" address is not supported.
> + */
> +int create_hyp_mappings(void *from, void *to)
> +{
> +       return __create_hyp_mappings(from, to, NULL);
> +}
> +
> +/**
> + * create_hyp_io_mappings - map a physical IO range in Hyp mode
> + * @from:      The virtual HYP start address of the range
> + * @to:                The virtual HYP end address of the range (exclusive)
> + * @addr:      The physical start address which gets mapped
> + */
> +int create_hyp_io_mappings(void *from, void *to, phys_addr_t addr)
> +{
> +       unsigned long pfn = __phys_to_pfn(addr);
> +       return __create_hyp_mappings(from, to, &pfn);
> +}
> +
> +/**
>   * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation.
>   * @kvm:       The KVM struct pointer for the VM.
>   *
> --
> 1.7.10.3
>
>

applied, thanks
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[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