Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f656ce01 authored by Marcelo Tosatti's avatar Marcelo Tosatti
Browse files

KVM: switch vcpu context to use SRCU

parent e93f8a0f
Loading
Loading
Loading
Loading
+6 −9
Original line number Diff line number Diff line
@@ -636,12 +636,9 @@ static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu)
static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
	union context *host_ctx, *guest_ctx;
	int r;
	int r, idx;

	/*
	 * down_read() may sleep and return with interrupts enabled
	 */
	down_read(&vcpu->kvm->slots_lock);
	idx = srcu_read_lock(&vcpu->kvm->srcu);

again:
	if (signal_pending(current)) {
@@ -663,7 +660,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	if (r < 0)
		goto vcpu_run_fail;

	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);
	kvm_guest_enter();

	/*
@@ -687,7 +684,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	kvm_guest_exit();
	preempt_enable();

	down_read(&vcpu->kvm->slots_lock);
	idx = srcu_read_lock(&vcpu->kvm->srcu);

	r = kvm_handle_exit(kvm_run, vcpu);

@@ -697,10 +694,10 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	}

out:
	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);
	if (r > 0) {
		kvm_resched(vcpu);
		down_read(&vcpu->kvm->slots_lock);
		idx = srcu_read_lock(&vcpu->kvm->srcu);
		goto again;
	}

+7 −3
Original line number Diff line number Diff line
@@ -67,10 +67,14 @@ static inline long kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)

static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
{
	int idx;
	struct kvm_memory_slot *mem;
	struct kvm_memslots *memslots;

	down_read(&vcpu->kvm->slots_lock);
	mem = &vcpu->kvm->memslots[0];
	idx = srcu_read_lock(&vcpu->kvm->srcu);
	memslots = rcu_dereference(vcpu->kvm->memslots);

	mem = &memslots->memslots[0];

	vcpu->arch.sie_block->gmsor = mem->userspace_addr;
	vcpu->arch.sie_block->gmslm =
@@ -78,7 +82,7 @@ static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
		(mem->npages << PAGE_SHIFT) +
		VIRTIODESCSPACE - 1ul;

	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);
}

/* implemented in priv.c */
+3 −4
Original line number Diff line number Diff line
@@ -2933,10 +2933,9 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask)
	spin_lock(&kvm_lock);

	list_for_each_entry(kvm, &vm_list, vm_list) {
		int npages;
		int npages, idx;

		if (!down_read_trylock(&kvm->slots_lock))
			continue;
		idx = srcu_read_lock(&kvm->srcu);
		spin_lock(&kvm->mmu_lock);
		npages = kvm->arch.n_alloc_mmu_pages -
			 kvm->arch.n_free_mmu_pages;
@@ -2949,7 +2948,7 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask)
		nr_to_scan--;

		spin_unlock(&kvm->mmu_lock);
		up_read(&kvm->slots_lock);
		srcu_read_unlock(&kvm->srcu, idx);
	}
	if (kvm_freed)
		list_move_tail(&kvm_freed->vm_list, &vm_list);
+3 −3
Original line number Diff line number Diff line
@@ -2478,10 +2478,10 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
{
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	u64 msr;
	int ret;
	int ret, idx;

	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
	down_read(&vcpu->kvm->slots_lock);
	idx = srcu_read_lock(&vcpu->kvm->srcu);
	if (!init_rmode(vmx->vcpu.kvm)) {
		ret = -ENOMEM;
		goto out;
@@ -2589,7 +2589,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
	vmx->emulation_required = 0;

out:
	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);
	return ret;
}

+24 −19
Original line number Diff line number Diff line
@@ -1306,15 +1306,15 @@ static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
		    int (*do_msr)(struct kvm_vcpu *vcpu,
				  unsigned index, u64 *data))
{
	int i;
	int i, idx;

	vcpu_load(vcpu);

	down_read(&vcpu->kvm->slots_lock);
	idx = srcu_read_lock(&vcpu->kvm->srcu);
	for (i = 0; i < msrs->nmsrs; ++i)
		if (do_msr(vcpu, entries[i].index, &entries[i].data))
			break;
	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);

	vcpu_put(vcpu);

@@ -3900,14 +3900,15 @@ static void vapic_enter(struct kvm_vcpu *vcpu)
static void vapic_exit(struct kvm_vcpu *vcpu)
{
	struct kvm_lapic *apic = vcpu->arch.apic;
	int idx;

	if (!apic || !apic->vapic_addr)
		return;

	down_read(&vcpu->kvm->slots_lock);
	idx = srcu_read_lock(&vcpu->kvm->srcu);
	kvm_release_page_dirty(apic->vapic_page);
	mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);
}

static void update_cr8_intercept(struct kvm_vcpu *vcpu)
@@ -4036,7 +4037,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
		kvm_lapic_sync_to_vapic(vcpu);
	}

	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);

	kvm_guest_enter();

@@ -4078,7 +4079,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)

	preempt_enable();

	down_read(&vcpu->kvm->slots_lock);
	vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);

	/*
	 * Profile KVM exit RIPs:
@@ -4100,6 +4101,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
static int __vcpu_run(struct kvm_vcpu *vcpu)
{
	int r;
	struct kvm *kvm = vcpu->kvm;

	if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED)) {
		pr_debug("vcpu %d received sipi with vector # %x\n",
@@ -4111,7 +4113,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
	}

	down_read(&vcpu->kvm->slots_lock);
	vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
	vapic_enter(vcpu);

	r = 1;
@@ -4119,9 +4121,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
		if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
			r = vcpu_enter_guest(vcpu);
		else {
			up_read(&vcpu->kvm->slots_lock);
			srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
			kvm_vcpu_block(vcpu);
			down_read(&vcpu->kvm->slots_lock);
			vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
			if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
			{
				switch(vcpu->arch.mp_state) {
@@ -4156,13 +4158,13 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
			++vcpu->stat.signal_exits;
		}
		if (need_resched()) {
			up_read(&vcpu->kvm->slots_lock);
			srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
			kvm_resched(vcpu);
			down_read(&vcpu->kvm->slots_lock);
			vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
		}
	}

	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
	post_kvm_run_save(vcpu);

	vapic_exit(vcpu);
@@ -4201,10 +4203,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
		vcpu->mmio_read_completed = 1;
		vcpu->mmio_needed = 0;

		down_read(&vcpu->kvm->slots_lock);
		vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
		r = emulate_instruction(vcpu, vcpu->arch.mmio_fault_cr2, 0,
					EMULTYPE_NO_DECODE);
		up_read(&vcpu->kvm->slots_lock);
		srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
		if (r == EMULATE_DO_MMIO) {
			/*
			 * Read-modify-write.  Back to userspace.
@@ -4967,11 +4969,12 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
{
	unsigned long vaddr = tr->linear_address;
	gpa_t gpa;
	int idx;

	vcpu_load(vcpu);
	down_read(&vcpu->kvm->slots_lock);
	idx = srcu_read_lock(&vcpu->kvm->srcu);
	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);
	tr->physical_address = gpa;
	tr->valid = gpa != UNMAPPED_GVA;
	tr->writeable = 1;
@@ -5223,11 +5226,13 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)

void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{
	int idx;

	kfree(vcpu->arch.mce_banks);
	kvm_free_lapic(vcpu);
	down_read(&vcpu->kvm->slots_lock);
	idx = srcu_read_lock(&vcpu->kvm->srcu);
	kvm_mmu_destroy(vcpu);
	up_read(&vcpu->kvm->slots_lock);
	srcu_read_unlock(&vcpu->kvm->srcu, idx);
	free_page((unsigned long)vcpu->arch.pio_data);
}

Loading