From patchwork Mon Sep 10 14:23:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Guo X-Patchwork-Id: 968073 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4289K15XWFz9sCQ; Tue, 11 Sep 2018 00:24:05 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1fzN6c-0001kI-Qt; Mon, 10 Sep 2018 14:23:58 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1fzN6c-0001jb-1j for kernel-team@lists.ubuntu.com; Mon, 10 Sep 2018 14:23:58 +0000 Received: from mail-pl1-f198.google.com ([209.85.214.198]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1fzN6b-0003nk-KY for kernel-team@lists.ubuntu.com; Mon, 10 Sep 2018 14:23:57 +0000 Received: by mail-pl1-f198.google.com with SMTP id a8-v6so10147620pla.10 for ; Mon, 10 Sep 2018 07:23:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=+w+5XTTGyEfVNp3oITZgQUF1f+haekBhCyxVKuPD/r4=; b=snhaRAMtvjeWa+KNBOxAGJ141TFRqZxvMS0wDVFr1CMHHg9NiXnOYUw6zv+QtFbmOi x3lFvA2Cxitr4bZF06bE0SZ1F9io8M0pFnFvNv/4JW5Uk54VTlOLxMLoUQbmCeeZ8BX/ 9M1DnPIYa11DXZMLuZGhi8fSMu+ZasdwvAK6+yLvGNuYd07SZOQgxGf/I4EIAkrYf3b3 ClXd+IDWZVDDiQDQMrqvNWTXw/U9GB0zmEwg9PwufRlUcf7IF2+BDDbyQwt7UI7PE3DF 8zNhKqpdNgUKN3lk5K18w8g7tOwt4S4AkKOG/E29epDESIiAAfPuNlqHd3wkJWEqaJab SBRQ== X-Gm-Message-State: APzg51CSriIyd+wh+3Qd1kzyl5qnDkN36N2wC5lqhhdBP56u5mpzvhu8 c0dr/9Y88GqG+VXb8iqgvrm+awBZ0cytk3HrCjd141RmoVE/AX5M1J22LJZB71JiZff9mctzxtz R5HOaFESeAEhc6V1YbExnbdC6zsgN16l71OjOu8Fvuw== X-Received: by 2002:a63:740f:: with SMTP id p15-v6mr23247030pgc.395.1536589435608; Mon, 10 Sep 2018 07:23:55 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYdQt9leXe3VmcNMFKEoysTvIQCDezGD76WL7JnVst/7ct4u0K5/DOea3Gp65gCxzn8QLnmJw== X-Received: by 2002:a63:740f:: with SMTP id p15-v6mr23247003pgc.395.1536589435338; Mon, 10 Sep 2018 07:23:55 -0700 (PDT) Received: from gavin-P70.buildd (114-35-245-81.HINET-IP.hinet.net. [114.35.245.81]) by smtp.gmail.com with ESMTPSA id j191-v6sm22868224pfc.136.2018.09.10.07.23.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 10 Sep 2018 07:23:54 -0700 (PDT) From: Gavin Guo To: kernel-team@lists.ubuntu.com Subject: [PATCH 3/4] KVM: ioapic: extract body of kvm_ioapic_set_irq Date: Mon, 10 Sep 2018 22:23:41 +0800 Message-Id: <1536589422-20822-4-git-send-email-gavin.guo@canonical.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1536589422-20822-1-git-send-email-gavin.guo@canonical.com> References: <1536589422-20822-1-git-send-email-gavin.guo@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Paolo Bonzini BugLink: https://bugs.launchpad.net/bugs/1791286 We will reuse it to process a nonzero IRR that is passed to KVM_SET_IRQCHIP. Reviewed-by: Alex Williamson Signed-off-by: Paolo Bonzini (backported from commit 44847dea79751e95665a439f8c63a65e51da8e1f) Signed-off-by: Gavin Guo --- virt/kvm/ioapic.c | 76 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 1cc1851812fa..6f6460a7c562 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -163,6 +163,56 @@ static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic) return false; } +static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, + int irq_level, bool line_status) +{ + union kvm_ioapic_redirect_entry entry; + u32 mask = 1 << irq; + u32 old_irr; + int edge, ret; + + entry = ioapic->redirtbl[irq]; + irq_level ^= entry.fields.polarity; + edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); + + if (!irq_level) { + ioapic->irr &= ~mask; + ret = 1; + goto out; + } + + /* + * Return 0 for coalesced interrupts; for edge-triggered interrupts, + * this only happens if a previous edge has not been delivered due + * do masking. For level interrupts, the remote_irr field tells + * us if the interrupt is waiting for an EOI. + * + * RTC is special: it is edge-triggered, but userspace likes to know + * if it has been already ack-ed via EOI because coalesced RTC + * interrupts lead to time drift in Windows guests. So we track + * EOI manually for the RTC interrupt. + */ + if (irq == RTC_GSI && line_status && + rtc_irq_check_coalesced(ioapic)) { + ret = 0; + goto out; + } + + old_irr = ioapic->irr; + ioapic->irr |= mask; + if ((edge && old_irr == ioapic->irr) || + (!edge && entry.fields.remote_irr)) { + ret = 0; + goto out; + } + + ret = ioapic_service(ioapic, irq, line_status); + +out: + trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); + return ret; +} + static void update_handled_vectors(struct kvm_ioapic *ioapic) { DECLARE_BITMAP(handled_vectors, 256); @@ -307,39 +357,15 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, int level, bool line_status) { - u32 old_irr; - u32 mask = 1 << irq; - union kvm_ioapic_redirect_entry entry; int ret, irq_level; BUG_ON(irq < 0 || irq >= IOAPIC_NUM_PINS); spin_lock(&ioapic->lock); - old_irr = ioapic->irr; irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq], irq_source_id, level); - entry = ioapic->redirtbl[irq]; - irq_level ^= entry.fields.polarity; - if (!irq_level) { - ioapic->irr &= ~mask; - ret = 1; - } else { - int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); + ret = ioapic_set_irq(ioapic, irq, irq_level, line_status); - if (irq == RTC_GSI && line_status && - rtc_irq_check_coalesced(ioapic)) { - ret = 0; /* coalesced */ - goto out; - } - ioapic->irr |= mask; - if ((edge && old_irr != ioapic->irr) || - (!edge && !entry.fields.remote_irr)) - ret = ioapic_service(ioapic, irq, line_status); - else - ret = 0; /* report coalesced interrupt */ - } -out: - trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); spin_unlock(&ioapic->lock); return ret;