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

Commit 35754c98 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

KVM: x86: introduce lapic_in_kernel



Avoid pointer chasing and memory barriers, and simplify the code
when split irqchip (LAPIC in kernel, IOAPIC/PIC in userspace)
is introduced.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent d50ab6c1
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ static int kvm_cpu_has_extint(struct kvm_vcpu *v)
 */
int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
{
	if (!irqchip_in_kernel(v->kvm))
	if (!lapic_in_kernel(v))
		return v->arch.interrupt.pending;

	if (kvm_cpu_has_extint(v))
@@ -75,7 +75,7 @@ int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
 */
int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
{
	if (!irqchip_in_kernel(v->kvm))
	if (!lapic_in_kernel(v))
		return v->arch.interrupt.pending;

	if (kvm_cpu_has_extint(v))
@@ -103,7 +103,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
{
	int vector;

	if (!irqchip_in_kernel(v->kvm))
	if (!lapic_in_kernel(v))
		return v->arch.interrupt.nr;

	vector = kvm_cpu_get_extint(v);
+8 −0
Original line number Diff line number Diff line
@@ -92,6 +92,14 @@ static inline int irqchip_in_kernel(struct kvm *kvm)
	return vpic != NULL;
}

static inline int lapic_in_kernel(struct kvm_vcpu *vcpu)
{
	/* Same as irqchip_in_kernel(vcpu->kvm), but with less
	 * pointer chasing and no unnecessary memory barriers.
	 */
	return vcpu->arch.apic != NULL;
}

void kvm_pic_reset(struct kvm_kpic_state *s);

void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
+2 −2
Original line number Diff line number Diff line
@@ -1985,7 +1985,7 @@ int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
	struct kvm_lapic *apic = vcpu->arch.apic;
	u32 reg = (msr - APIC_BASE_MSR) << 4;

	if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
	if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic))
		return 1;

	if (reg == APIC_ICR2)
@@ -2002,7 +2002,7 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
	struct kvm_lapic *apic = vcpu->arch.apic;
	u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0;

	if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
	if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic))
		return 1;

	if (reg == APIC_DFR || reg == APIC_ICR2) {
+1 −1
Original line number Diff line number Diff line
@@ -3427,7 +3427,7 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn)

static bool can_do_async_pf(struct kvm_vcpu *vcpu)
{
	if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
	if (unlikely(!lapic_in_kernel(vcpu) ||
		     kvm_event_needs_reinjection(vcpu)))
		return false;

+2 −2
Original line number Diff line number Diff line
@@ -3060,7 +3060,7 @@ static int cr8_write_interception(struct vcpu_svm *svm)
	u8 cr8_prev = kvm_get_cr8(&svm->vcpu);
	/* instruction emulation calls kvm_set_cr8() */
	r = cr_interception(svm);
	if (irqchip_in_kernel(svm->vcpu.kvm))
	if (lapic_in_kernel(&svm->vcpu))
		return r;
	if (cr8_prev <= kvm_get_cr8(&svm->vcpu))
		return r;
@@ -3305,7 +3305,7 @@ static int interrupt_window_interception(struct vcpu_svm *svm)
	 * If the user space waits to inject interrupts, exit as soon as
	 * possible
	 */
	if (!irqchip_in_kernel(svm->vcpu.kvm) &&
	if (!lapic_in_kernel(&svm->vcpu) &&
	    kvm_run->request_interrupt_window &&
	    !kvm_cpu_has_interrupt(&svm->vcpu)) {
		kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
Loading