From: Linus Torvalds Date: Wed, 3 Jul 2013 20:21:40 +0000 (-0700) Subject: Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=fe489bf4505ae26d3c6d6a1f1d3064c2a9c5cd85;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git Merge tag 'for-linus' of git://git./virt/kvm/kvm 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 ... --- fe489bf4505ae26d3c6d6a1f1d3064c2a9c5cd85 diff --cc Documentation/virtual/kvm/api.txt index 9bfadeb8be31,6365fef8d616..66dd2aa53ba4 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@@ -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 arch/s390/include/asm/pgtable.h index 9aefa3c64eb2,1d0ad7d2d29a..0ea4e591fa78 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@@ -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 } diff --cc virt/kvm/arm/arch_timer.c index 000000000000,af4583e2c185..c2e1ef4604e8 mode 000000,100644..100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@@ -1,0 -1,283 +1,284 @@@ + /* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier + * + * 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 + #include + #include + #include + #include + + #include + #include + + #include + #include + + 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; + }