arch/powerpc/kvm/booke.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kvm/booke.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kvm/booke.c
Extension
.c
Size
58285 bytes
Lines
2243
Domain
Architecture Layer
Bucket
arch/powerpc
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 (!(current->thread.regs->msr & MSR_VEC)) {
			enable_kernel_altivec();
			load_vr_state(&vcpu->arch.vr);
			disable_kernel_altivec();
			current->thread.vr_save_area = &vcpu->arch.vr;
			current->thread.regs->msr |= MSR_VEC;
		}
	}
#endif
}

/*
 * Save guest vcpu AltiVec state into thread.
 * It requires to be called with preemption disabled.
 */
static inline void kvmppc_save_guest_altivec(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_ALTIVEC
	if (cpu_has_feature(CPU_FTR_ALTIVEC)) {
		if (current->thread.regs->msr & MSR_VEC)
			giveup_altivec(current);
		current->thread.vr_save_area = NULL;
	}
#endif
}

static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu)
{
	/* Synchronize guest's desire to get debug interrupts into shadow MSR */
#ifndef CONFIG_KVM_BOOKE_HV
	vcpu->arch.shadow_msr &= ~MSR_DE;
	vcpu->arch.shadow_msr |= vcpu->arch.shared->msr & MSR_DE;
#endif

	/* Force enable debug interrupts when user space wants to debug */
	if (vcpu->guest_debug) {
#ifdef CONFIG_KVM_BOOKE_HV
		/*
		 * Since there is no shadow MSR, sync MSR_DE into the guest
		 * visible MSR.
		 */
		vcpu->arch.shared->msr |= MSR_DE;
#else
		vcpu->arch.shadow_msr |= MSR_DE;
		vcpu->arch.shared->msr &= ~MSR_DE;
#endif
	}
}

/*
 * Helper function for "full" MSR writes.  No need to call this if only
 * EE/CE/ME/DE/RI are changing.
 */
void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
{
	u32 old_msr = vcpu->arch.shared->msr;

#ifdef CONFIG_KVM_BOOKE_HV
	new_msr |= MSR_GS;
#endif

	vcpu->arch.shared->msr = new_msr;

	kvmppc_mmu_msr_notify(vcpu, old_msr);
	kvmppc_vcpu_sync_spe(vcpu);
	kvmppc_vcpu_sync_fpu(vcpu);
	kvmppc_vcpu_sync_debug(vcpu);
}

static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
                                       unsigned int priority)
{
	trace_kvm_booke_queue_irqprio(vcpu, priority);
	set_bit(priority, &vcpu->arch.pending_exceptions);
}

void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu,
				 ulong dear_flags, ulong esr_flags)
{
	vcpu->arch.queued_dear = dear_flags;
	vcpu->arch.queued_esr = esr_flags;
	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
}

void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, ulong srr1_flags,
				    ulong dear_flags, ulong esr_flags)
{
	WARN_ON_ONCE(srr1_flags);
	vcpu->arch.queued_dear = dear_flags;
	vcpu->arch.queued_esr = esr_flags;

Annotation

Implementation Notes