Re: [kvm-unit-tests PATCH 1/2] arm64: Add support for configuring the translation granule

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

 



On Tue, Nov 03, 2020 at 04:25:15PM +0000, Alexandru Elisei wrote:
> Hi,
> 
> On 11/3/20 4:10 PM, Andrew Jones wrote:
> > On Tue, Nov 03, 2020 at 03:49:32PM +0000, Nikos Nikoleris wrote:
> >>>> diff --git a/lib/arm64/asm/page.h b/lib/arm64/asm/page.h
> >>>> index 46af552..2a06207 100644
> >>>> --- a/lib/arm64/asm/page.h
> >>>> +++ b/lib/arm64/asm/page.h
> >>>> @@ -10,38 +10,51 @@
> >>>>    * This work is licensed under the terms of the GNU GPL, version 2.
> >>>>    */
> >>>> +#include <config.h>
> >>>>   #include <linux/const.h>
> >>>> -#define PGTABLE_LEVELS		2
> >>>>   #define VA_BITS			42
> >>> Let's bump VA_BITS to 48 while we're at it.
> > I tried my suggestion to go to 48 VA bits, but it seems to break
> > things for 64K pages.
> 
> I believe that is because we end up with PGTABLE_LEVELS=3 and in
> mmu_set_ranges_sect() we try to install a block mapping at the PUD level, which is
> forbidden by the architecture.
> 
> I think the easiest fix for that is to always try to install block mapping at the
> pmd level. The diff below fixed all errors (with 16k and 64k pages):
> 
> diff --git a/lib/arm/mmu.c b/lib/arm/mmu.c
> index 6d1c75b00eaa..d33948a8a06a 100644
> --- a/lib/arm/mmu.c
> +++ b/lib/arm/mmu.c
> @@ -134,20 +134,22 @@ void mmu_set_range_sect(pgd_t *pgtable, uintptr_t virt_offset,
>                         phys_addr_t phys_start, phys_addr_t phys_end,
>                         pgprot_t prot)
>  {
> -       phys_addr_t paddr = phys_start & PUD_MASK;
> -       uintptr_t vaddr = virt_offset & PUD_MASK;
> +       phys_addr_t paddr = phys_start & PMD_MASK;
> +       uintptr_t vaddr = virt_offset & PMD_MASK;
>         uintptr_t virt_end = phys_end - paddr + vaddr;
>         pgd_t *pgd;
>         pud_t *pud;
> -       pud_t entry;
> +       pmd_t *pmd;
> +       pmd_t entry;
>  
> -       for (; vaddr < virt_end; vaddr += PUD_SIZE, paddr += PUD_SIZE) {
> -               pud_val(entry) = paddr;
> -               pud_val(entry) |= PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S;
> -               pud_val(entry) |= pgprot_val(prot);
> +       for (; vaddr < virt_end; vaddr += PMD_SIZE, paddr += PMD_SIZE) {
> +               pmd_val(entry) = paddr;
> +               pmd_val(entry) |= PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S;
> +               pmd_val(entry) |= pgprot_val(prot);
>                 pgd = pgd_offset(pgtable, vaddr);
>                 pud = pud_alloc(pgd, vaddr);
> -               WRITE_ONCE(*pud, entry);
> +               pmd = pmd_alloc(pud, vaddr);
> +               WRITE_ONCE(*pmd, entry);
>                 flush_tlb_page(vaddr);

Nice work! This resolves my issue as well. And, I can run with 16K pages
on my thunderx now too.


>         }
>  }
> diff --git a/lib/arm64/asm/page.h b/lib/arm64/asm/page.h
> index 2a06207444aa..f649f56bf16f 100644
> --- a/lib/arm64/asm/page.h
> +++ b/lib/arm64/asm/page.h
> @@ -13,7 +13,7 @@
>  #include <config.h>
>  #include <linux/const.h>
>  
> -#define VA_BITS                        42
> +#define VA_BITS                        46

Let's use 48.

>  
>  #define PAGE_SIZE              CONFIG_PAGE_SIZE
>  #if PAGE_SIZE == 65536
> 
> Thanks,
> 
> Alex
> 

Thanks,
drew




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux