Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Jul 2013 20:21:40 +0000 (13:21 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Jul 2013 20:21:40 +0000 (13:21 -0700)
Pull KVM fixes from Paolo Bonzini:
 "On the x86 side, there are some optimizations and documentation
  updates.  The big ARM/KVM change for 3.11, support for AArch64, will
  come through Catalin Marinas's tree.  s390 and PPC have misc cleanups
  and bugfixes"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (87 commits)
  KVM: PPC: Ignore PIR writes
  KVM: PPC: Book3S PR: Invalidate SLB entries properly
  KVM: PPC: Book3S PR: Allow guest to use 1TB segments
  KVM: PPC: Book3S PR: Don't keep scanning HPTEG after we find a match
  KVM: PPC: Book3S PR: Fix invalidation of SLB entry 0 on guest entry
  KVM: PPC: Book3S PR: Fix proto-VSID calculations
  KVM: PPC: Guard doorbell exception with CONFIG_PPC_DOORBELL
  KVM: Fix RTC interrupt coalescing tracking
  kvm: Add a tracepoint write_tsc_offset
  KVM: MMU: Inform users of mmio generation wraparound
  KVM: MMU: document fast invalidate all mmio sptes
  KVM: MMU: document fast invalidate all pages
  KVM: MMU: document fast page fault
  KVM: MMU: document mmio page fault
  KVM: MMU: document write_flooding_count
  KVM: MMU: document clear_spte_count
  KVM: MMU: drop kvm_mmu_zap_mmio_sptes
  KVM: MMU: init kvm generation close to mmio wrap-around value
  KVM: MMU: add tracepoint for check_mmio_spte
  KVM: MMU: fast invalidate all mmio sptes
  ...

17 files changed:
1  2 
Documentation/virtual/kvm/api.txt
MAINTAINERS
arch/arm/kvm/arm.c
arch/arm/kvm/interrupts_head.S
arch/arm/kvm/mmu.c
arch/powerpc/kvm/booke.c
arch/s390/include/asm/pgtable.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/entry64.S
arch/s390/mm/pgtable.c
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/emulate.c
arch/x86/kvm/lapic.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
include/linux/kvm_host.h
virt/kvm/arm/arch_timer.c

@@@ -2278,10 -2261,10 +2278,10 @@@ return indicates the attribute is imple
  indicate that the attribute can be read or written in the device's
  current state.  "addr" is ignored.
  
- 4.77 KVM_ARM_VCPU_INIT
+ 4.82 KVM_ARM_VCPU_INIT
  
  Capability: basic
 -Architectures: arm
 +Architectures: arm, arm64
  Type: vcpu ioctl
  Parameters: struct struct kvm_vcpu_init (in)
  Returns: 0 on success; -1 on error
@@@ -2300,14 -2283,12 +2300,14 @@@ should be created before this ioctl is 
  Possible features:
        - KVM_ARM_VCPU_POWER_OFF: Starts the CPU in a power-off state.
          Depends on KVM_CAP_ARM_PSCI.
 +      - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode.
 +        Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
  
  
- 4.78 KVM_GET_REG_LIST
+ 4.83 KVM_GET_REG_LIST
  
  Capability: basic
 -Architectures: arm
 +Architectures: arm, arm64
  Type: vcpu ioctl
  Parameters: struct kvm_reg_list (in/out)
  Returns: 0 on success; -1 on error
@@@ -2324,10 -2305,10 +2324,10 @@@ This ioctl returns the guest registers 
  KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
  
  
- 4.80 KVM_ARM_SET_DEVICE_ADDR
+ 4.84 KVM_ARM_SET_DEVICE_ADDR
  
  Capability: KVM_CAP_ARM_SET_DEVICE_ADDR
 -Architectures: arm
 +Architectures: arm, arm64
  Type: vm ioctl
  Parameters: struct kvm_arm_device_address (in)
  Returns: 0 on success, -1 on error
@@@ -2354,15 -2335,14 +2354,15 @@@ address type id specific to the individ
    bits:  | 63        ...       32 | 31    ...    16 | 15    ...    0 |
    field: |        0x00000000      |     device id   |  addr type id  |
  
 -ARM currently only require this when using the in-kernel GIC support for the
 -hardware VGIC features, using KVM_ARM_DEVICE_VGIC_V2 as the device id.  When
 -setting the base address for the guest's mapping of the VGIC virtual CPU
 -and distributor interface, the ioctl must be called after calling
 -KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs.  Calling
 -this ioctl twice for any of the base addresses will return -EEXIST.
 +ARM/arm64 currently only require this when using the in-kernel GIC
 +support for the hardware VGIC features, using KVM_ARM_DEVICE_VGIC_V2
 +as the device id.  When setting the base address for the guest's
 +mapping of the VGIC virtual CPU and distributor interface, the ioctl
 +must be called after calling KVM_CREATE_IRQCHIP, but before calling
 +KVM_RUN on any of the VCPUs.  Calling this ioctl twice for any of the
 +base addresses will return -EEXIST.
  
- 4.82 KVM_PPC_RTAS_DEFINE_TOKEN
+ 4.85 KVM_PPC_RTAS_DEFINE_TOKEN
  
  Capability: KVM_CAP_PPC_RTAS
  Architectures: ppc
diff --cc MAINTAINERS
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -629,11 -628,10 +625,11 @@@ static inline void pgste_set_unlock(pte
  {
  #ifdef CONFIG_PGSTE
        asm(
-               "       nihh    %1,0xff7f\n"    /* clear RCP_PCL_BIT */
+               "       nihh    %1,0xff7f\n"    /* clear PCL bit */
                "       stg     %1,%0\n"
                : "=Q" (ptep[PTRS_PER_PTE])
 -              : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc");
 +              : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE])
 +              : "cc", "memory");
        preempt_enable();
  #endif
  }
@@@ -709,19 -700,17 +705,19 @@@ static inline void pgste_set_key(pte_t 
  {
  #ifdef CONFIG_PGSTE
        unsigned long address;
 -      unsigned long okey, nkey;
 +      unsigned long nkey;
  
 -      if (!pte_present(entry))
 +      if (pte_val(entry) & _PAGE_INVALID)
                return;
 +      VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID));
        address = pte_val(entry) & PAGE_MASK;
 -      okey = nkey = page_get_storage_key(address);
 -      nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
 -      /* Set page access key and fetch protection bit from pgste */
 -      nkey |= (pgste_val(pgste) & (PGSTE_ACC_BITS | PGSTE_FP_BIT)) >> 56;
 -      if (okey != nkey)
 -              page_set_storage_key(address, nkey, 0);
 +      /*
 +       * Set page access key and fetch protection bit from pgste.
 +       * The guest C/R information is still in the PGSTE, set real
 +       * key C/R to 0.
 +       */
-       nkey = (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
++      nkey = (pgste_val(pgste) & (PGSTE_ACC_BITS | PGSTE_FP_BIT)) >> 56;
 +      page_set_storage_key(address, nkey, 0);
  #endif
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,af4583e..c2e1ef4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,283 +1,284 @@@
+ /*
+  * Copyright (C) 2012 ARM Ltd.
+  * Author: Marc Zyngier <marc.zyngier@arm.com>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+  */
+ #include <linux/cpu.h>
+ #include <linux/of_irq.h>
+ #include <linux/kvm.h>
+ #include <linux/kvm_host.h>
+ #include <linux/interrupt.h>
+ #include <clocksource/arm_arch_timer.h>
+ #include <asm/arch_timer.h>
+ #include <kvm/arm_vgic.h>
+ #include <kvm/arm_arch_timer.h>
+ static struct timecounter *timecounter;
+ static struct workqueue_struct *wqueue;
+ static unsigned int host_vtimer_irq;
+ static cycle_t kvm_phys_timer_read(void)
+ {
+       return timecounter->cc->read(timecounter->cc);
+ }
+ static bool timer_is_armed(struct arch_timer_cpu *timer)
+ {
+       return timer->armed;
+ }
+ /* timer_arm: as in "arm the timer", not as in ARM the company */
+ static void timer_arm(struct arch_timer_cpu *timer, u64 ns)
+ {
+       timer->armed = true;
+       hrtimer_start(&timer->timer, ktime_add_ns(ktime_get(), ns),
+                     HRTIMER_MODE_ABS);
+ }
+ static void timer_disarm(struct arch_timer_cpu *timer)
+ {
+       if (timer_is_armed(timer)) {
+               hrtimer_cancel(&timer->timer);
+               cancel_work_sync(&timer->expired);
+               timer->armed = false;
+       }
+ }
+ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
+ {
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
+       kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
+                           timer->irq->irq,
+                           timer->irq->level);
+ }
+ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
+ {
+       struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
+       /*
+        * We disable the timer in the world switch and let it be
+        * handled by kvm_timer_sync_hwstate(). Getting a timer
+        * interrupt at this point is a sure sign of some major
+        * breakage.
+        */
+       pr_warn("Unexpected interrupt %d on vcpu %p\n", irq, vcpu);
+       return IRQ_HANDLED;
+ }
+ static void kvm_timer_inject_irq_work(struct work_struct *work)
+ {
+       struct kvm_vcpu *vcpu;
+       vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired);
+       vcpu->arch.timer_cpu.armed = false;
+       kvm_timer_inject_irq(vcpu);
+ }
+ static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt)
+ {
+       struct arch_timer_cpu *timer;
+       timer = container_of(hrt, struct arch_timer_cpu, timer);
+       queue_work(wqueue, &timer->expired);
+       return HRTIMER_NORESTART;
+ }
+ /**
+  * kvm_timer_flush_hwstate - prepare to move the virt timer to the cpu
+  * @vcpu: The vcpu pointer
+  *
+  * Disarm any pending soft timers, since the world-switch code will write the
+  * virtual timer state back to the physical CPU.
+  */
+ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
+ {
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       /*
+        * We're about to run this vcpu again, so there is no need to
+        * keep the background timer running, as we're about to
+        * populate the CPU timer again.
+        */
+       timer_disarm(timer);
+ }
+ /**
+  * kvm_timer_sync_hwstate - sync timer state from cpu
+  * @vcpu: The vcpu pointer
+  *
+  * Check if the virtual timer was armed and either schedule a corresponding
+  * soft timer or inject directly if already expired.
+  */
+ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
+ {
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       cycle_t cval, now;
+       u64 ns;
+       if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
+               !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE))
+               return;
+       cval = timer->cntv_cval;
+       now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
+       BUG_ON(timer_is_armed(timer));
+       if (cval <= now) {
+               /*
+                * Timer has already expired while we were not
+                * looking. Inject the interrupt and carry on.
+                */
+               kvm_timer_inject_irq(vcpu);
+               return;
+       }
+       ns = cyclecounter_cyc2ns(timecounter->cc, cval - now);
+       timer_arm(timer, ns);
+ }
+ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
+                         const struct kvm_irq_level *irq)
+ {
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       /*
+        * The vcpu timer irq number cannot be determined in
+        * kvm_timer_vcpu_init() because it is called much before
+        * kvm_vcpu_set_target(). To handle this, we determine
+        * vcpu timer irq number when the vcpu is reset.
+        */
+       timer->irq = irq;
+ }
+ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
+ {
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       INIT_WORK(&timer->expired, kvm_timer_inject_irq_work);
+       hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+       timer->timer.function = kvm_timer_expire;
+ }
+ static void kvm_timer_init_interrupt(void *info)
+ {
+       enable_percpu_irq(host_vtimer_irq, 0);
+ }
+ static int kvm_timer_cpu_notify(struct notifier_block *self,
+                               unsigned long action, void *cpu)
+ {
+       switch (action) {
+       case CPU_STARTING:
+       case CPU_STARTING_FROZEN:
+               kvm_timer_init_interrupt(NULL);
+               break;
+       case CPU_DYING:
+       case CPU_DYING_FROZEN:
+               disable_percpu_irq(host_vtimer_irq);
+               break;
+       }
+       return NOTIFY_OK;
+ }
+ static struct notifier_block kvm_timer_cpu_nb = {
+       .notifier_call = kvm_timer_cpu_notify,
+ };
+ static const struct of_device_id arch_timer_of_match[] = {
+       { .compatible   = "arm,armv7-timer",    },
++      { .compatible   = "arm,armv8-timer",    },
+       {},
+ };
+ int kvm_timer_hyp_init(void)
+ {
+       struct device_node *np;
+       unsigned int ppi;
+       int err;
+       timecounter = arch_timer_get_timecounter();
+       if (!timecounter)
+               return -ENODEV;
+       np = of_find_matching_node(NULL, arch_timer_of_match);
+       if (!np) {
+               kvm_err("kvm_arch_timer: can't find DT node\n");
+               return -ENODEV;
+       }
+       ppi = irq_of_parse_and_map(np, 2);
+       if (!ppi) {
+               kvm_err("kvm_arch_timer: no virtual timer interrupt\n");
+               err = -EINVAL;
+               goto out;
+       }
+       err = request_percpu_irq(ppi, kvm_arch_timer_handler,
+                                "kvm guest timer", kvm_get_running_vcpus());
+       if (err) {
+               kvm_err("kvm_arch_timer: can't request interrupt %d (%d)\n",
+                       ppi, err);
+               goto out;
+       }
+       host_vtimer_irq = ppi;
+       err = register_cpu_notifier(&kvm_timer_cpu_nb);
+       if (err) {
+               kvm_err("Cannot register timer CPU notifier\n");
+               goto out_free;
+       }
+       wqueue = create_singlethread_workqueue("kvm_arch_timer");
+       if (!wqueue) {
+               err = -ENOMEM;
+               goto out_free;
+       }
+       kvm_info("%s IRQ%d\n", np->name, ppi);
+       on_each_cpu(kvm_timer_init_interrupt, NULL, 1);
+       goto out;
+ out_free:
+       free_percpu_irq(ppi, kvm_get_running_vcpus());
+ out:
+       of_node_put(np);
+       return err;
+ }
+ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
+ {
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       timer_disarm(timer);
+ }
+ int kvm_timer_init(struct kvm *kvm)
+ {
+       if (timecounter && wqueue) {
+               kvm->arch.timer.cntvoff = kvm_phys_timer_read();
+               kvm->arch.timer.enabled = 1;
+       }
+       return 0;
+ }