]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
Merge tag 'kvm-arm-for-3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm...
authorPaolo Bonzini <pbonzini@redhat.com>
Sat, 27 Sep 2014 09:03:33 +0000 (11:03 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Sat, 27 Sep 2014 09:03:33 +0000 (11:03 +0200)
Changes for KVM for arm/arm64 for 3.18

This includes a bunch of changes:
 - Support read-only memory slots on arm/arm64
 - Various changes to fix Sparse warnings
 - Correctly detect write vs. read Stage-2 faults
 - Various VGIC cleanups and fixes
 - Dynamic VGIC data strcuture sizing
 - Fix SGI set_clear_pend offset bug
 - Fix VTTBR_BADDR Mask
 - Correctly report the FSC on Stage-2 faults

Conflicts:
virt/kvm/eventfd.c
[duplicate, different patch where the kvm-arm version broke x86.
 The kvm tree instead has the right one]

1  2 
arch/arm/include/asm/kvm_host.h
arch/arm64/include/asm/kvm_host.h
include/linux/kvm_host.h
virt/kvm/kvm_main.c

index 155497c2b4da5e5e7c976a149262e8a726a63ac6,46e5d4da1989c2b52dfa229a68f287700e989277..53036e21756b6b1efaef6e9c34e64ae3117f30d2
@@@ -43,7 -43,7 +43,7 @@@
  #include <kvm/arm_vgic.h>
  
  u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode);
- int kvm_target_cpu(void);
+ int __attribute_const__ kvm_target_cpu(void);
  int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
  void kvm_reset_coprocs(struct kvm_vcpu *vcpu);
  
@@@ -170,8 -170,7 +170,8 @@@ unsigned long kvm_arm_num_regs(struct k
  int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
  
  /* We do not have shadow page tables, hence the empty hooks */
 -static inline int kvm_age_hva(struct kvm *kvm, unsigned long hva)
 +static inline int kvm_age_hva(struct kvm *kvm, unsigned long start,
 +                            unsigned long end)
  {
        return 0;
  }
@@@ -181,11 -180,6 +181,11 @@@ static inline int kvm_test_age_hva(stru
        return 0;
  }
  
 +static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 +                                                       unsigned long address)
 +{
 +}
 +
  struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
  struct kvm_vcpu __percpu **kvm_get_running_vcpus(void);
  
index 992d9da88119c62a273f45d379d3950c65997b11,bcde419057463e0b2e0204418ca34b7be796d92d..2012c4ba8d67bf15c484048b4a0fe5b68f8e1b94
@@@ -43,7 -43,7 +43,7 @@@
  
  #define KVM_VCPU_MAX_FEATURES 3
  
- int kvm_target_cpu(void);
+ int __attribute_const__ kvm_target_cpu(void);
  int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
  int kvm_arch_dev_ioctl_check_extension(long ext);
  
@@@ -180,8 -180,7 +180,8 @@@ int kvm_unmap_hva_range(struct kvm *kvm
  void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
  
  /* We do not have shadow page tables, hence the empty hooks */
 -static inline int kvm_age_hva(struct kvm *kvm, unsigned long hva)
 +static inline int kvm_age_hva(struct kvm *kvm, unsigned long start,
 +                            unsigned long end)
  {
        return 0;
  }
@@@ -191,13 -190,8 +191,13 @@@ static inline int kvm_test_age_hva(stru
        return 0;
  }
  
 +static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 +                                                       unsigned long address)
 +{
 +}
 +
  struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
- struct kvm_vcpu __percpu **kvm_get_running_vcpus(void);
+ struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void);
  
  u64 kvm_call_hyp(void *hypfn, ...);
  
diff --combined include/linux/kvm_host.h
index d594f9f34429d95ffc7a8ba785f13c6366d367b0,bbd8d57b04e02e24af3d98cbe3fb6f0302794e4c..28be31f49250a65e54f5d785cdd48d5676a5d045
@@@ -136,7 -136,6 +136,7 @@@ static inline bool is_error_page(struc
  #define KVM_REQ_GLOBAL_CLOCK_UPDATE 22
  #define KVM_REQ_ENABLE_IBS        23
  #define KVM_REQ_DISABLE_IBS       24
 +#define KVM_REQ_APIC_PAGE_RELOAD  25
  
  #define KVM_USERSPACE_IRQ_SOURCE_ID           0
  #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID      1
@@@ -199,17 -198,6 +199,17 @@@ int kvm_setup_async_pf(struct kvm_vcpu 
  int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu);
  #endif
  
 +/*
 + * Carry out a gup that requires IO. Allow the mm to relinquish the mmap
 + * semaphore if the filemap/swap has to wait on a page lock. pagep == NULL
 + * controls whether we retry the gup one more time to completion in that case.
 + * Typically this is called after a FAULT_FLAG_RETRY_NOWAIT in the main tdp
 + * handler.
 + */
 +int kvm_get_user_page_io(struct task_struct *tsk, struct mm_struct *mm,
 +                       unsigned long addr, bool write_fault,
 +                       struct page **pagep);
 +
  enum {
        OUTSIDE_GUEST_MODE,
        IN_GUEST_MODE,
@@@ -536,6 -524,8 +536,8 @@@ struct page *gfn_to_page(struct kvm *kv
  unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
  unsigned long gfn_to_hva_prot(struct kvm *kvm, gfn_t gfn, bool *writable);
  unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn);
+ unsigned long gfn_to_hva_memslot_prot(struct kvm_memory_slot *slot, gfn_t gfn,
+                                     bool *writable);
  void kvm_release_page_clean(struct page *page);
  void kvm_release_page_dirty(struct page *page);
  void kvm_set_page_accessed(struct page *page);
@@@ -587,7 -577,6 +589,7 @@@ void kvm_flush_remote_tlbs(struct kvm *
  void kvm_reload_remote_mmus(struct kvm *kvm);
  void kvm_make_mclock_inprogress_request(struct kvm *kvm);
  void kvm_make_scan_ioapic_request(struct kvm *kvm);
 +bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
  
  long kvm_arch_dev_ioctl(struct file *filp,
                        unsigned int ioctl, unsigned long arg);
diff --combined virt/kvm/kvm_main.c
index a1cf53ee0d286a5fa3a75229d3b0d407b27475c7,278232025129cae0686b5fa628c07f27169e7d2d..39a02fbdb5725ef2d2145f17c6f638db1362152c
  
  #include <asm/processor.h>
  #include <asm/io.h>
 +#include <asm/ioctl.h>
  #include <asm/uaccess.h>
  #include <asm/pgtable.h>
  
  #include "coalesced_mmio.h"
  #include "async_pf.h"
 +#include "vfio.h"
  
  #define CREATE_TRACE_POINTS
  #include <trace/events/kvm.h>
@@@ -153,7 -151,7 +153,7 @@@ static void ack_flush(void *_completed
  {
  }
  
 -static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
 +bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req)
  {
        int i, cpu, me;
        cpumask_var_t cpus;
@@@ -190,7 -188,7 +190,7 @@@ void kvm_flush_remote_tlbs(struct kvm *
        long dirty_count = kvm->tlbs_dirty;
  
        smp_mb();
 -      if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))
 +      if (kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))
                ++kvm->stat.remote_tlb_flush;
        cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);
  }
@@@ -198,17 -196,17 +198,17 @@@ EXPORT_SYMBOL_GPL(kvm_flush_remote_tlbs
  
  void kvm_reload_remote_mmus(struct kvm *kvm)
  {
 -      make_all_cpus_request(kvm, KVM_REQ_MMU_RELOAD);
 +      kvm_make_all_cpus_request(kvm, KVM_REQ_MMU_RELOAD);
  }
  
  void kvm_make_mclock_inprogress_request(struct kvm *kvm)
  {
 -      make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
 +      kvm_make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
  }
  
  void kvm_make_scan_ioapic_request(struct kvm *kvm)
  {
 -      make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC);
 +      kvm_make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC);
  }
  
  int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
@@@ -296,9 -294,6 +296,9 @@@ static void kvm_mmu_notifier_invalidate
                kvm_flush_remote_tlbs(kvm);
  
        spin_unlock(&kvm->mmu_lock);
 +
 +      kvm_arch_mmu_notifier_invalidate_page(kvm, address);
 +
        srcu_read_unlock(&kvm->srcu, idx);
  }
  
@@@ -372,8 -367,7 +372,8 @@@ static void kvm_mmu_notifier_invalidate
  
  static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn,
                                              struct mm_struct *mm,
 -                                            unsigned long address)
 +                                            unsigned long start,
 +                                            unsigned long end)
  {
        struct kvm *kvm = mmu_notifier_to_kvm(mn);
        int young, idx;
        idx = srcu_read_lock(&kvm->srcu);
        spin_lock(&kvm->mmu_lock);
  
 -      young = kvm_age_hva(kvm, address);
 +      young = kvm_age_hva(kvm, start, end);
        if (young)
                kvm_flush_remote_tlbs(kvm);
  
@@@ -1095,9 -1089,9 +1095,9 @@@ EXPORT_SYMBOL_GPL(gfn_to_hva)
   * If writable is set to false, the hva returned by this function is only
   * allowed to be read.
   */
- unsigned long gfn_to_hva_prot(struct kvm *kvm, gfn_t gfn, bool *writable)
+ unsigned long gfn_to_hva_memslot_prot(struct kvm_memory_slot *slot,
+                                     gfn_t gfn, bool *writable)
  {
-       struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn);
        unsigned long hva = __gfn_to_hva_many(slot, gfn, NULL, false);
  
        if (!kvm_is_error_hva(hva) && writable)
        return hva;
  }
  
+ unsigned long gfn_to_hva_prot(struct kvm *kvm, gfn_t gfn, bool *writable)
+ {
+       struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn);
+       return gfn_to_hva_memslot_prot(slot, gfn, writable);
+ }
  static int kvm_read_hva(void *data, void __user *hva, int len)
  {
        return __copy_from_user(data, hva, len);
@@@ -1127,43 -1128,6 +1134,43 @@@ static int get_user_page_nowait(struct 
        return __get_user_pages(tsk, mm, start, 1, flags, page, NULL, NULL);
  }
  
 +int kvm_get_user_page_io(struct task_struct *tsk, struct mm_struct *mm,
 +                       unsigned long addr, bool write_fault,
 +                       struct page **pagep)
 +{
 +      int npages;
 +      int locked = 1;
 +      int flags = FOLL_TOUCH | FOLL_HWPOISON |
 +                  (pagep ? FOLL_GET : 0) |
 +                  (write_fault ? FOLL_WRITE : 0);
 +
 +      /*
 +       * If retrying the fault, we get here *not* having allowed the filemap
 +       * to wait on the page lock. We should now allow waiting on the IO with
 +       * the mmap semaphore released.
 +       */
 +      down_read(&mm->mmap_sem);
 +      npages = __get_user_pages(tsk, mm, addr, 1, flags, pagep, NULL,
 +                                &locked);
 +      if (!locked) {
 +              VM_BUG_ON(npages);
 +
 +              if (!pagep)
 +                      return 0;
 +
 +              /*
 +               * The previous call has now waited on the IO. Now we can
 +               * retry and complete. Pass TRIED to ensure we do not re
 +               * schedule async IO (see e.g. filemap_fault).
 +               */
 +              down_read(&mm->mmap_sem);
 +              npages = __get_user_pages(tsk, mm, addr, 1, flags | FOLL_TRIED,
 +                                        pagep, NULL, NULL);
 +      }
 +      up_read(&mm->mmap_sem);
 +      return npages;
 +}
 +
  static inline int check_user_page_hwpoison(unsigned long addr)
  {
        int rc, flags = FOLL_TOUCH | FOLL_HWPOISON | FOLL_WRITE;
@@@ -1226,15 -1190,9 +1233,15 @@@ static int hva_to_pfn_slow(unsigned lon
                npages = get_user_page_nowait(current, current->mm,
                                              addr, write_fault, page);
                up_read(&current->mm->mmap_sem);
 -      } else
 -              npages = get_user_pages_fast(addr, 1, write_fault,
 -                                           page);
 +      } else {
 +              /*
 +               * By now we have tried gup_fast, and possibly async_pf, and we
 +               * are certainly not atomic. Time to retry the gup, allowing
 +               * mmap semaphore to be relinquished in the case of IO.
 +               */
 +              npages = kvm_get_user_page_io(current, current->mm, addr,
 +                                            write_fault, page);
 +      }
        if (npages != 1)
                return npages;
  
@@@ -2037,9 -1995,6 +2044,9 @@@ static long kvm_vcpu_ioctl(struct file 
        if (vcpu->kvm->mm != current->mm)
                return -EIO;
  
 +      if (unlikely(_IOC_TYPE(ioctl) != KVMIO))
 +              return -EINVAL;
 +
  #if defined(CONFIG_S390) || defined(CONFIG_PPC) || defined(CONFIG_MIPS)
        /*
         * Special cases: vcpu ioctls that are asynchronous to vcpu execution,
@@@ -3278,9 -3233,6 +3285,9 @@@ int kvm_init(void *opaque, unsigned vcp
                goto out_undebugfs;
        }
  
 +      r = kvm_vfio_ops_init();
 +      WARN_ON(r);
 +
        return 0;
  
  out_undebugfs: