void kvm_arch_destroy_vm(struct kvm *kvm) { unsigned int i; struct kvm_vcpu *vcpu; #ifdef CONFIG_KVM_XICS /* * We call kick_all_cpus_sync() to ensure that all * CPUs have executed any pending IPIs before we * continue and free VCPUs structures below. */ if (is_kvmppc_hv_enabled(kvm)) kick_all_cpus_sync(); #endif kvm_for_each_vcpu(i, vcpu, kvm) kvm_arch_vcpu_free(vcpu); mutex_lock(&kvm->lock); for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) kvm->vcpus[i] = NULL; atomic_set(&kvm->online_vcpus, 0); kvmppc_core_destroy_vm(kvm); mutex_unlock(&kvm->lock); /* drop the module reference */ module_put(kvm->arch.kvm_ops->owner); }
/************* MMU Notifiers *************/ static void do_kvm_unmap_hva(struct kvm *kvm, unsigned long start, unsigned long end) { long i; struct kvm_vcpu *vcpu; struct kvm_memslots *slots; struct kvm_memory_slot *memslot; slots = kvm_memslots(kvm); kvm_for_each_memslot(memslot, slots) { unsigned long hva_start, hva_end; gfn_t gfn, gfn_end; hva_start = max(start, memslot->userspace_addr); hva_end = min(end, memslot->userspace_addr + (memslot->npages << PAGE_SHIFT)); if (hva_start >= hva_end) continue; /* * {gfn(page) | page intersects with [hva_start, hva_end)} = * {gfn, gfn+1, ..., gfn_end-1}. */ gfn = hva_to_gfn_memslot(hva_start, memslot); gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot); kvm_for_each_vcpu(i, vcpu, kvm) kvmppc_mmu_pte_pflush(vcpu, gfn << PAGE_SHIFT, gfn_end << PAGE_SHIFT); }
/* Handle SCK (SET CLOCK) interception */ static int handle_set_clock(struct kvm_vcpu *vcpu) { struct kvm_vcpu *cpup; s64 hostclk, val; u64 op2; int i; if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); op2 = kvm_s390_get_base_disp_s(vcpu); if (op2 & 7) /* Operand must be on a doubleword boundary */ return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); if (get_guest(vcpu, val, (u64 __user *) op2)) return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); if (store_tod_clock(&hostclk)) { kvm_s390_set_psw_cc(vcpu, 3); return 0; } val = (val - hostclk) & ~0x3fUL; mutex_lock(&vcpu->kvm->lock); kvm_for_each_vcpu(i, cpup, vcpu->kvm) cpup->arch.sie_block->epoch = val; mutex_unlock(&vcpu->kvm->lock); kvm_s390_set_psw_cc(vcpu, 0); return 0; }
/* * vgic_init: allocates and initializes dist and vcpu data structures * depending on two dimensioning parameters: * - the number of spis * - the number of vcpus * The function is generally called when nr_spis has been explicitly set * by the guest through the KVM DEVICE API. If not nr_spis is set to 256. * vgic_initialized() returns true when this function has succeeded. * Must be called with kvm->lock held! */ int vgic_init(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; struct kvm_vcpu *vcpu; int ret = 0, i; if (vgic_initialized(kvm)) return 0; /* freeze the number of spis */ if (!dist->nr_spis) dist->nr_spis = VGIC_NR_IRQS_LEGACY - VGIC_NR_PRIVATE_IRQS; ret = kvm_vgic_dist_init(kvm, dist->nr_spis); if (ret) goto out; if (vgic_has_its(kvm)) dist->msis_require_devid = true; kvm_for_each_vcpu(i, vcpu, kvm) kvm_vgic_vcpu_init(vcpu); ret = kvm_vgic_setup_default_irq_routing(kvm); if (ret) goto out; dist->initialized = true; out: return ret; }
static void kvm_arm_halt_guest(struct kvm *kvm) { int i; struct kvm_vcpu *vcpu; kvm_for_each_vcpu(i, vcpu, kvm) vcpu->arch.pause = true; force_vm_exit(cpu_all_mask); }
void kvm_arm_halt_guest(struct kvm *kvm) { int i; struct kvm_vcpu *vcpu; kvm_for_each_vcpu(i, vcpu, kvm) vcpu->arch.pause = true; kvm_make_all_cpus_request(kvm, KVM_REQ_SLEEP); }
void kvm_vgic_destroy(struct kvm *kvm) { struct kvm_vcpu *vcpu; int i; kvm_vgic_dist_destroy(kvm); kvm_for_each_vcpu(i, vcpu, kvm) kvm_vgic_vcpu_destroy(vcpu); }
static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic) { struct kvm_vcpu *vcpu; int i; if (RTC_GSI >= IOAPIC_NUM_PINS) return; rtc_irq_eoi_tracking_reset(ioapic); kvm_for_each_vcpu(i, vcpu, ioapic->kvm) __rtc_irq_eoi_tracking_restore_one(vcpu); }
static void kvmppc_free_vcpus(struct kvm *kvm) { unsigned int i; struct kvm_vcpu *vcpu; kvm_for_each_vcpu(i, vcpu, kvm) kvm_arch_vcpu_free(vcpu); mutex_lock(&kvm->lock); for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) kvm->vcpus[i] = NULL; atomic_set(&kvm->online_vcpus, 0); mutex_unlock(&kvm->lock); }
void kvm_arch_destroy_vm(struct kvm *kvm) { unsigned int i; struct kvm_vcpu *vcpu; kvm_for_each_vcpu(i, vcpu, kvm) kvm_arch_vcpu_free(vcpu); mutex_lock(&kvm->lock); for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) kvm->vcpus[i] = NULL; atomic_set(&kvm->online_vcpus, 0); kvmppc_core_destroy_vm(kvm); mutex_unlock(&kvm->lock); /* drop the module reference */ module_put(kvm->arch.kvm_ops->owner); }