Merge tag 'kvm-arm-for-3.18-take-2' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Oct 2014 21:32:31 +0000 (14:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Oct 2014 21:32:31 +0000 (14:32 -0700)
Pull second batch of changes for KVM/{arm,arm64} from Marc Zyngier:
 "The most obvious thing is the sizeable MMU changes to support 48bit
  VAs on arm64.

  Summary:

   - support for 48bit IPA and VA (EL2)
   - a number of fixes for devices mapped into guests
   - yet another VGIC fix for BE
   - a fix for CPU hotplug
   - a few compile fixes (disabled VGIC, strict mm checks)"

[ I'm pulling directly from Marc at the request of Paolo Bonzini, whose
  backpack was stolen at Düsseldorf airport and will do new keys and
  rebuild his web of trust.    - Linus ]

* tag 'kvm-arm-for-3.18-take-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm:
  arm/arm64: KVM: Fix BE accesses to GICv2 EISR and ELRSR regs
  arm: kvm: STRICT_MM_TYPECHECKS fix for user_mem_abort
  arm/arm64: KVM: Ensure memslots are within KVM_PHYS_SIZE
  arm64: KVM: Implement 48 VA support for KVM EL2 and Stage-2
  arm/arm64: KVM: map MMIO regions at creation time
  arm64: kvm: define PAGE_S2_DEVICE as read-only by default
  ARM: kvm: define PAGE_S2_DEVICE as read-only by default
  arm/arm64: KVM: add 'writable' parameter to kvm_phys_addr_ioremap
  arm/arm64: KVM: fix potential NULL dereference in user_mem_abort()
  arm/arm64: KVM: use __GFP_ZERO not memset() to get zeroed pages
  ARM: KVM: fix vgic-disabled build
  arm: kvm: fix CPU hotplug

1  2 
arch/arm/include/asm/pgtable.h
arch/arm64/include/asm/pgtable.h

index 90aa4583b3086812e7bbea226f9092c0cc422cd7,92b2fbe1886882800dde5827cc5d2053d1ebcd47..3b30062975b247165dc8f8db946f304f15a9c50a
@@@ -100,7 -100,7 +100,7 @@@ extern pgprot_t            pgprot_s2_device
  #define PAGE_HYP              _MOD_PROT(pgprot_kernel, L_PTE_HYP)
  #define PAGE_HYP_DEVICE               _MOD_PROT(pgprot_hyp_device, L_PTE_HYP)
  #define PAGE_S2                       _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY)
- #define PAGE_S2_DEVICE                _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDWR)
+ #define PAGE_S2_DEVICE                _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDONLY)
  
  #define __PAGE_NONE           __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE)
  #define __PAGE_SHARED         __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
@@@ -226,6 -226,7 +226,6 @@@ static inline pte_t *pmd_page_vaddr(pmd
  #define pte_dirty(pte)                (pte_isset((pte), L_PTE_DIRTY))
  #define pte_young(pte)                (pte_isset((pte), L_PTE_YOUNG))
  #define pte_exec(pte)         (pte_isclear((pte), L_PTE_XN))
 -#define pte_special(pte)      (0)
  
  #define pte_valid_user(pte)   \
        (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte))
@@@ -244,8 -245,7 +244,8 @@@ static inline void set_pte_at(struct mm
        unsigned long ext = 0;
  
        if (addr < TASK_SIZE && pte_valid_user(pteval)) {
 -              __sync_icache_dcache(pteval);
 +              if (!pte_special(pteval))
 +                      __sync_icache_dcache(pteval);
                ext |= PTE_EXT_NG;
        }
  
@@@ -264,6 -264,8 +264,6 @@@ PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG)
  PTE_BIT_FUNC(mkexec,   &= ~L_PTE_XN);
  PTE_BIT_FUNC(mknexec,   |= L_PTE_XN);
  
 -static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
 -
  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  {
        const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER |
index cefd3e825612640a061da464ac43e2a63cbefcea,51f6f5284ce59ff5388aa5a9ea36cef513be5eb9..41a43bf26492b6558bbf1e78f7747a8b4a39d05d
@@@ -79,7 -79,7 +79,7 @@@ extern void __pgd_error(const char *fil
  #define PAGE_HYP_DEVICE               __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
  
  #define PAGE_S2                       __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
- #define PAGE_S2_DEVICE                __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN)
+ #define PAGE_S2_DEVICE                __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
  
  #define PAGE_NONE             __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN)
  #define PAGE_SHARED           __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
@@@ -149,51 -149,46 +149,51 @@@ extern struct page *empty_zero_page
  #define pte_valid_not_user(pte) \
        ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID)
  
 -static inline pte_t pte_wrprotect(pte_t pte)
 +static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot)
  {
 -      pte_val(pte) &= ~PTE_WRITE;
 +      pte_val(pte) &= ~pgprot_val(prot);
        return pte;
  }
  
 -static inline pte_t pte_mkwrite(pte_t pte)
 +static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot)
  {
 -      pte_val(pte) |= PTE_WRITE;
 +      pte_val(pte) |= pgprot_val(prot);
        return pte;
  }
  
 +static inline pte_t pte_wrprotect(pte_t pte)
 +{
 +      return clear_pte_bit(pte, __pgprot(PTE_WRITE));
 +}
 +
 +static inline pte_t pte_mkwrite(pte_t pte)
 +{
 +      return set_pte_bit(pte, __pgprot(PTE_WRITE));
 +}
 +
  static inline pte_t pte_mkclean(pte_t pte)
  {
 -      pte_val(pte) &= ~PTE_DIRTY;
 -      return pte;
 +      return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
  }
  
  static inline pte_t pte_mkdirty(pte_t pte)
  {
 -      pte_val(pte) |= PTE_DIRTY;
 -      return pte;
 +      return set_pte_bit(pte, __pgprot(PTE_DIRTY));
  }
  
  static inline pte_t pte_mkold(pte_t pte)
  {
 -      pte_val(pte) &= ~PTE_AF;
 -      return pte;
 +      return clear_pte_bit(pte, __pgprot(PTE_AF));
  }
  
  static inline pte_t pte_mkyoung(pte_t pte)
  {
 -      pte_val(pte) |= PTE_AF;
 -      return pte;
 +      return set_pte_bit(pte, __pgprot(PTE_AF));
  }
  
  static inline pte_t pte_mkspecial(pte_t pte)
  {
 -      pte_val(pte) |= PTE_SPECIAL;
 -      return pte;
 +      return set_pte_bit(pte, __pgprot(PTE_SPECIAL));
  }
  
  static inline void set_pte(pte_t *ptep, pte_t pte)
@@@ -244,16 -239,6 +244,16 @@@ static inline void set_pte_at(struct mm
  
  #define __HAVE_ARCH_PTE_SPECIAL
  
 +static inline pte_t pud_pte(pud_t pud)
 +{
 +      return __pte(pud_val(pud));
 +}
 +
 +static inline pmd_t pud_pmd(pud_t pud)
 +{
 +      return __pmd(pud_val(pud));
 +}
 +
  static inline pte_t pmd_pte(pmd_t pmd)
  {
        return __pte(pmd_val(pmd));
@@@ -271,13 -256,7 +271,13 @@@ static inline pmd_t pte_pmd(pte_t pte
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  #define pmd_trans_huge(pmd)   (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
  #define pmd_trans_splitting(pmd)      pte_special(pmd_pte(pmd))
 -#endif
 +#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 +#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
 +struct vm_area_struct;
 +void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
 +                        pmd_t *pmdp);
 +#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
 +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
  
  #define pmd_young(pmd)                pte_young(pmd_pte(pmd))
  #define pmd_wrprotect(pmd)    pte_pmd(pte_wrprotect(pmd_pte(pmd)))
  #define mk_pmd(page,prot)     pfn_pmd(page_to_pfn(page),prot)
  
  #define pmd_page(pmd)           pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
 +#define pud_write(pud)                pte_write(pud_pte(pud))
  #define pud_pfn(pud)          (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
  
  #define set_pmd_at(mm, addr, pmdp, pmd)       set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
@@@ -318,8 -296,6 +318,8 @@@ static inline int has_transparent_hugep
        __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
  #define pgprot_writecombine(prot) \
        __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 +#define pgprot_device(prot) \
 +      __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
  #define __HAVE_PHYS_MEM_ACCESS_PROT
  struct file;
  extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
@@@ -400,8 -376,6 +400,8 @@@ static inline pmd_t *pmd_offset(pud_t *
        return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
  }
  
 +#define pud_page(pud)           pmd_page(pud_pmd(pud))
 +
  #endif        /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */
  
  #if CONFIG_ARM64_PGTABLE_LEVELS > 3