arch/loongarch/kvm/vcpu.c

Source file repositories/reference/linux-study-clean/arch/loongarch/kvm/vcpu.c

File Facts

System
Linux kernel
Corpus path
arch/loongarch/kvm/vcpu.c
Extension
.c
Size
48719 bytes
Lines
1899
Domain
Architecture Layer
Bucket
arch/loongarch
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st))) {
			ghc->gpa = INVALID_GPA;
			return;
		}
	}

	st = (struct kvm_steal_time __user *)ghc->hva;
	if (kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_PREEMPT)) {
		unsafe_put_user(0, &st->preempted, out);
		vcpu->arch.st.preempted = 0;
	}

	unsafe_get_user(version, &st->version, out);
	if (version & 1)
		version += 1; /* first time write, random junk */

	version += 1;
	unsafe_put_user(version, &st->version, out);
	smp_wmb();

	unsafe_get_user(steal, &st->steal, out);
	steal += current->sched_info.run_delay - vcpu->arch.st.last_steal;
	vcpu->arch.st.last_steal = current->sched_info.run_delay;
	unsafe_put_user(steal, &st->steal, out);

	smp_wmb();
	version += 1;
	unsafe_put_user(version, &st->version, out);
out:
	mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa));
}

/*
 * kvm_check_requests - check and handle pending vCPU requests
 *
 * Return: RESUME_GUEST if we should enter the guest
 *         RESUME_HOST  if we should exit to userspace
 */
static int kvm_check_requests(struct kvm_vcpu *vcpu)
{
	if (!kvm_request_pending(vcpu))
		return RESUME_GUEST;

	if (kvm_check_request(KVM_REQ_TLB_FLUSH, vcpu))
		vcpu->arch.vpid = 0;  /* Drop vpid for this vCPU */

	if (kvm_dirty_ring_check_request(vcpu))
		return RESUME_HOST;

	if (kvm_check_request(KVM_REQ_STEAL_UPDATE, vcpu))
		kvm_update_stolen_time(vcpu);

	return RESUME_GUEST;
}

static void kvm_late_check_requests(struct kvm_vcpu *vcpu)
{
	lockdep_assert_irqs_disabled();

	if (!kvm_request_pending(vcpu))
		return;

	if (kvm_check_request(KVM_REQ_PMU, vcpu)) {
		kvm_own_pmu(vcpu);
		vcpu->arch.aux_inuse |= KVM_LARCH_PMU;
	}

	if (kvm_check_request(KVM_REQ_TLB_FLUSH_GPA, vcpu))
		if (vcpu->arch.flush_gpa != INVALID_GPA) {
			kvm_flush_tlb_gpa(vcpu, vcpu->arch.flush_gpa);
			vcpu->arch.flush_gpa = INVALID_GPA;
		}

	if (kvm_check_request(KVM_REQ_FPU_LOAD, vcpu)) {
		if (kvm_guest_has_lasx(&vcpu->arch))
			kvm_own_lasx(vcpu);
		else if (kvm_guest_has_lsx(&vcpu->arch))
			kvm_own_lsx(vcpu);
		else if (kvm_guest_has_fpu(&vcpu->arch))
			kvm_own_fpu(vcpu);
	}

	if (kvm_check_request(KVM_REQ_LBT_LOAD, vcpu))
		kvm_own_lbt(vcpu);
}

/*
 * Check and handle pending signal and vCPU requests etc
 * Run with irq enabled and preempt enabled
 *

Annotation

Implementation Notes