[kvmarm:kvm-arm64/nv-wip-v5.0-rc1 43/75] arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1709:6: error: implicit declaration of function 'kvm_is_shadow_s2_fault'; did you mean 'kvm_is_write_fault'?

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

 



tree:   https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git kvm-arm64/nv-wip-v5.0-rc1
head:   688c386ca096f2c1f2eee386697586c88df5d5bc
commit: 7804bbf602f8d97fc5237ea12cdf28064952085c [43/75] KVM: arm64: nv: Handle shadow stage 2 page faults
config: arm-axm55xx_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout 7804bbf602f8d97fc5237ea12cdf28064952085c
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=arm 

All error/warnings (new ones prefixed by >>):

     struct kvm *kvm = mmu->kvm;
                 ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: At top level:
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1188:35: warning: 'struct kvm_s2_mmu' declared inside parameter list will not be visible outside of this definition or declaration
    static bool stage2_is_exec(struct kvm_s2_mmu *mmu, phys_addr_t addr)
                                      ^~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'stage2_is_exec':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1195:32: error: passing argument 1 of 'stage2_get_leaf_entry' from incompatible pointer type [-Werror=incompatible-pointer-types]
     found = stage2_get_leaf_entry(mmu, addr, &pudp, &pmdp, &ptep);
                                   ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1150:13: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static bool stage2_get_leaf_entry(struct kvm_s2_mmu *mmu, phys_addr_t addr,
                ^~~~~~~~~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: At top level:
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1207:34: warning: 'struct kvm_s2_mmu' declared inside parameter list will not be visible outside of this definition or declaration
    static int stage2_set_pte(struct kvm_s2_mmu *mmu,
                                     ^~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'stage2_set_pte':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1212:23: error: dereferencing pointer to incomplete type 'struct kvm_s2_mmu'
     struct kvm *kvm = mmu->kvm;
                          ^~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1222:23: error: passing argument 1 of 'stage2_get_pud' from incompatible pointer type [-Werror=incompatible-pointer-types]
     pud = stage2_get_pud(mmu, cache, addr);
                          ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1023:15: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static pud_t *stage2_get_pud(struct kvm_s2_mmu *mmu, struct kvm_mmu_memory_cache *cache,
                  ^~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1236:23: error: passing argument 1 of 'stage2_dissolve_pud' from incompatible pointer type [-Werror=incompatible-pointer-types]
      stage2_dissolve_pud(mmu, addr, pud);
                          ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:127:13: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static void stage2_dissolve_pud(struct kvm_s2_mmu *mmu, phys_addr_t addr, pud_t *pudp)
                ^~~~~~~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1260:23: error: passing argument 1 of 'stage2_dissolve_pmd' from incompatible pointer type [-Werror=incompatible-pointer-types]
      stage2_dissolve_pmd(mmu, addr, pmd);
                          ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:108:13: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static void stage2_dissolve_pmd(struct kvm_s2_mmu *mmu, phys_addr_t addr, pmd_t *pmd)
                ^~~~~~~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1284:26: error: passing argument 1 of 'kvm_tlb_flush_vmid_ipa' from incompatible pointer type [-Werror=incompatible-pointer-types]
      kvm_tlb_flush_vmid_ipa(mmu, addr);
                             ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:69:13: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static void kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa)
                ^~~~~~~~~~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1212:14: warning: unused variable 'kvm' [-Wunused-variable]
     struct kvm *kvm = mmu->kvm;
                 ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_phys_addr_ioremap':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1350:34: error: 'struct kvm_arch' has no member named 'mmu'
      ret = stage2_set_pte(&kvm->arch.mmu, &cache, addr, &pte,
                                     ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: At top level:
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1439:35: warning: 'struct kvm_s2_mmu' declared inside parameter list will not be visible outside of this definition or declaration
    static void stage2_wp_pmds(struct kvm_s2_mmu *mmu, pud_t *pud,
                                      ^~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'stage2_wp_pmds':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1442:23: error: dereferencing pointer to incomplete type 'struct kvm_s2_mmu'
     struct kvm *kvm = mmu->kvm;
                          ^~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: At top level:
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1469:36: warning: 'struct kvm_s2_mmu' declared inside parameter list will not be visible outside of this definition or declaration
    static void  stage2_wp_puds(struct kvm_s2_mmu *mmu, pgd_t *pgd,
                                       ^~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'stage2_wp_puds':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1472:23: error: dereferencing pointer to incomplete type 'struct kvm_s2_mmu'
     struct kvm *kvm = mmu->kvm;
                          ^~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1484:20: error: passing argument 1 of 'stage2_wp_pmds' from incompatible pointer type [-Werror=incompatible-pointer-types]
        stage2_wp_pmds(mmu, pud, addr, next);
                       ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1439:13: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static void stage2_wp_pmds(struct kvm_s2_mmu *mmu, pud_t *pud,
                ^~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1472:14: warning: unused variable 'kvm' [-Wunused-variable]
     struct kvm *kvm = mmu->kvm;
                 ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: At top level:
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1496:36: warning: 'struct kvm_s2_mmu' declared inside parameter list will not be visible outside of this definition or declaration
    static void stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
                                       ^~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'stage2_wp_range':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1498:23: error: dereferencing pointer to incomplete type 'struct kvm_s2_mmu'
     struct kvm *kvm = mmu->kvm;
                          ^~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1518:19: error: passing argument 1 of 'stage2_wp_puds' from incompatible pointer type [-Werror=incompatible-pointer-types]
       stage2_wp_puds(mmu, pgd, addr, next);
                      ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1469:14: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static void  stage2_wp_puds(struct kvm_s2_mmu *mmu, pgd_t *pgd,
                 ^~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_mmu_wp_memory_region':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1543:28: error: 'struct kvm_arch' has no member named 'mmu'
     stage2_wp_range(&kvm->arch.mmu, start, end);
                               ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_mmu_write_protect_pt_masked':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1567:28: error: 'struct kvm_arch' has no member named 'mmu'
     stage2_wp_range(&kvm->arch.mmu, start, end);
                               ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: At top level:
>> arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1665:13: warning: 'struct kvm_s2_trans' declared inside parameter list will not be visible outside of this definition or declaration
         struct kvm_s2_trans *nested,
                ^~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'user_mem_abort':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1682:37: error: 'struct kvm_vcpu_arch' has no member named 'hw_mmu'
     struct kvm_s2_mmu *mmu = vcpu->arch.hw_mmu;
                                        ^
>> arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1709:6: error: implicit declaration of function 'kvm_is_shadow_s2_fault'; did you mean 'kvm_is_write_fault'? [-Werror=implicit-function-declaration]
     if (kvm_is_shadow_s2_fault(vcpu)) {
         ^~~~~~~~~~~~~~~~~~~~~~
         kvm_is_write_fault
>> arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1710:15: error: dereferencing pointer to incomplete type 'struct kvm_s2_trans'
      ipa = nested->output;
                  ^~
   In file included from include/asm-generic/bug.h:18:0,
                    from arch/arm/include/asm/bug.h:60,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/mm.h:9,
                    from include/linux/mman.h:5,
                    from arch/arm/kvm/../../../virt/kvm/arm/mmu.c:19:
   include/linux/kernel.h:870:2: error: first argument to '__builtin_choose_expr' not a constant
     __builtin_choose_expr(__safe_cmp(x, y), \
     ^
   include/linux/kernel.h:879:19: note: in expansion of macro '__careful_cmp'
    #define min(x, y) __careful_cmp(x, y, <)
                      ^~~~~~~~~~~~~
>> arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1717:18: note: in expansion of macro 'min'
      max_map_size = min(nested->block_size, max_map_size);
                     ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1810:47: error: passing argument 1 of 'stage2_is_exec' from incompatible pointer type [-Werror=incompatible-pointer-types]
      (fault_status == FSC_PERM && stage2_is_exec(mmu, fault_ipa));
                                                  ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1188:13: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static bool stage2_is_exec(struct kvm_s2_mmu *mmu, phys_addr_t addr)
                ^~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1822:29: error: passing argument 1 of 'stage2_set_pud_huge' from incompatible pointer type [-Werror=incompatible-pointer-types]
      ret = stage2_set_pud_huge(mmu, memcache, fault_ipa, &new_pud);
                                ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1112:12: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static int stage2_set_pud_huge(struct kvm_s2_mmu *mmu,
               ^~~~~~~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1834:29: error: passing argument 1 of 'stage2_set_pmd_huge' from incompatible pointer type [-Werror=incompatible-pointer-types]
      ret = stage2_set_pmd_huge(mmu, memcache, fault_ipa, &new_pmd);
                                ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1064:12: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static int stage2_set_pmd_huge(struct kvm_s2_mmu *mmu,
               ^~~~~~~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1846:24: error: passing argument 1 of 'stage2_set_pte' from incompatible pointer type [-Werror=incompatible-pointer-types]
      ret = stage2_set_pte(mmu, memcache, fault_ipa, &new_pte, flags);
                           ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1207:12: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    static int stage2_set_pte(struct kvm_s2_mmu *mmu,
               ^~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'handle_access_fault':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1875:39: error: 'struct kvm_vcpu_arch' has no member named 'hw_mmu'
     if (!stage2_get_leaf_entry(vcpu->arch.hw_mmu, fault_ipa, &pud, &pmd, &pte))
                                          ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_handle_guest_abort':
>> arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1916:22: error: storage size of 'nested_trans' isn't known
     struct kvm_s2_trans nested_trans;
                         ^~~~~~~~~~~~
>> arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1975:9: error: implicit declaration of function 'kvm_walk_nested_s2'; did you mean 'kvm_inject_nested_irq'? [-Werror=implicit-function-declaration]
      ret = kvm_walk_nested_s2(vcpu, fault_ipa, &nested_trans);
            ^~~~~~~~~~~~~~~~~~
            kvm_inject_nested_irq
>> arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1977:4: error: implicit declaration of function 'kvm_inject_s2_fault'; did you mean 'kvm_inject_pabt'? [-Werror=implicit-function-declaration]
       kvm_inject_s2_fault(vcpu, nested_trans.esr);
       ^~~~~~~~~~~~~~~~~~~
       kvm_inject_pabt
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1916:22: warning: unused variable 'nested_trans' [-Wunused-variable]
     struct kvm_s2_trans nested_trans;
                         ^~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_unmap_hva_handler':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2075:35: error: 'struct kvm_arch' has no member named 'mmu'
     kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, size);
                                      ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_unmap_hva_range':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2082:16: error: 'struct kvm_arch' has no member named 'mmu'
     if (!kvm->arch.mmu.pgd)
                   ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_set_spte_handler':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2102:27: error: 'struct kvm_arch' has no member named 'mmu'
     stage2_set_pte(&kvm->arch.mmu, NULL, gpa, pte, 0);
                              ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_set_spte_hva':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2113:16: error: 'struct kvm_arch' has no member named 'mmu'
     if (!kvm->arch.mmu.pgd)
                   ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_age_hva_handler':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2136:39: error: 'struct kvm_arch' has no member named 'mmu'
     if (!stage2_get_leaf_entry(&kvm->arch.mmu, gpa, &pud, &pmd, &pte))
                                          ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_test_age_hva_handler':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2154:39: error: 'struct kvm_arch' has no member named 'mmu'
     if (!stage2_get_leaf_entry(&kvm->arch.mmu, gpa, &pud, &pmd, &pte))
                                          ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_age_hva':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2167:16: error: 'struct kvm_arch' has no member named 'mmu'
     if (!kvm->arch.mmu.pgd)
                   ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_test_age_hva':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2175:16: error: 'struct kvm_arch' has no member named 'mmu'
     if (!kvm->arch.mmu.pgd)
                   ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_arch_prepare_memory_region':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2388:36: error: 'struct kvm_arch' has no member named 'mmu'
      kvm_unmap_stage2_range(&kvm->arch.mmu, mem->guest_phys_addr, mem->memory_size);
                                       ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2390:34: error: 'struct kvm_arch' has no member named 'mmu'
      stage2_flush_memslot(&kvm->arch.mmu, memslot);
                                     ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_arch_flush_shadow_all':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2416:27: error: 'struct kvm_arch' has no member named 'nested_mmus_size'
     for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
                              ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2417:38: error: 'struct kvm_arch' has no member named 'nested_mmus'
      struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
                                         ^
   In file included from arch/arm/include/asm/bug.h:60:0,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/mm.h:9,
                    from include/linux/mman.h:5,
                    from arch/arm/kvm/../../../virt/kvm/arm/mmu.c:19:
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2419:14: error: dereferencing pointer to incomplete type 'struct kvm_s2_mmu'
      WARN_ON(mmu->usage_count > 0);
                 ^
   include/asm-generic/bug.h:122:25: note: in definition of macro 'WARN_ON'
     int __ret_warn_on = !!(condition);    \
                            ^~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2422:24: error: passing argument 1 of 'kvm_free_stage2_pgd' from incompatible pointer type [-Werror=incompatible-pointer-types]
       kvm_free_stage2_pgd(mmu);
                           ^~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:1005:6: note: expected 'struct kvm_s2_mmu *' but argument is of type 'struct kvm_s2_mmu *'
    void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
         ^~~~~~~~~~~~~~~~~~~
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2424:17: error: 'struct kvm_arch' has no member named 'nested_mmus'
     kfree(kvm->arch.nested_mmus);
                    ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2425:11: error: 'struct kvm_arch' has no member named 'nested_mmus'
     kvm->arch.nested_mmus = NULL;
              ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2426:11: error: 'struct kvm_arch' has no member named 'nested_mmus_size'
     kvm->arch.nested_mmus_size = 0;
              ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2427:32: error: 'struct kvm_arch' has no member named 'mmu'
     kvm_free_stage2_pgd(&kvm->arch.mmu);
                                   ^
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c: In function 'kvm_arch_flush_shadow_memslot':
   arch/arm/kvm/../../../virt/kvm/arm/mmu.c:2437:35: error: 'struct kvm_arch' has no member named 'mmu'
     kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, size);
                                      ^
   cc1: some warnings being treated as errors

vim +1709 arch/arm/kvm/../../../virt/kvm/arm/mmu.c

  1521	
  1522	/**
  1523	 * kvm_mmu_wp_memory_region() - write protect stage 2 entries for memory slot
  1524	 * @kvm:	The KVM pointer
  1525	 * @slot:	The memory slot to write protect
  1526	 *
  1527	 * Called to start logging dirty pages after memory region
  1528	 * KVM_MEM_LOG_DIRTY_PAGES operation is called. After this function returns
  1529	 * all present PUD, PMD and PTEs are write protected in the memory region.
  1530	 * Afterwards read of dirty page log can be called.
  1531	 *
  1532	 * Acquires kvm_mmu_lock. Called with kvm->slots_lock mutex acquired,
  1533	 * serializing operations for VM memory regions.
  1534	 */
  1535	void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
  1536	{
  1537		struct kvm_memslots *slots = kvm_memslots(kvm);
  1538		struct kvm_memory_slot *memslot = id_to_memslot(slots, slot);
  1539		phys_addr_t start = memslot->base_gfn << PAGE_SHIFT;
  1540		phys_addr_t end = (memslot->base_gfn + memslot->npages) << PAGE_SHIFT;
  1541	
  1542		spin_lock(&kvm->mmu_lock);
> 1543		stage2_wp_range(&kvm->arch.mmu, start, end);
  1544		spin_unlock(&kvm->mmu_lock);
  1545		kvm_flush_remote_tlbs(kvm);
  1546	}
  1547	
  1548	/**
  1549	 * kvm_mmu_write_protect_pt_masked() - write protect dirty pages
  1550	 * @kvm:	The KVM pointer
  1551	 * @slot:	The memory slot associated with mask
  1552	 * @gfn_offset:	The gfn offset in memory slot
  1553	 * @mask:	The mask of dirty pages at offset 'gfn_offset' in this memory
  1554	 *		slot to be write protected
  1555	 *
  1556	 * Walks bits set in mask write protects the associated pte's. Caller must
  1557	 * acquire kvm_mmu_lock.
  1558	 */
  1559	static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
  1560			struct kvm_memory_slot *slot,
  1561			gfn_t gfn_offset, unsigned long mask)
  1562	{
  1563		phys_addr_t base_gfn = slot->base_gfn + gfn_offset;
  1564		phys_addr_t start = (base_gfn +  __ffs(mask)) << PAGE_SHIFT;
  1565		phys_addr_t end = (base_gfn + __fls(mask) + 1) << PAGE_SHIFT;
  1566	
  1567		stage2_wp_range(&kvm->arch.mmu, start, end);
  1568	}
  1569	
  1570	/*
  1571	 * kvm_arch_mmu_enable_log_dirty_pt_masked - enable dirty logging for selected
  1572	 * dirty pages.
  1573	 *
  1574	 * It calls kvm_mmu_write_protect_pt_masked to write protect selected pages to
  1575	 * enable dirty logging for them.
  1576	 */
  1577	void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
  1578			struct kvm_memory_slot *slot,
  1579			gfn_t gfn_offset, unsigned long mask)
  1580	{
  1581		kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask);
  1582	}
  1583	
  1584	static void clean_dcache_guest_page(kvm_pfn_t pfn, unsigned long size)
  1585	{
  1586		__clean_dcache_guest_page(pfn, size);
  1587	}
  1588	
  1589	static void invalidate_icache_guest_page(kvm_pfn_t pfn, unsigned long size)
  1590	{
  1591		__invalidate_icache_guest_page(pfn, size);
  1592	}
  1593	
  1594	static void kvm_send_hwpoison_signal(unsigned long address,
  1595					     struct vm_area_struct *vma)
  1596	{
  1597		short lsb;
  1598	
  1599		if (is_vm_hugetlb_page(vma))
  1600			lsb = huge_page_shift(hstate_vma(vma));
  1601		else
  1602			lsb = PAGE_SHIFT;
  1603	
  1604		send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current);
  1605	}
  1606	
  1607	static bool fault_supports_stage2_pmd_mappings(struct kvm_memory_slot *memslot,
  1608						       unsigned long hva)
  1609	{
  1610		gpa_t gpa_start, gpa_end;
  1611		hva_t uaddr_start, uaddr_end;
  1612		size_t size;
  1613	
  1614		size = memslot->npages * PAGE_SIZE;
  1615	
  1616		gpa_start = memslot->base_gfn << PAGE_SHIFT;
  1617		gpa_end = gpa_start + size;
  1618	
  1619		uaddr_start = memslot->userspace_addr;
  1620		uaddr_end = uaddr_start + size;
  1621	
  1622		/*
  1623		 * Pages belonging to memslots that don't have the same alignment
  1624		 * within a PMD for userspace and IPA cannot be mapped with stage-2
  1625		 * PMD entries, because we'll end up mapping the wrong pages.
  1626		 *
  1627		 * Consider a layout like the following:
  1628		 *
  1629		 *    memslot->userspace_addr:
  1630		 *    +-----+--------------------+--------------------+---+
  1631		 *    |abcde|fgh  Stage-1 PMD    |    Stage-1 PMD   tv|xyz|
  1632		 *    +-----+--------------------+--------------------+---+
  1633		 *
  1634		 *    memslot->base_gfn << PAGE_SIZE:
  1635		 *      +---+--------------------+--------------------+-----+
  1636		 *      |abc|def  Stage-2 PMD    |    Stage-2 PMD     |tvxyz|
  1637		 *      +---+--------------------+--------------------+-----+
  1638		 *
  1639		 * If we create those stage-2 PMDs, we'll end up with this incorrect
  1640		 * mapping:
  1641		 *   d -> f
  1642		 *   e -> g
  1643		 *   f -> h
  1644		 */
  1645		if ((gpa_start & ~S2_PMD_MASK) != (uaddr_start & ~S2_PMD_MASK))
  1646			return false;
  1647	
  1648		/*
  1649		 * Next, let's make sure we're not trying to map anything not covered
  1650		 * by the memslot. This means we have to prohibit PMD size mappings
  1651		 * for the beginning and end of a non-PMD aligned and non-PMD sized
  1652		 * memory slot (illustrated by the head and tail parts of the
  1653		 * userspace view above containing pages 'abcde' and 'xyz',
  1654		 * respectively).
  1655		 *
  1656		 * Note that it doesn't matter if we do the check using the
  1657		 * userspace_addr or the base_gfn, as both are equally aligned (per
  1658		 * the check above) and equally sized.
  1659		 */
  1660		return (hva & S2_PMD_MASK) >= uaddr_start &&
  1661		       (hva & S2_PMD_MASK) + S2_PMD_SIZE <= uaddr_end;
  1662	}
  1663	
  1664	static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> 1665				  struct kvm_s2_trans *nested,
  1666				  struct kvm_memory_slot *memslot,
  1667				  unsigned long hva, unsigned long fault_status)
  1668	{
  1669		int ret;
  1670		bool write_fault, writable;
  1671		bool exec_fault, needs_exec;
  1672		unsigned long mmu_seq;
  1673		phys_addr_t ipa = fault_ipa;
  1674		gfn_t gfn;
  1675		struct kvm *kvm = vcpu->kvm;
  1676		struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
  1677		struct vm_area_struct *vma;
  1678		kvm_pfn_t pfn;
  1679		pgprot_t mem_type = PAGE_S2;
  1680		bool logging_active = memslot_is_logging(memslot);
  1681		unsigned long vma_pagesize, flags = 0;
> 1682		struct kvm_s2_mmu *mmu = vcpu->arch.hw_mmu;
  1683		unsigned long max_map_size = PUD_SIZE;
  1684	
  1685		write_fault = kvm_is_write_fault(vcpu);
  1686		exec_fault = kvm_vcpu_trap_is_iabt(vcpu);
  1687		VM_BUG_ON(write_fault && exec_fault);
  1688	
  1689		if (fault_status == FSC_PERM && !write_fault && !exec_fault) {
  1690			kvm_err("Unexpected L2 read permission error\n");
  1691			return -EFAULT;
  1692		}
  1693	
  1694		if (!fault_supports_stage2_pmd_mappings(memslot, hva))
  1695			max_map_size = PAGE_SIZE;
  1696	
  1697		if (logging_active)
  1698			max_map_size = PAGE_SIZE;
  1699	
  1700		/* Let's check if we will get back a huge page backed by hugetlbfs */
  1701		down_read(&current->mm->mmap_sem);
  1702		vma = find_vma_intersection(current->mm, hva, hva + 1);
  1703		if (unlikely(!vma)) {
  1704			kvm_err("Failed to find VMA for hva 0x%lx\n", hva);
  1705			up_read(&current->mm->mmap_sem);
  1706			return -EFAULT;
  1707		}
  1708	
> 1709		if (kvm_is_shadow_s2_fault(vcpu)) {
> 1710			ipa = nested->output;
  1711	
  1712			/*
  1713			 * If we're about to create a shadow stage 2 entry, then we
  1714			 * can only create a block mapping if the guest stage 2 page
  1715			 * table uses at least as big a mapping.
  1716			 */
> 1717			max_map_size = min(nested->block_size, max_map_size);
  1718		}
  1719		gfn = ipa >> PAGE_SHIFT;
  1720	
  1721		vma_pagesize = min(vma_kernel_pagesize(vma), max_map_size);
  1722		/*
  1723		 * PUD level may not exist for a VM but PMD is guaranteed to
  1724		 * exist.
  1725		 */
  1726		if ((vma_pagesize == PMD_SIZE ||
  1727		     (vma_pagesize == PUD_SIZE && kvm_stage2_has_pud(kvm)))) {
  1728			gfn = (ipa & huge_page_mask(hstate_vma(vma))) >> PAGE_SHIFT;
  1729		}
  1730		up_read(&current->mm->mmap_sem);
  1731	
  1732	
  1733		/* We need minimum second+third level pages */
  1734		ret = mmu_topup_memory_cache(memcache, kvm_mmu_cache_min_pages(kvm),
  1735					     KVM_NR_MEM_OBJS);
  1736		if (ret)
  1737			return ret;
  1738	
  1739		mmu_seq = vcpu->kvm->mmu_notifier_seq;
  1740		/*
  1741		 * Ensure the read of mmu_notifier_seq happens before we call
  1742		 * gfn_to_pfn_prot (which calls get_user_pages), so that we don't risk
  1743		 * the page we just got a reference to gets unmapped before we have a
  1744		 * chance to grab the mmu_lock, which ensure that if the page gets
  1745		 * unmapped afterwards, the call to kvm_unmap_hva will take it away
  1746		 * from us again properly. This smp_rmb() interacts with the smp_wmb()
  1747		 * in kvm_mmu_notifier_invalidate_<page|range_end>.
  1748		 */
  1749		smp_rmb();
  1750	
  1751		pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable);
  1752		if (pfn == KVM_PFN_ERR_HWPOISON) {
  1753			kvm_send_hwpoison_signal(hva, vma);
  1754			return 0;
  1755		}
  1756		if (is_error_noslot_pfn(pfn))
  1757			return -EFAULT;
  1758	
  1759		if (kvm_is_device_pfn(pfn)) {
  1760			mem_type = PAGE_S2_DEVICE;
  1761			flags |= KVM_S2PTE_FLAG_IS_IOMAP;
  1762		} else if (logging_active) {
  1763			/*
  1764			 * Faults on pages in a memslot with logging enabled
  1765			 * should not be mapped with huge pages (it introduces churn
  1766			 * and performance degradation), so force a pte mapping.
  1767			 */
  1768			flags |= KVM_S2_FLAG_LOGGING_ACTIVE;
  1769	
  1770			/*
  1771			 * Only actually map the page as writable if this was a write
  1772			 * fault.
  1773			 */
  1774			if (!write_fault)
  1775				writable = false;
  1776		}
  1777	
  1778		spin_lock(&kvm->mmu_lock);
  1779		if (mmu_notifier_retry(kvm, mmu_seq))
  1780			goto out_unlock;
  1781	
  1782		if (vma_pagesize == PAGE_SIZE && max_map_size >= PMD_SIZE) {
  1783			/*
  1784			 * Only PMD_SIZE transparent hugepages(THP) are
  1785			 * currently supported. This code will need to be
  1786			 * updated to support other THP sizes.
  1787			 */
  1788			if (transparent_hugepage_adjust(&pfn, &ipa, &fault_ipa))
  1789				vma_pagesize = PMD_SIZE;
  1790		}
  1791	
  1792		if (writable)
  1793			kvm_set_pfn_dirty(pfn);
  1794	
  1795		if (fault_status != FSC_PERM)
  1796			clean_dcache_guest_page(pfn, vma_pagesize);
  1797	
  1798		if (exec_fault)
  1799			invalidate_icache_guest_page(pfn, vma_pagesize);
  1800	
  1801		/*
  1802		 * If we took an execution fault we have made the
  1803		 * icache/dcache coherent above and should now let the s2
  1804		 * mapping be executable.
  1805		 *
  1806		 * Write faults (!exec_fault && FSC_PERM) are orthogonal to
  1807		 * execute permissions, and we preserve whatever we have.
  1808		 */
  1809		needs_exec = exec_fault ||
  1810			(fault_status == FSC_PERM && stage2_is_exec(mmu, fault_ipa));
  1811	
  1812		if (vma_pagesize == PUD_SIZE) {
  1813			pud_t new_pud = kvm_pfn_pud(pfn, mem_type);
  1814	
  1815			new_pud = kvm_pud_mkhuge(new_pud);
  1816			if (writable)
  1817				new_pud = kvm_s2pud_mkwrite(new_pud);
  1818	
  1819			if (needs_exec)
  1820				new_pud = kvm_s2pud_mkexec(new_pud);
  1821	
  1822			ret = stage2_set_pud_huge(mmu, memcache, fault_ipa, &new_pud);
  1823		} else if (vma_pagesize == PMD_SIZE) {
  1824			pmd_t new_pmd = kvm_pfn_pmd(pfn, mem_type);
  1825	
  1826			new_pmd = kvm_pmd_mkhuge(new_pmd);
  1827	
  1828			if (writable)
  1829				new_pmd = kvm_s2pmd_mkwrite(new_pmd);
  1830	
  1831			if (needs_exec)
  1832				new_pmd = kvm_s2pmd_mkexec(new_pmd);
  1833	
  1834			ret = stage2_set_pmd_huge(mmu, memcache, fault_ipa, &new_pmd);
  1835		} else {
  1836			pte_t new_pte = kvm_pfn_pte(pfn, mem_type);
  1837	
  1838			if (writable) {
  1839				new_pte = kvm_s2pte_mkwrite(new_pte);
  1840				mark_page_dirty(kvm, gfn);
  1841			}
  1842	
  1843			if (needs_exec)
  1844				new_pte = kvm_s2pte_mkexec(new_pte);
  1845	
  1846			ret = stage2_set_pte(mmu, memcache, fault_ipa, &new_pte, flags);
  1847		}
  1848	
  1849	out_unlock:
  1850		spin_unlock(&kvm->mmu_lock);
  1851		kvm_set_pfn_accessed(pfn);
  1852		kvm_release_pfn_clean(pfn);
  1853		return ret;
  1854	}
  1855	
  1856	/*
  1857	 * Resolve the access fault by making the page young again.
  1858	 * Note that because the faulting entry is guaranteed not to be
  1859	 * cached in the TLB, we don't need to invalidate anything.
  1860	 * Only the HW Access Flag updates are supported for Stage 2 (no DBM),
  1861	 * so there is no need for atomic (pte|pmd)_mkyoung operations.
  1862	 */
  1863	static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
  1864	{
  1865		pud_t *pud;
  1866		pmd_t *pmd;
  1867		pte_t *pte;
  1868		kvm_pfn_t pfn;
  1869		bool pfn_valid = false;
  1870	
  1871		trace_kvm_access_fault(fault_ipa);
  1872	
  1873		spin_lock(&vcpu->kvm->mmu_lock);
  1874	
> 1875		if (!stage2_get_leaf_entry(vcpu->arch.hw_mmu, fault_ipa, &pud, &pmd, &pte))
  1876			goto out;
  1877	
  1878		if (pud) {		/* HugeTLB */
  1879			*pud = kvm_s2pud_mkyoung(*pud);
  1880			pfn = kvm_pud_pfn(*pud);
  1881			pfn_valid = true;
  1882		} else	if (pmd) {	/* THP, HugeTLB */
  1883			*pmd = pmd_mkyoung(*pmd);
  1884			pfn = pmd_pfn(*pmd);
  1885			pfn_valid = true;
  1886		} else {
  1887			*pte = pte_mkyoung(*pte);	/* Just a page... */
  1888			pfn = pte_pfn(*pte);
  1889			pfn_valid = true;
  1890		}
  1891	
  1892	out:
  1893		spin_unlock(&vcpu->kvm->mmu_lock);
  1894		if (pfn_valid)
  1895			kvm_set_pfn_accessed(pfn);
  1896	}
  1897	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Attachment: .config.gz
Description: application/gzip

_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/mailman/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