From nobody Mon Feb 9 13:38:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1586762919; cv=none; d=zohomail.com; s=zohoarc; b=e5VT0I4im6cRVuG+ODKaU8Q67qaLxvEzdjHayp2dPBFusSAuPP/yr/d5nuSBhzh+88kLuYCNB6VZo+3j2hJoRgclLxHDunS/0zoQ7Tbu2GP7sk13YxdKhU96M2QdyO9PIzckK+aAmoME12oF7t7UM3LEM2kyUpiLlIu/CSkPP34= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1586762919; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=P7gLkQIPuNQlPBOIn5uasx4X7H2iy/a2FvVglL7xhFs=; b=g65TTZGKKz+RzlXniF3ak3nlr8TJsrwfc44ZYQTP1XUUV8cxZgCW95SnMHLGLvKxri/OhvwuYvqNtp5TgLWEsOGAxOW7onYFQ3aXjTmd0lOnIbWBzfQNKW/1nHFDdDQZ8088Vrud4yoFGyLVxGUj2ZcyTU+5kbWx3f14u4fN1jU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1586762919963741.5431377521209; Mon, 13 Apr 2020 00:28:39 -0700 (PDT) Received: from localhost ([::1]:41224 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jNtWI-0004f5-F6 for importer@patchew.org; Mon, 13 Apr 2020 03:28:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37713) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jNtUx-0003A2-Fk for qemu-devel@nongnu.org; Mon, 13 Apr 2020 03:27:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jNtUv-0000X3-Jl for qemu-devel@nongnu.org; Mon, 13 Apr 2020 03:27:15 -0400 Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]:39303) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jNtUv-0000Us-DR for qemu-devel@nongnu.org; Mon, 13 Apr 2020 03:27:13 -0400 Received: by mail-pg1-x541.google.com with SMTP id g32so4116384pgb.6 for ; Mon, 13 Apr 2020 00:27:13 -0700 (PDT) Received: from software.domain.org (28.144.92.34.bc.googleusercontent.com. [34.92.144.28]) by smtp.gmail.com with ESMTPSA id u8sm7241341pgl.19.2020.04.13.00.27.09 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Apr 2020 00:27:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=P7gLkQIPuNQlPBOIn5uasx4X7H2iy/a2FvVglL7xhFs=; b=mSIaEOe6WEmtD74gfGTW44hdcZ6hGZS48Zf+SalURw3wqRhKi433JhVqsABNgRd2/K JhoWKvFBh42rZ0qcFMgcCupXJCSG+ji07BJjnOzhqDvO9PdLs3exlyFX4yqJEmMlqhqR mxJGjKmI3AhTyaLQ89EEt4SmfT8YjILA9xEJz16RMkPCblgFp+wmULhM09HMg2zt3XxZ DfElysMzw2PUcYH/+U9UwMEiL4vR0y42xO1lUQhdwe465GgdMg0wbTlf2I0vq2fxOvLl hmihzVKTk+uFPtdH/P9bPDbn8x7uMIf8dkXvdxiVHPlRY+qb0rdf9z3T55EBZuIWweWA iOlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=P7gLkQIPuNQlPBOIn5uasx4X7H2iy/a2FvVglL7xhFs=; b=ZnOUBozVBtfyo8TnP63YK7og5OJWt5hxcWJAu2nNH51WHhsh3Lt4agR/Cyy2pJogJ1 p+/aIIYFhu1VaTIxVgbxqnKIquqrC8wR6RYC7b4wNd6SLzJSCk0XRJu/MWDFjp79UnDQ gZgtpoCJFS20MR9FxJBHrHVHqMcJ90hhwVYbBqlRG38mf5njXc4YbXL9Hy4zzwUnehi5 EnWC5xQcm7S0UiJAlEnZt5wW5C9au+s9BDgdQ/LS9i7zG94xVbQk/pwgCU4S6reWYYkq GrbcSCA8IPg6znHTPqeaWu6Dqk3VkZBaAxDhVLIFrIiEL57bF4R7XuvCL10TGhy66xnj fCwQ== X-Gm-Message-State: AGi0Pubp4hXawBloKdBsNo1nWeTdVBLY+y++LwfvusoyesYi/czSRenD uGAfL51IqinDKLWKzYkqc1U= X-Google-Smtp-Source: APiQypLtb7hku7z8GsxaDxKPnCWJBa/U7fTlL06VXjTFJwOlpFfKbFEyp+oqf7bJxGT+d4W3ZT9M7Q== X-Received: by 2002:a62:ed10:: with SMTP id u16mr7708160pfh.16.1586762832376; Mon, 13 Apr 2020 00:27:12 -0700 (PDT) From: Huacai Chen To: Paolo Bonzini , Thomas Bogendoerfer Subject: [PATCH 10/15] KVM: MIPS: Add more types of virtual interrupts Date: Mon, 13 Apr 2020 15:30:19 +0800 Message-Id: <1586763024-12197-11-git-send-email-chenhc@lemote.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1586763024-12197-1-git-send-email-chenhc@lemote.com> References: <1586763024-12197-1-git-send-email-chenhc@lemote.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::541 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kvm@vger.kernel.org, Huacai Chen , qemu-devel@nongnu.org, Jiaxun Yang , linux-mips@vger.kernel.org, Fuxin Zhang , Huacai Chen Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In current implementation, MIPS KVM uses IP2, IP3, IP4 and IP7 for external interrupt, two kinds of IPIs and timer interrupt respectively, but Loongson-3 based machines prefer to use IP2, IP3, IP6 and IP7 for two kinds of external interrupts, IPI and timer interrupt. So we define two priority-irq mapping tables: kvm_loongson3_priority_to_irq[] for Loongson-3, and kvm_default_priority_to_irq[] for others. The virtual interrupt infrastructure is updated to deliver all types of interrupts from IP2, IP3, IP4, IP6 and IP7. Signed-off-by: Huacai Chen Co-developed-by: Jiaxun Yang --- arch/mips/kvm/interrupt.c | 93 +++++++------------------------------------= ---- arch/mips/kvm/interrupt.h | 14 ++++--- arch/mips/kvm/mips.c | 40 ++++++++++++++++++-- arch/mips/kvm/vz.c | 53 ++++----------------------- 4 files changed, 67 insertions(+), 133 deletions(-) diff --git a/arch/mips/kvm/interrupt.c b/arch/mips/kvm/interrupt.c index 7257e8b6..d28c2c9c 100644 --- a/arch/mips/kvm/interrupt.c +++ b/arch/mips/kvm/interrupt.c @@ -61,27 +61,8 @@ void kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu, * the EXC code will be set when we are actually * delivering the interrupt: */ - switch (intr) { - case 2: - kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0)); - /* Queue up an INT exception for the core */ - kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IO); - break; - - case 3: - kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ1)); - kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_1); - break; - - case 4: - kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ2)); - kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_2); - break; - - default: - break; - } - + kvm_set_c0_guest_cause(vcpu->arch.cop0, 1 << (intr + 8)); + kvm_mips_queue_irq(vcpu, kvm_irq_to_priority(intr)); } =20 void kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu, @@ -89,26 +70,8 @@ void kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu, { int intr =3D (int)irq->irq; =20 - switch (intr) { - case -2: - kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0)); - kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IO); - break; - - case -3: - kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ1)); - kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_1); - break; - - case -4: - kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ2)); - kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_2); - break; - - default: - break; - } - + kvm_clear_c0_guest_cause(vcpu->arch.cop0, 1 << (-intr + 8)); + kvm_mips_dequeue_irq(vcpu, kvm_irq_to_priority(-intr)); } =20 /* Deliver the interrupt of the corresponding priority, if possible. */ @@ -116,50 +79,20 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, uns= igned int priority, u32 cause) { int allowed =3D 0; - u32 exccode; + u32 exccode, ie; =20 struct kvm_vcpu_arch *arch =3D &vcpu->arch; struct mips_coproc *cop0 =3D vcpu->arch.cop0; =20 - switch (priority) { - case MIPS_EXC_INT_TIMER: - if ((kvm_read_c0_guest_status(cop0) & ST0_IE) - && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) - && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) { - allowed =3D 1; - exccode =3D EXCCODE_INT; - } - break; - - case MIPS_EXC_INT_IO: - if ((kvm_read_c0_guest_status(cop0) & ST0_IE) - && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) - && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) { - allowed =3D 1; - exccode =3D EXCCODE_INT; - } - break; - - case MIPS_EXC_INT_IPI_1: - if ((kvm_read_c0_guest_status(cop0) & ST0_IE) - && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) - && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) { - allowed =3D 1; - exccode =3D EXCCODE_INT; - } - break; - - case MIPS_EXC_INT_IPI_2: - if ((kvm_read_c0_guest_status(cop0) & ST0_IE) - && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) - && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) { - allowed =3D 1; - exccode =3D EXCCODE_INT; - } - break; + if (priority =3D=3D MIPS_EXC_MAX) + return 0; =20 - default: - break; + ie =3D 1 << (kvm_priority_to_irq[priority] + 8); + if ((kvm_read_c0_guest_status(cop0) & ST0_IE) + && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) + && (kvm_read_c0_guest_status(cop0) & ie)) { + allowed =3D 1; + exccode =3D EXCCODE_INT; } =20 /* Are we allowed to deliver the interrupt ??? */ diff --git a/arch/mips/kvm/interrupt.h b/arch/mips/kvm/interrupt.h index 3bf0a49..c3e878c 100644 --- a/arch/mips/kvm/interrupt.h +++ b/arch/mips/kvm/interrupt.h @@ -21,11 +21,12 @@ #define MIPS_EXC_NMI 5 #define MIPS_EXC_MCHK 6 #define MIPS_EXC_INT_TIMER 7 -#define MIPS_EXC_INT_IO 8 -#define MIPS_EXC_EXECUTE 9 -#define MIPS_EXC_INT_IPI_1 10 -#define MIPS_EXC_INT_IPI_2 11 -#define MIPS_EXC_MAX 12 +#define MIPS_EXC_INT_IO_1 8 +#define MIPS_EXC_INT_IO_2 9 +#define MIPS_EXC_EXECUTE 10 +#define MIPS_EXC_INT_IPI_1 11 +#define MIPS_EXC_INT_IPI_2 12 +#define MIPS_EXC_MAX 13 /* XXXSL More to follow */ =20 #define C_TI (_ULCAST_(1) << 30) @@ -38,6 +39,9 @@ #define KVM_MIPS_IRQ_CLEAR_ALL_AT_ONCE (0) #endif =20 +extern u32 *kvm_priority_to_irq; +u32 kvm_irq_to_priority(u32 irq); + void kvm_mips_queue_irq(struct kvm_vcpu *vcpu, unsigned int priority); void kvm_mips_dequeue_irq(struct kvm_vcpu *vcpu, unsigned int priority); int kvm_mips_pending_timer(struct kvm_vcpu *vcpu); diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 71244bf..5c3a414 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -495,7 +495,10 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, int intr =3D (int)irq->irq; struct kvm_vcpu *dvcpu =3D NULL; =20 - if (intr =3D=3D 3 || intr =3D=3D -3 || intr =3D=3D 4 || intr =3D=3D -4) + if (intr =3D=3D kvm_priority_to_irq[MIPS_EXC_INT_IPI_1] || + intr =3D=3D kvm_priority_to_irq[MIPS_EXC_INT_IPI_2] || + intr =3D=3D (-kvm_priority_to_irq[MIPS_EXC_INT_IPI_1]) || + intr =3D=3D (-kvm_priority_to_irq[MIPS_EXC_INT_IPI_2])) kvm_debug("%s: CPU: %d, INTR: %d\n", __func__, irq->cpu, (int)intr); =20 @@ -504,10 +507,10 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, else dvcpu =3D vcpu->kvm->vcpus[irq->cpu]; =20 - if (intr =3D=3D 2 || intr =3D=3D 3 || intr =3D=3D 4) { + if (intr =3D=3D 2 || intr =3D=3D 3 || intr =3D=3D 4 || intr =3D=3D 6) { kvm_mips_callbacks->queue_io_int(dvcpu, irq); =20 - } else if (intr =3D=3D -2 || intr =3D=3D -3 || intr =3D=3D -4) { + } else if (intr =3D=3D -2 || intr =3D=3D -3 || intr =3D=3D -4 || intr =3D= =3D -6) { kvm_mips_callbacks->dequeue_io_int(dvcpu, irq); } else { kvm_err("%s: invalid interrupt ioctl (%d:%d)\n", __func__, @@ -1679,6 +1682,34 @@ static struct notifier_block kvm_mips_csr_die_notifi= er =3D { .notifier_call =3D kvm_mips_csr_die_notify, }; =20 +static u32 kvm_default_priority_to_irq[MIPS_EXC_MAX] =3D { + [MIPS_EXC_INT_TIMER] =3D C_IRQ5, + [MIPS_EXC_INT_IO_1] =3D C_IRQ0, + [MIPS_EXC_INT_IPI_1] =3D C_IRQ1, + [MIPS_EXC_INT_IPI_2] =3D C_IRQ2, +}; + +static u32 kvm_loongson3_priority_to_irq[MIPS_EXC_MAX] =3D { + [MIPS_EXC_INT_TIMER] =3D C_IRQ5, + [MIPS_EXC_INT_IO_1] =3D C_IRQ0, + [MIPS_EXC_INT_IO_2] =3D C_IRQ1, + [MIPS_EXC_INT_IPI_1] =3D C_IRQ4, +}; + +u32 *kvm_priority_to_irq =3D kvm_default_priority_to_irq; + +u32 kvm_irq_to_priority(u32 irq) +{ + int i; + + for (i =3D MIPS_EXC_INT_TIMER; i < MIPS_EXC_MAX; i++) { + if (kvm_priority_to_irq[i] =3D=3D (1 << (irq + 8))) + return i; + } + + return MIPS_EXC_MAX; +} + static int __init kvm_mips_init(void) { int ret; @@ -1697,6 +1728,9 @@ static int __init kvm_mips_init(void) if (ret) return ret; =20 + if (boot_cpu_type() =3D=3D CPU_LOONGSON64) + kvm_priority_to_irq =3D kvm_loongson3_priority_to_irq; + register_die_notifier(&kvm_mips_csr_die_notifier); =20 return 0; diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c index 9a228dc..db9b0f5 100644 --- a/arch/mips/kvm/vz.c +++ b/arch/mips/kvm/vz.c @@ -225,23 +225,7 @@ static void kvm_vz_queue_io_int_cb(struct kvm_vcpu *vc= pu, * interrupts are asynchronous to vcpu execution therefore defer guest * cp0 accesses */ - switch (intr) { - case 2: - kvm_vz_queue_irq(vcpu, MIPS_EXC_INT_IO); - break; - - case 3: - kvm_vz_queue_irq(vcpu, MIPS_EXC_INT_IPI_1); - break; - - case 4: - kvm_vz_queue_irq(vcpu, MIPS_EXC_INT_IPI_2); - break; - - default: - break; - } - + kvm_vz_queue_irq(vcpu, kvm_irq_to_priority(intr)); } =20 static void kvm_vz_dequeue_io_int_cb(struct kvm_vcpu *vcpu, @@ -253,44 +237,22 @@ static void kvm_vz_dequeue_io_int_cb(struct kvm_vcpu = *vcpu, * interrupts are asynchronous to vcpu execution therefore defer guest * cp0 accesses */ - switch (intr) { - case -2: - kvm_vz_dequeue_irq(vcpu, MIPS_EXC_INT_IO); - break; - - case -3: - kvm_vz_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_1); - break; - - case -4: - kvm_vz_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_2); - break; - - default: - break; - } - + kvm_vz_dequeue_irq(vcpu, kvm_irq_to_priority(-intr)); } =20 -static u32 kvm_vz_priority_to_irq[MIPS_EXC_MAX] =3D { - [MIPS_EXC_INT_TIMER] =3D C_IRQ5, - [MIPS_EXC_INT_IO] =3D C_IRQ0, - [MIPS_EXC_INT_IPI_1] =3D C_IRQ1, - [MIPS_EXC_INT_IPI_2] =3D C_IRQ2, -}; - static int kvm_vz_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int prior= ity, u32 cause) { u32 irq =3D (priority < MIPS_EXC_MAX) ? - kvm_vz_priority_to_irq[priority] : 0; + kvm_priority_to_irq[priority] : 0; =20 switch (priority) { case MIPS_EXC_INT_TIMER: set_gc0_cause(C_TI); break; =20 - case MIPS_EXC_INT_IO: + case MIPS_EXC_INT_IO_1: + case MIPS_EXC_INT_IO_2: case MIPS_EXC_INT_IPI_1: case MIPS_EXC_INT_IPI_2: if (cpu_has_guestctl2) @@ -311,7 +273,7 @@ static int kvm_vz_irq_clear_cb(struct kvm_vcpu *vcpu, u= nsigned int priority, u32 cause) { u32 irq =3D (priority < MIPS_EXC_MAX) ? - kvm_vz_priority_to_irq[priority] : 0; + kvm_priority_to_irq[priority] : 0; =20 switch (priority) { case MIPS_EXC_INT_TIMER: @@ -329,7 +291,8 @@ static int kvm_vz_irq_clear_cb(struct kvm_vcpu *vcpu, u= nsigned int priority, } break; =20 - case MIPS_EXC_INT_IO: + case MIPS_EXC_INT_IO_1: + case MIPS_EXC_INT_IO_2: case MIPS_EXC_INT_IPI_1: case MIPS_EXC_INT_IPI_2: /* Clear GuestCtl2.VIP irq if not using Hardware Clear */ --=20 2.7.0